diff options
author | Damien Miller <djm@mindrot.org> | 2005-03-01 21:24:33 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2005-03-01 21:24:33 +1100 |
commit | f91ee4c3def4de8b4b9409f07ab26a61e535e1e6 (patch) | |
tree | 92d9f883c3c34f0d80b49a7855dcc2514798cf02 /ssh.c | |
parent | 1717fd422f2c5691d745a7daf6908df9a6458904 (diff) | |
download | openssh-git-f91ee4c3def4de8b4b9409f07ab26a61e535e1e6.tar.gz |
- djm@cvs.openbsd.org 2005/03/01 10:09:52
[auth-options.c channels.c channels.h clientloop.c compat.c compat.h]
[misc.c misc.h readconf.c readconf.h servconf.c ssh.1 ssh.c ssh_config.5]
[sshd_config.5]
bz#413: allow optional specification of bind address for port forwardings.
Patch originally by Dan Astorian, but worked on by several people
Adds GatewayPorts=clientspecified option on server to allow remote
forwards to bind to client-specified ports.
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 110 |
1 files changed, 65 insertions, 45 deletions
@@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.231 2005/02/16 09:56:44 otto Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.232 2005/03/01 10:09:52 djm Exp $"); #include <openssl/evp.h> #include <openssl/err.h> @@ -158,9 +158,10 @@ usage(void) { fprintf(stderr, "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" -" [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n" -" [-L port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd]\n" -" [-o option] [-p port] [-R port:host:hostport] [-S ctl_path]\n" +" [-D [listen-host:]port] [-e escape_char] [-F configfile]\n" +" [-i identity_file] [-L [listen-host:]port:host:hostport]\n" +" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" +" [-R [listen-host:]port:host:hostport] [-S ctl_path]\n" " [user@]hostname [command]\n" ); exit(1); @@ -178,14 +179,13 @@ int 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]; char *p, *cp, *line, buf[256]; struct stat st; struct passwd *pw; int dummy; extern int optind, optreset; extern char *optarg; + Forward fwd; __progname = ssh_get_progname(av[0]); init_rng(); @@ -401,39 +401,51 @@ again: 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); + else { fprintf(stderr, - "Bad forwarding specification '%s'\n", + "Bad local forwarding specification '%s'\n", optarg); - usage(); - /* NOTREACHED */ + exit(1); } - 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); + } else { fprintf(stderr, - "Bad forwarding port(s) '%s'\n", optarg); + "Bad remote forwarding specification " + "'%s'\n", optarg); exit(1); } - 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); + memset(&fwd, '\0', sizeof(fwd)); + fwd.connect_host = "socks"; + if ((fwd.listen_host = hpdelim(&cp)) == NULL) { + fprintf(stderr, "Bad dynamic forwarding " + "specification '%.100s'\n", optarg); + exit(1); + } + if (cp != NULL) { + fwd.listen_port = a2port(cp); + fwd.listen_host = cleanhostname(fwd.listen_host); + } else { + fwd.listen_port = a2port(fwd.listen_host); + fwd.listen_host = ""; + } + + if (fwd.listen_port == 0) { fprintf(stderr, "Bad dynamic port '%s'\n", optarg); exit(1); } - add_local_forward(&options, fwd_port, "socks", 0); + add_local_forward(&options, &fwd); + xfree(p); break; case 'C': @@ -842,14 +854,19 @@ ssh_init_forwarding(void) /* 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); + debug("Local connections to %.200s:%d forwarded to remote " + "address %.200s:%d", + (options.local_forwards[i].listen_host == NULL) ? + (options.gateway_ports ? "*" : "LOCALHOST") : + options.local_forwards[i].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, + options.local_forwards[i].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) @@ -857,14 +874,17 @@ ssh_init_forwarding(void) /* 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); + debug("Remote connections from %.200s:%d forwarded to " + "local address %.200s:%d", + options.remote_forwards[i].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); + options.remote_forwards[i].listen_host, + options.remote_forwards[i].listen_port, + options.remote_forwards[i].connect_host, + options.remote_forwards[i].connect_port); } } @@ -1040,12 +1060,12 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) return; 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); + logit("Warning: remote port forwarding failed for listen " + "port %d", options.remote_forwards[i].listen_port); } static void |