From f91ee4c3def4de8b4b9409f07ab26a61e535e1e6 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 1 Mar 2005 21:24:33 +1100 Subject: - 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. --- ssh.c | 110 +++++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 45 deletions(-) (limited to 'ssh.c') diff --git a/ssh.c b/ssh.c index 1f50727e9..99b25afcc 100644 --- a/ssh.c +++ b/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 #include @@ -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 -- cgit v1.2.3