Bugzilla – Attachment 321 Details for
Bug 413
Port forwarding: [localhost:]localport:remotehost:remoteport
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Implement optional address binding for port forwards (update 3)
openssh-portbind3.patch (text/plain), 28.44 KB, created by
Darren Tucker
on 2003-06-04 21:37:30 AEST
(
hide
)
Description:
Implement optional address binding for port forwards (update 3)
Filename:
MIME Type:
Creator:
Darren Tucker
Created:
2003-06-04 21:37:30 AEST
Size:
28.44 KB
patch
obsolete
>Index: auth-options.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-options.c,v >retrieving revision 1.26 >diff -u -r1.26 auth-options.c >--- auth-options.c 3 Jun 2003 00:25:48 -0000 1.26 >+++ auth-options.c 4 Jun 2003 10:23:39 -0000 >@@ -217,7 +217,7 @@ > } > cp = "permitopen=\""; > if (strncasecmp(opts, cp, strlen(cp)) == 0) { >- char host[256], sport[6]; >+ char *host, *p; > u_short port; > char *patterns = xmalloc(strlen(opts) + 1); > >@@ -243,8 +243,9 @@ > } > patterns[i] = 0; > opts++; >- if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 && >- sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) { >+ p = patterns; >+ host = hpdelim(&p); >+ if (!host) { > debug("%.100s, line %lu: Bad permitopen specification " > "<%.100s>", file, linenum, patterns); > auth_debug_add("%.100s, line %lu: " >@@ -252,9 +253,11 @@ > xfree(patterns); > goto bad_option; > } >- if ((port = a2port(sport)) == 0) { >+ host = cleanhostname(host); >+ port = p ? a2port(p) : 0; >+ if (port == 0) { > debug("%.100s, line %lu: Bad permitopen port <%.100s>", >- file, linenum, sport); >+ file, linenum, p ? p : ""); > auth_debug_add("%.100s, line %lu: " > "Bad permitopen port", file, linenum); > xfree(patterns); >Index: channels.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/channels.c,v >retrieving revision 1.166 >diff -u -r1.166 channels.c >--- channels.c 14 May 2003 03:45:43 -0000 1.166 >+++ channels.c 4 Jun 2003 10:23:40 -0000 >@@ -2016,8 +2016,9 @@ > Channel *c; > int success, sock, on = 1; > struct addrinfo hints, *ai, *aitop; >- const char *host; >+ const char *host, *addr = NULL; > char ntop[NI_MAXHOST], strport[NI_MAXSERV]; >+ int wildcard = 0; > > success = 0; > host = (type == SSH_CHANNEL_RPORT_LISTENER) ? >@@ -2033,16 +2034,35 @@ > } > > /* >+ * Determine whether or not a port forward listens to loopback, >+ * specified address or wildcard. >+ */ >+ if (gateway_ports) { >+ if (listen_addr == NULL || listen_addr[0] == '\0' || >+ strcmp(listen_addr, "*") == 0) >+ wildcard = 1; >+ else >+ addr = listen_addr; >+ } else if (type == SSH_CHANNEL_PORT_LISTENER) { >+ /* A client may override GatewayPorts with a wildcard */ >+ if (listen_addr != NULL && strcmp(listen_addr, "*") == 0) >+ wildcard = 1; >+ else >+ addr = listen_addr; >+ } >+ >+ /* > * getaddrinfo returns a loopback address if the hostname is > * set to NULL and hints.ai_flags is not AI_PASSIVE > */ > memset(&hints, 0, sizeof(hints)); > hints.ai_family = IPv4or6; >- hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; >+ hints.ai_flags = wildcard ? AI_PASSIVE : 0; > hints.ai_socktype = SOCK_STREAM; > snprintf(strport, sizeof strport, "%d", listen_port); >- if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) >- packet_disconnect("getaddrinfo: fatal error"); >+ if (getaddrinfo(addr, strport, &hints, &aitop) != 0) >+ packet_disconnect("getaddrinfo: %.200s: fatal error", >+ addr ? addr : "(NULL)"); > > for (ai = aitop; ai; ai = ai->ai_next) { > if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) >@@ -2104,11 +2124,12 @@ > > /* protocol local port fwd, used by ssh (and sshd in v1) */ > int >-channel_setup_local_fwd_listener(u_short listen_port, >+channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, > const char *host_to_connect, u_short port_to_connect, int gateway_ports) > { > return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, >- NULL, listen_port, host_to_connect, port_to_connect, gateway_ports); >+ listen_host, listen_port, host_to_connect, port_to_connect, >+ gateway_ports); > } > > /* protocol v2 remote port fwd, used by sshd */ >@@ -2126,7 +2147,7 @@ > */ > > void >-channel_request_remote_forwarding(u_short listen_port, >+channel_request_remote_forwarding(const char *listen_host, u_short listen_port, > const char *host_to_connect, u_short port_to_connect) > { > int type, success = 0; >@@ -2137,7 +2158,14 @@ > > /* Send the forward request to the remote side. */ > if (compat20) { >- const char *address_to_bind = "0.0.0.0"; >+ const char *address_to_bind; >+ if (listen_host == NULL) >+ address_to_bind = "127.0.0.1"; >+ else if (listen_host[0] == '\0' || strcmp(listen_host, "*")==0) >+ address_to_bind = "0.0.0.0"; >+ else >+ address_to_bind = listen_host; >+ > packet_start(SSH2_MSG_GLOBAL_REQUEST); > packet_put_cstring("tcpip-forward"); > packet_put_char(1); /* boolean: want reply */ >@@ -2205,7 +2233,7 @@ > port); > #endif > /* Initiate forwarding */ >- channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports); >+ channel_setup_local_fwd_listener(NULL, port, hostname, host_port, gateway_ports); > > /* Free the argument string. */ > xfree(hostname); >Index: channels.h >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/channels.h,v >retrieving revision 1.63 >diff -u -r1.63 channels.h >--- channels.h 22 Jul 2002 15:28:54 -0000 1.63 >+++ channels.h 12 Feb 2003 10:38:17 -0000 >@@ -199,8 +199,11 @@ > void channel_input_port_forward_request(int, int); > int channel_connect_to(const char *, u_short); > int channel_connect_by_listen_address(u_short); >-void channel_request_remote_forwarding(u_short, const char *, u_short); >-int channel_setup_local_fwd_listener(u_short, const char *, u_short, int); >+void >+channel_request_remote_forwarding(const char *, u_short, const char *, u_short); >+int >+channel_setup_local_fwd_listener(const char *, u_short, const char *, u_short, >+int); > int channel_setup_remote_fwd_listener(const char *, u_short, int); > > /* x11 forwarding */ >Index: clientloop.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/clientloop.c,v >retrieving revision 1.95 >diff -u -r1.95 clientloop.c >--- clientloop.c 15 May 2003 00:20:14 -0000 1.95 >+++ clientloop.c 4 Jun 2003 11:32:27 -0000 >@@ -476,8 +476,7 @@ > { > void (*handler)(int); > char *s, *cmd; >- u_short fwd_port, fwd_host_port; >- char buf[1024], sfwd_port[6], sfwd_host_port[6]; >+ Forward fwd; > int local = 0; > > leave_raw_mode(); >@@ -499,31 +498,22 @@ > logit("Not supported for SSH protocol version 1."); > goto out; > } >- s += 2; >- while (*s && isspace(*s)) >- s++; > >- if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]", >- sfwd_port, buf, sfwd_host_port) != 3 && >- sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", >- sfwd_port, buf, sfwd_host_port) != 3) { >+ if ( !parse_forward(&fwd, (s+2))) { > logit("Bad forwarding specification."); > goto out; > } >- if ((fwd_port = a2port(sfwd_port)) == 0 || >- (fwd_host_port = a2port(sfwd_host_port)) == 0) { >- logit("Bad forwarding port(s)."); >- goto out; >- } >+ > if (local) { >- if (channel_setup_local_fwd_listener(fwd_port, buf, >- fwd_host_port, options.gateway_ports) < 0) { >+ if (channel_setup_local_fwd_listener(fwd.listen_host, >+ fwd.listen_port, fwd.connect_host, fwd.connect_port, >+ options.gateway_ports) < 0) { > logit("Port forwarding failed."); > goto out; > } > } else >- channel_request_remote_forwarding(fwd_port, buf, >- fwd_host_port); >+ channel_request_remote_forwarding(fwd.listen_host, >+ fwd.listen_port, fwd.connect_host, fwd.connect_port); > logit("Forwarding port."); > out: > signal(SIGINT, handler); >Index: misc.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/misc.c,v >retrieving revision 1.35 >diff -u -r1.35 misc.c >--- misc.c 14 May 2003 03:41:39 -0000 1.35 >+++ misc.c 4 Jun 2003 10:23:41 -0000 >@@ -269,6 +269,51 @@ > return total; > } > >+/* Search for next delimiter between hostnames/addresses and ports. >+ * Argument may be modified (for termination). >+ * Returns *cp if parsing succeeds. >+ * *cp is set to the start of the next delimiter, if one was found. >+ * If this is the last field, *cp is set to NULL. >+ */ >+char * >+hpdelim(char **cp) >+{ >+ char *s, *old; >+ >+ if (!(cp && *cp)) >+ return NULL; >+ >+ old = s = *cp; >+ if (*s == '[') { >+ s = strchr(s, ']'); >+ if (!s) >+ return NULL; >+ else >+ ++s; >+ } else { >+ s = strpbrk(s, ":/"); >+ if (!s) >+ s = *cp + strlen(*cp); /* trailing null */ >+ } >+ >+ switch (*s) { >+ case '\0': >+ *cp = NULL; /* no more fields*/ >+ break; >+ >+ case ':': >+ case '/': >+ *s = '\0'; /* terminate */ >+ *cp = s + 1; >+ break; >+ >+ default: >+ return NULL; >+ } >+ >+ return old; >+} >+ > char * > cleanhostname(char *host) > { >Index: misc.h >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/misc.h,v >retrieving revision 1.14 >diff -u -r1.14 misc.h >--- misc.h 22 Mar 2002 02:54:25 -0000 1.14 >+++ misc.h 12 Feb 2003 10:38:17 -0000 >@@ -18,6 +18,7 @@ > void unset_nonblock(int); > void set_nodelay(int); > int a2port(const char *); >+char *hpdelim(char **); > char *cleanhostname(char *); > char *colon(char *); > long convtime(const char *); >Index: readconf.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/readconf.c,v >retrieving revision 1.87 >diff -u -r1.87 readconf.c >--- readconf.c 18 May 2003 10:50:30 -0000 1.87 >+++ readconf.c 4 Jun 2003 11:26:00 -0000 >@@ -205,21 +205,26 @@ > */ > > void >-add_local_forward(Options *options, u_short port, const char *host, >- u_short host_port) >+add_local_forward(Options *options, const char *listen_host, >+ u_short listen_port, const char *connect_host, >+ u_short connect_port) > { > Forward *fwd; > #ifndef NO_IPPORT_RESERVED_CONCEPT > extern uid_t original_real_uid; >- if (port < IPPORT_RESERVED && original_real_uid != 0) >+ if (listen_port < IPPORT_RESERVED && original_real_uid != 0) > fatal("Privileged ports can only be forwarded by root."); > #endif > if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) > fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); > fwd = &options->local_forwards[options->num_local_forwards++]; >- fwd->port = port; >- fwd->host = xstrdup(host); >- fwd->host_port = host_port; >+ if (listen_host == NULL) >+ fwd->listen_host = NULL; >+ else >+ fwd->listen_host = xstrdup(listen_host); >+ fwd->listen_port = listen_port; >+ fwd->connect_host = xstrdup(connect_host); >+ fwd->connect_port = connect_port; > } > > /* >@@ -228,17 +233,22 @@ > */ > > void >-add_remote_forward(Options *options, u_short port, const char *host, >- u_short host_port) >+add_remote_forward(Options *options, const char *listen_host, >+ u_short listen_port, const char *connect_host, >+ u_short connect_port) > { > Forward *fwd; > if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) > fatal("Too many remote forwards (max %d).", > SSH_MAX_FORWARDS_PER_DIRECTION); > fwd = &options->remote_forwards[options->num_remote_forwards++]; >- fwd->port = port; >- fwd->host = xstrdup(host); >- fwd->host_port = host_port; >+ if (listen_host == NULL) >+ fwd->listen_host = NULL; >+ else >+ fwd->listen_host = xstrdup(listen_host); >+ fwd->listen_port = listen_port; >+ fwd->connect_host = xstrdup(connect_host); >+ fwd->connect_port = connect_port; > } > > static void >@@ -246,11 +256,15 @@ > { > int i; > >- for (i = 0; i < options->num_local_forwards; i++) >- xfree(options->local_forwards[i].host); >+ for (i = 0; i < options->num_local_forwards; i++) { >+ xfree(options->local_forwards[i].listen_host); >+ xfree(options->local_forwards[i].connect_host); >+ } > options->num_local_forwards = 0; >- for (i = 0; i < options->num_remote_forwards; i++) >- xfree(options->remote_forwards[i].host); >+ for (i = 0; i < options->num_remote_forwards; i++) { >+ xfree(options->remote_forwards[i].listen_host); >+ xfree(options->remote_forwards[i].connect_host); >+ } > options->num_remote_forwards = 0; > } > >@@ -283,12 +297,12 @@ > char *line, const char *filename, int linenum, > int *activep) > { >- char buf[256], *s, **charptr, *endofnumber, *keyword, *arg; >+ char *s, **charptr, *endofnumber, *keyword, *arg, >+ *arg2, fwdarg[256]; > int opcode, *intptr, value; > size_t len; >- u_short fwd_port, fwd_host_port; >- char sfwd_host_port[6]; > extern int IPv4or6; >+ Forward fwd; > > /* Strip trailing whitespace */ > for(len = strlen(line) - 1; len > 0; len--) { >@@ -649,27 +663,33 @@ > if (!arg || *arg == '\0') > fatal("%.200s line %d: Missing port argument.", > filename, linenum); >- if ((fwd_port = a2port(arg)) == 0) >- fatal("%.200s line %d: Bad listen port.", >- filename, linenum); >- arg = strdelim(&s); >- if (!arg || *arg == '\0') >+ arg2 = strdelim(&s); >+ if (!arg2 || *arg2 == '\0') > fatal("%.200s line %d: Missing second argument.", > filename, linenum); >- if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && >- sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2) >+ >+ /* construct a string for parse_forward */ >+ snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); >+ >+ if (parse_forward(&fwd, fwdarg) == 0) > fatal("%.200s line %d: Bad forwarding specification.", > filename, linenum); >- if ((fwd_host_port = a2port(sfwd_host_port)) == 0) >+ if (fwd.listen_port == 0) >+ fatal("%.200s line %d: Bad listen port.", >+ filename, linenum); >+ if (fwd.connect_port == 0) > fatal("%.200s line %d: Bad forwarding port.", > filename, linenum); >+ > if (*activep) { > if (opcode == oLocalForward) >- add_local_forward(options, fwd_port, buf, >- fwd_host_port); >+ add_local_forward(options, >+ fwd.listen_host, fwd.listen_port, >+ fwd.connect_host, fwd.connect_port); > else if (opcode == oRemoteForward) >- add_remote_forward(options, fwd_port, buf, >- fwd_host_port); >+ add_remote_forward(options, >+ fwd.listen_host, fwd.listen_port, >+ fwd.connect_host, fwd.connect_port); > } > break; > >@@ -678,12 +698,24 @@ > if (!arg || *arg == '\0') > fatal("%.200s line %d: Missing port argument.", > filename, linenum); >- fwd_port = a2port(arg); >- if (fwd_port == 0) >+ fwd.listen_port = 0; >+ fwd.listen_host = hpdelim(&arg); >+ if (!fwd.listen_host) >+ fatal("%.200s line %d: Bad forwarding specification.", >+ filename, linenum); >+ if (arg) { >+ fwd.listen_port = a2port(arg); >+ fwd.listen_host = cleanhostname(fwd.listen_host); >+ } else { >+ fwd.listen_port = a2port(fwd.listen_host); >+ fwd.listen_host = ""; >+ } >+ if (fwd.listen_port == 0) > fatal("%.200s line %d: Badly formatted port number.", > filename, linenum); > if (*activep) >- add_local_forward(options, fwd_port, "socks4", 0); >+ add_local_forward(options, fwd.listen_host, >+ fwd.listen_port, "socks4", 0); > break; > > case oClearAllForwardings: >@@ -985,4 +1017,51 @@ > /* options->hostname will be set in the main program if appropriate */ > /* options->host_key_alias should not be set by default */ > /* options->preferred_authentications will be set in ssh */ >+} >+ >+/* >+ * parse_forward >+ * parses a string containing a port forwarding specification of the form: >+ * [listenhost:]listenport:connecthost:connectport >+ * returns number of arguments parsed or zero on error >+ */ >+int >+parse_forward(Forward *fwd, const char *fwdspec) >+{ >+ int i; >+ char *p, *cp, *fwdarg[4]; >+ >+ cp = p = xstrdup(fwdspec); >+ >+ /* skip leading spaces */ >+ while (*cp && isspace(*cp)) >+ cp++; >+ >+ for (i = 0; i < 4; ++i) >+ if ( !(fwdarg[i] = hpdelim(&cp)) ) >+ break; >+ switch(i) { >+ case 3: >+ fwd->listen_host = NULL; >+ fwd->listen_port = a2port(fwdarg[0]); >+ fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); >+ fwd->connect_port = a2port(fwdarg[2]); >+ break; >+ >+ case 4: >+ fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); >+ fwd->listen_port = a2port(fwdarg[1]); >+ fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); >+ fwd->connect_port = a2port(fwdarg[3]); >+ break; >+ default: >+ i = 0; /* failure */ >+ } >+ >+ xfree(p); >+ >+ if (fwd->listen_port == 0 && fwd->connect_port == 0) >+ i = 0; /* failure */ >+ >+ return(i); > } >Index: readconf.h >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/readconf.h,v >retrieving revision 1.42 >diff -u -r1.42 readconf.h >--- readconf.h 16 May 2003 01:39:05 -0000 1.42 >+++ readconf.h 4 Jun 2003 10:23:42 -0000 >@@ -21,9 +21,10 @@ > /* Data structure for representing a forwarding request. */ > > typedef struct { >- u_short port; /* Port to forward. */ >- char *host; /* Host to connect. */ >- u_short host_port; /* Port to connect on host. */ >+ char *listen_host; /* Host (address) to listen on. */ >+ u_short listen_port; /* Port to forward. */ >+ char *connect_host; /* Host to connect. */ >+ u_short connect_port; /* Port to connect on connect_host. */ > } Forward; > /* Data structure for representing option data. */ > >@@ -106,11 +107,14 @@ > void initialize_options(Options *); > void fill_default_options(Options *); > int read_config_file(const char *, const char *, Options *); >+int parse_forward(Forward *, const char *); > > int > process_config_line(Options *, const char *, char *, const char *, int, int *); > >-void add_local_forward(Options *, u_short, const char *, u_short); >-void add_remote_forward(Options *, u_short, const char *, u_short); >+void >+add_local_forward(Options *, const char *, u_short, const char *, u_short); >+void >+add_remote_forward(Options *, const char *, u_short, const char *, u_short); > > #endif /* READCONF_H */ >Index: servconf.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/servconf.c,v >retrieving revision 1.108 >diff -u -r1.108 servconf.c >--- servconf.c 4 Jun 2003 09:06:59 -0000 1.108 >+++ servconf.c 4 Jun 2003 10:23:42 -0000 >@@ -427,6 +427,7 @@ > char *cp, **charptr, *arg, *p; > int *intptr, value, i, n; > ServerOpCodes opcode; >+ ushort port; > > cp = line; > arg = strdelim(&cp); >@@ -499,39 +500,27 @@ > > case sListenAddress: > arg = strdelim(&cp); >- if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) >+ if (!arg || *arg == '\0') > fatal("%s line %d: missing inet addr.", > filename, linenum); >- if (*arg == '[') { >- if ((p = strchr(arg, ']')) == NULL) >- fatal("%s line %d: bad ipv6 inet addr usage.", >+ p = hpdelim(&arg); >+ if (!p) >+ fatal("%s line %d: bad inet addr:port usage.", >+ filename, linenum); >+ p = cleanhostname(p); >+ if (arg) { >+ port = a2port(arg); >+ if (port == 0) { >+ fatal("%s line %d: bad port number.", > filename, linenum); >- arg++; >- memmove(p, p+1, strlen(p+1)+1); >- } else if (((p = strchr(arg, ':')) == NULL) || >- (strchr(p+1, ':') != NULL)) { >- add_listen_addr(options, arg, 0); >- break; >+ /* NOTREACHED */ >+ } >+ } else { >+ port = 0; > } >- if (*p == ':') { >- u_short port; > >- p++; >- if (*p == '\0') >- fatal("%s line %d: bad inet addr:port usage.", >- filename, linenum); >- else { >- *(p-1) = '\0'; >- if ((port = a2port(p)) == 0) >- fatal("%s line %d: bad port number.", >- filename, linenum); >- add_listen_addr(options, arg, port); >- } >- } else if (*p == '\0') >- add_listen_addr(options, arg, 0); >- else >- fatal("%s line %d: bad inet addr usage.", >- filename, linenum); >+ add_listen_addr(options, p, port); >+ > break; > > case sHostKeyFile: >Index: ssh.1 >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/ssh.1,v >retrieving revision 1.131 >diff -u -r1.131 ssh.1 >--- ssh.1 23 May 2003 08:44:23 -0000 1.131 >+++ ssh.1 4 Jun 2003 10:23:43 -0000 >@@ -61,9 +61,10 @@ > .Op Fl F Ar configfile > .Oo Fl L Xo > .Sm off >-.Ar port : >+.Ar [ listenhost : ] >+.Ar listenport : > .Ar host : >-.Ar hostport >+.Ar port > .Sm on > .Xc > .Oc >@@ -71,9 +72,10 @@ > .Bk -words > .Oo Fl R Xo > .Sm off >-.Ar port : >+.Ar [ listenhost : ] >+.Ar listenport : > .Ar host : >-.Ar hostport >+.Ar port > .Sm on > .Xc > .Oc >@@ -606,46 +608,52 @@ > will be ignored. > The default for the per-user configuration file is > .Pa $HOME/.ssh/config . >-.It Fl L Ar port:host:hostport >+.It Fl L Ar [listenhost:]listenport:host:port > Specifies that the given port on the local (client) host is to be > forwarded to the given host and port on the remote side. > This works by allocating a socket to listen to > .Ar port >-on the local side, and whenever a connection is made to this port, the >+on the local side (optionally binding it to >+.Ar listenhost >+), and whenever a connection is made to this port, the > connection is forwarded over the secure channel, and a connection is > made to > .Ar host > port >-.Ar hostport >+.Ar port > from the remote machine. > Port forwardings can also be specified in the configuration file. > Only root can forward privileged ports. > IPv6 addresses can be specified with an alternative syntax: >-.Ar port/host/hostport >-.It Fl R Ar port:host:hostport >+.Ar [listenhost/]listenport/host/port >+.It Fl R Ar [listenhost:]listenport:host:port > Specifies that the given port on the remote (server) host is to be > forwarded to the given host and port on the local side. > This works by allocating a socket to listen to > .Ar port >-on the remote side, and whenever a connection is made to this port, the >+on the remote side (optionally binding it to >+.Ar listenhost >+), and whenever a connection is made to this port, the > connection is forwarded over the secure channel, and a connection is > made to > .Ar host > port >-.Ar hostport >+.Ar port > from the local machine. > Port forwardings can also be specified in the configuration file. > Privileged ports can be forwarded only when > logging in as root on the remote machine. > IPv6 addresses can be specified with an alternative syntax: >-.Ar port/host/hostport >-.It Fl D Ar port >+.Ar [listenhost/]listenport/host/port >+.It Fl D Ar [listenhost:]port > Specifies a local > .Dq dynamic > application-level port forwarding. > This works by allocating a socket to listen to > .Ar port >-on the local side, and whenever a connection is made to this port, the >+on the local side, (optionally binding it to >+.Ar listenhost >+) and whenever a connection is made to this port, the > connection is forwarded over the secure channel, and the application > protocol is then used to determine where to connect to from the > remote machine. >Index: ssh.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/ssh.c,v >retrieving revision 1.172 >diff -u -r1.172 ssh.c >--- ssh.c 18 May 2003 10:52:40 -0000 1.172 >+++ ssh.c 4 Jun 2003 10:40:54 -0000 >@@ -180,11 +180,11 @@ > fprintf(stderr, " -c cipher Select encryption algorithm\n"); > fprintf(stderr, " -m macs Specify MAC algorithms for protocol version 2.\n"); > fprintf(stderr, " -p port Connect to this port. Server must be on the same port.\n"); >- fprintf(stderr, " -L listen-port:host:port Forward local port to remote address\n"); >- fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); >+ fprintf(stderr, " -L [listen-host]:listen-port:host:port Forward local port to remote address\n"); >+ fprintf(stderr, " -R [listen-host]:listen-port:host:port Forward remote port to local address\n"); > fprintf(stderr, " These cause %s to listen for connections on a port, and\n", __progname); > fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); >- fprintf(stderr, " -D port Enable dynamic application-level port forwarding.\n"); >+ fprintf(stderr, " -D [listen-host]:port Enable dynamic application-level port forwarding.\n"); > fprintf(stderr, " -C Enable compression.\n"); > fprintf(stderr, " -N Do not execute a shell or command.\n"); > fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); >@@ -209,14 +209,15 @@ > main(int ac, char **av) > { > int i, opt, exit_status; >- u_short fwd_port, fwd_host_port; >- char sfwd_port[6], sfwd_host_port[6]; >+ u_short fwd_lport; >+ char *fwd_lhost; > char *p, *cp, buf[256]; > struct stat st; > struct passwd *pw; > int dummy; > extern int optind, optreset; > extern char *optarg; >+ Forward fwd; > > __progname = get_progname(av[0]); > init_rng(); >@@ -422,39 +423,56 @@ > break; > > case 'L': >- case 'R': >- if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]", >- sfwd_port, buf, sfwd_host_port) != 3 && >- sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]", >- sfwd_port, buf, sfwd_host_port) != 3) { >+ if (parse_forward(&fwd, optarg)) { >+ add_local_forward(&options, >+ fwd.listen_host, fwd.listen_port, >+ fwd.connect_host, fwd.connect_port); >+ } else { > fprintf(stderr, > "Bad forwarding specification '%s'\n", > optarg); > usage(); >+ exit(1); > /* NOTREACHED */ > } >- if ((fwd_port = a2port(sfwd_port)) == 0 || >- (fwd_host_port = a2port(sfwd_host_port)) == 0) { >+ break; >+ >+ case 'R': >+ if (parse_forward(&fwd, optarg)) { >+ add_remote_forward(&options, >+ fwd.listen_host, fwd.listen_port, >+ fwd.connect_host, fwd.connect_port); >+ } else { > fprintf(stderr, >- "Bad forwarding port(s) '%s'\n", optarg); >+ "Bad forwarding specification '%s'\n", >+ optarg); >+ usage(); > exit(1); >+ /* NOTREACHED */ > } >- if (opt == 'L') >- add_local_forward(&options, fwd_port, buf, >- fwd_host_port); >- else if (opt == 'R') >- add_remote_forward(&options, fwd_port, buf, >- fwd_host_port); > break; > > case 'D': >- fwd_port = a2port(optarg); >- if (fwd_port == 0) { >+ cp = p = xstrdup(optarg); >+ fwd_lport = 0; >+ fwd_lhost = hpdelim(&cp); /* may be NULL */ >+ if (cp) { >+ fwd_lport = a2port(cp); >+ fwd_lhost = cleanhostname(fwd_lhost); >+ } else { >+ fwd_lport = a2port(fwd_lhost); >+ fwd_lhost = ""; >+ } >+ >+ if (fwd_lport == 0) { > fprintf(stderr, "Bad dynamic port '%s'\n", > optarg); >+ xfree(p); > exit(1); > } >- add_local_forward(&options, fwd_port, "socks4", 0); >+ add_local_forward(&options, >+ fwd_lhost, fwd_lport, "socks4", 0); >+ xfree(p); > break; > > case 'C': >@@ -805,17 +823,23 @@ > { > int success = 0; > int i; >+ char *listen_host; > > /* Initiate local TCP/IP port forwardings. */ > for (i = 0; i < options.num_local_forwards; i++) { >- debug("Connections to local port %d forwarded to remote address %.200s:%d", >- options.local_forwards[i].port, >- options.local_forwards[i].host, >- options.local_forwards[i].host_port); >+ listen_host = options.local_forwards[i].listen_host; >+ if (listen_host && listen_host[0] == '\0' && !options.gateway_ports) >+ listen_host = NULL; >+ debug("Local connections to %.200s:%d forwarded to remote address %.200s:%d", >+ listen_host, >+ options.local_forwards[i].listen_port, >+ options.local_forwards[i].connect_host, >+ options.local_forwards[i].connect_port); > success += channel_setup_local_fwd_listener( >- options.local_forwards[i].port, >- options.local_forwards[i].host, >- options.local_forwards[i].host_port, >+ listen_host, >+ options.local_forwards[i].listen_port, >+ options.local_forwards[i].connect_host, >+ options.local_forwards[i].connect_port, > options.gateway_ports); > } > if (i > 0 && success == 0) >@@ -823,14 +847,19 @@ > > /* Initiate remote TCP/IP port forwardings. */ > for (i = 0; i < options.num_remote_forwards; i++) { >- debug("Connections to remote port %d forwarded to local address %.200s:%d", >- options.remote_forwards[i].port, >- options.remote_forwards[i].host, >- options.remote_forwards[i].host_port); >+ listen_host = options.remote_forwards[i].listen_host; >+ if (listen_host && listen_host[0] == '\0' && !options.gateway_ports) >+ listen_host = NULL; >+ debug("Remote connections from %.200s:%d forwarded to local address %.200s:%d", >+ listen_host, >+ options.remote_forwards[i].listen_port, >+ options.remote_forwards[i].connect_host, >+ options.remote_forwards[i].connect_port); > channel_request_remote_forwarding( >- options.remote_forwards[i].port, >- options.remote_forwards[i].host, >- options.remote_forwards[i].host_port); >+ listen_host, >+ options.remote_forwards[i].listen_port, >+ options.remote_forwards[i].connect_host, >+ options.remote_forwards[i].connect_port); > } > } > >@@ -1009,12 +1038,12 @@ > } > debug("remote forward %s for: listen %d, connect %s:%d", > type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", >- options.remote_forwards[i].port, >- options.remote_forwards[i].host, >- options.remote_forwards[i].host_port); >+ options.remote_forwards[i].listen_port, >+ options.remote_forwards[i].connect_host, >+ options.remote_forwards[i].connect_port); > if (type == SSH2_MSG_REQUEST_FAILURE) > logit("Warning: remote port forwarding failed for listen port %d", >- options.remote_forwards[i].port); >+ options.remote_forwards[i].listen_port); > } > > /* request pty/x11/agent/tcpfwd/shell for channel */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 413
:
179
|
180
|
182
|
217
|
219
|
229
|
321
|
666
|
782
|
783
|
784
|
791
|
792
|
806
|
834