+ ssh->X11_fwd_enabled = TRUE;
+ }
+ }
+
+ /*
+ * Enable port forwardings.
+ */
+ {
+ char type;
+ int n;
+ int sport,dport,sserv,dserv;
+ char sports[256], dports[256], saddr[256], host[256];
+
+ ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
+ /* Add port forwardings. */
+ ssh->portfwd_strptr = ssh->cfg.portfwd;
+ while (*ssh->portfwd_strptr) {
+ type = *ssh->portfwd_strptr++;
+ saddr[0] = '\0';
+ n = 0;
+ while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != '\t') {
+ if (*ssh->portfwd_strptr == ':') {
+ /*
+ * We've seen a colon in the middle of the
+ * source port number. This means that
+ * everything we've seen until now is the
+ * source _address_, so we'll move it into
+ * saddr and start sports from the beginning
+ * again.
+ */
+ ssh->portfwd_strptr++;
+ sports[n] = '\0';
+ strcpy(saddr, sports);
+ n = 0;
+ }
+ if (n < 255) sports[n++] = *ssh->portfwd_strptr++;
+ }
+ sports[n] = 0;
+ if (type != 'D') {
+ if (*ssh->portfwd_strptr == '\t')
+ ssh->portfwd_strptr++;
+ n = 0;
+ while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != ':') {
+ if (n < 255) host[n++] = *ssh->portfwd_strptr++;
+ }
+ host[n] = 0;
+ if (*ssh->portfwd_strptr == ':')
+ ssh->portfwd_strptr++;
+ n = 0;
+ while (*ssh->portfwd_strptr) {
+ if (n < 255) dports[n++] = *ssh->portfwd_strptr++;
+ }
+ dports[n] = 0;
+ ssh->portfwd_strptr++;
+ dport = atoi(dports);
+ dserv = 0;
+ if (dport == 0) {
+ dserv = 1;
+ dport = net_service_lookup(dports);
+ if (!dport) {
+ logeventf(ssh, "Service lookup failed for destination"
+ " port \"%s\"", dports);
+ }
+ }
+ } else {
+ while (*ssh->portfwd_strptr) ssh->portfwd_strptr++;
+ dport = dserv = -1;
+ }
+ sport = atoi(sports);
+ sserv = 0;
+ if (sport == 0) {
+ sserv = 1;
+ sport = net_service_lookup(sports);
+ if (!sport) {
+ logeventf(ssh, "Service lookup failed for source"
+ " port \"%s\"", sports);
+ }
+ }
+ if (sport && dport) {
+ if (type == 'L') {
+ pfd_addforward(host, dport, *saddr ? saddr : NULL,
+ sport, ssh, &ssh->cfg);
+ logeventf(ssh, "Local port %.*s%.*s%.*s%.*s%d%.*s"
+ " forwarding to %s:%.*s%.*s%d%.*s",
+ (int)(*saddr?strlen(saddr):0), *saddr?saddr:NULL,
+ (int)(*saddr?1:0), ":",
+ (int)(sserv ? strlen(sports) : 0), sports,
+ sserv, "(", sport, sserv, ")",
+ host,
+ (int)(dserv ? strlen(dports) : 0), dports,
+ dserv, "(", dport, dserv, ")");
+ } else if (type == 'D') {
+ pfd_addforward(NULL, -1, *saddr ? saddr : NULL,
+ sport, ssh, &ssh->cfg);
+ logeventf(ssh, "Local port %.*s%.*s%.*s%.*s%d%.*s"
+ " doing SOCKS dynamic forwarding",
+ (int)(*saddr?strlen(saddr):0), *saddr?saddr:NULL,
+ (int)(*saddr?1:0), ":",
+ (int)(sserv ? strlen(sports) : 0), sports,
+ sserv, "(", sport, sserv, ")");
+ } else {
+ struct ssh_rportfwd *pf;
+ pf = snew(struct ssh_rportfwd);
+ strcpy(pf->dhost, host);
+ pf->dport = dport;
+ pf->sport = sport;
+ if (add234(ssh->rportfwds, pf) != pf) {
+ logeventf(ssh, "Duplicate remote port forwarding"
+ " to %s:%d", host, dport);
+ sfree(pf);
+ } else {
+ logeventf(ssh, "Requesting remote port "
+ "%.*s%.*s%.*s%.*s%d%.*s"
+ " forward to %s:%.*s%.*s%d%.*s",
+ (int)(*saddr?strlen(saddr):0),
+ *saddr?saddr:NULL,
+ (int)(*saddr?1:0), ":",
+ (int)(sserv ? strlen(sports) : 0), sports,
+ sserv, "(", sport, sserv, ")",
+ host,
+ (int)(dserv ? strlen(dports) : 0), dports,
+ dserv, "(", dport, dserv, ")");
+ ssh2_pkt_init(ssh, SSH2_MSG_GLOBAL_REQUEST);
+ ssh2_pkt_addstring(ssh, "tcpip-forward");
+ ssh2_pkt_addbool(ssh, 1);/* want reply */
+ if (*saddr)
+ ssh2_pkt_addstring(ssh, saddr);
+ if (ssh->cfg.rport_acceptall)
+ ssh2_pkt_addstring(ssh, "0.0.0.0");
+ else
+ ssh2_pkt_addstring(ssh, "127.0.0.1");
+ ssh2_pkt_adduint32(ssh, sport);
+ ssh2_pkt_send(ssh);
+
+ do {
+ crWaitUntilV(ispkt);
+ if (ssh->pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
+ unsigned i = ssh2_pkt_getuint32(ssh);
+ struct ssh_channel *c;
+ c = find234(ssh->channels, &i, ssh_channelfind);
+ if (!c)
+ continue;/* nonexistent channel */
+ c->v.v2.remwindow += ssh2_pkt_getuint32(ssh);
+ }
+ } while (ssh->pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
+
+ if (ssh->pktin.type != SSH2_MSG_REQUEST_SUCCESS) {
+ if (ssh->pktin.type != SSH2_MSG_REQUEST_FAILURE) {
+ bombout(("Unexpected response to port "
+ "forwarding request: packet type %d",
+ ssh->pktin.type));
+ crStopV;
+ }
+ logevent("Server refused this port forwarding");
+ } else {
+ logevent("Remote port forwarding enabled");
+ }
+ }
+ }
+ }