diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2005-03-01 10:09:53 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2005-03-01 10:09:53 +0000 |
commit | e491a20dd7bb33c41c50ddbd0275af9e60dec8c4 (patch) | |
tree | 19be461455115f8ce09a4129004626612a92a9c6 /usr.bin/ssh/ssh.c | |
parent | 14bcbbf0d0fc71b5721cfe1d741f78705be73ebb (diff) |
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.
ok markus@
Diffstat (limited to 'usr.bin/ssh/ssh.c')
-rw-r--r-- | usr.bin/ssh/ssh.c | 110 |
1 files changed, 65 insertions, 45 deletions
diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index c767dc7840b..68c7741e495 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -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; /* * Save the original real uid. It will be needed later (uid-swapping @@ -396,39 +396,51 @@ again: break; case 'L': - case 'R': - if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]", - sfwd_port, buf, sfwd_host_port) != 3 && - sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]", - 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': @@ -831,14 +843,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) @@ -846,14 +863,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); } } @@ -1029,12 +1049,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 |