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) |
- 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 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.231 2005/02/16 09:56:44 otto Exp $"); | 43 | RCSID("$OpenBSD: ssh.c,v 1.232 2005/03/01 10:09:52 djm Exp $"); |
44 | 44 | ||
45 | #include <openssl/evp.h> | 45 | #include <openssl/evp.h> |
46 | #include <openssl/err.h> | 46 | #include <openssl/err.h> |
@@ -158,9 +158,10 @@ usage(void) | |||
158 | { | 158 | { |
159 | fprintf(stderr, | 159 | fprintf(stderr, |
160 | "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" | 160 | "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" |
161 | " [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n" | 161 | " [-D [listen-host:]port] [-e escape_char] [-F configfile]\n" |
162 | " [-L port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd]\n" | 162 | " [-i identity_file] [-L [listen-host:]port:host:hostport]\n" |
163 | " [-o option] [-p port] [-R port:host:hostport] [-S ctl_path]\n" | 163 | " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" |
164 | " [-R [listen-host:]port:host:hostport] [-S ctl_path]\n" | ||
164 | " [user@]hostname [command]\n" | 165 | " [user@]hostname [command]\n" |
165 | ); | 166 | ); |
166 | exit(1); | 167 | exit(1); |
@@ -178,14 +179,13 @@ int | |||
178 | main(int ac, char **av) | 179 | main(int ac, char **av) |
179 | { | 180 | { |
180 | int i, opt, exit_status; | 181 | int i, opt, exit_status; |
181 | u_short fwd_port, fwd_host_port; | ||
182 | char sfwd_port[6], sfwd_host_port[6]; | ||
183 | char *p, *cp, *line, buf[256]; | 182 | char *p, *cp, *line, buf[256]; |
184 | struct stat st; | 183 | struct stat st; |
185 | struct passwd *pw; | 184 | struct passwd *pw; |
186 | int dummy; | 185 | int dummy; |
187 | extern int optind, optreset; | 186 | extern int optind, optreset; |
188 | extern char *optarg; | 187 | extern char *optarg; |
188 | Forward fwd; | ||
189 | 189 | ||
190 | __progname = ssh_get_progname(av[0]); | 190 | __progname = ssh_get_progname(av[0]); |
191 | init_rng(); | 191 | init_rng(); |
@@ -401,39 +401,51 @@ again: | |||
401 | break; | 401 | break; |
402 | 402 | ||
403 | case 'L': | 403 | case 'L': |
404 | case 'R': | 404 | if (parse_forward(&fwd, optarg)) |
405 | if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]", | 405 | add_local_forward(&options, &fwd); |
406 | sfwd_port, buf, sfwd_host_port) != 3 && | 406 | else { |
407 | sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]", | ||
408 | sfwd_port, buf, sfwd_host_port) != 3) { | ||
409 | fprintf(stderr, | 407 | fprintf(stderr, |
410 | "Bad forwarding specification '%s'\n", | 408 | "Bad local forwarding specification '%s'\n", |
411 | optarg); | 409 | optarg); |
412 | usage(); | 410 | exit(1); |
413 | /* NOTREACHED */ | ||
414 | } | 411 | } |
415 | if ((fwd_port = a2port(sfwd_port)) == 0 || | 412 | break; |
416 | (fwd_host_port = a2port(sfwd_host_port)) == 0) { | 413 | |
414 | case 'R': | ||
415 | if (parse_forward(&fwd, optarg)) { | ||
416 | add_remote_forward(&options, &fwd); | ||
417 | } else { | ||
417 | fprintf(stderr, | 418 | fprintf(stderr, |
418 | "Bad forwarding port(s) '%s'\n", optarg); | 419 | "Bad remote forwarding specification " |
420 | "'%s'\n", optarg); | ||
419 | exit(1); | 421 | exit(1); |
420 | } | 422 | } |
421 | if (opt == 'L') | ||
422 | add_local_forward(&options, fwd_port, buf, | ||
423 | fwd_host_port); | ||
424 | else if (opt == 'R') | ||
425 | add_remote_forward(&options, fwd_port, buf, | ||
426 | fwd_host_port); | ||
427 | break; | 423 | break; |
428 | 424 | ||
429 | case 'D': | 425 | case 'D': |
430 | fwd_port = a2port(optarg); | 426 | cp = p = xstrdup(optarg); |
431 | if (fwd_port == 0) { | 427 | memset(&fwd, '\0', sizeof(fwd)); |
428 | fwd.connect_host = "socks"; | ||
429 | if ((fwd.listen_host = hpdelim(&cp)) == NULL) { | ||
430 | fprintf(stderr, "Bad dynamic forwarding " | ||
431 | "specification '%.100s'\n", optarg); | ||
432 | exit(1); | ||
433 | } | ||
434 | if (cp != NULL) { | ||
435 | fwd.listen_port = a2port(cp); | ||
436 | fwd.listen_host = cleanhostname(fwd.listen_host); | ||
437 | } else { | ||
438 | fwd.listen_port = a2port(fwd.listen_host); | ||
439 | fwd.listen_host = ""; | ||
440 | } | ||
441 | |||
442 | if (fwd.listen_port == 0) { | ||
432 | fprintf(stderr, "Bad dynamic port '%s'\n", | 443 | fprintf(stderr, "Bad dynamic port '%s'\n", |
433 | optarg); | 444 | optarg); |
434 | exit(1); | 445 | exit(1); |
435 | } | 446 | } |
436 | add_local_forward(&options, fwd_port, "socks", 0); | 447 | add_local_forward(&options, &fwd); |
448 | xfree(p); | ||
437 | break; | 449 | break; |
438 | 450 | ||
439 | case 'C': | 451 | case 'C': |
@@ -842,14 +854,19 @@ ssh_init_forwarding(void) | |||
842 | 854 | ||
843 | /* Initiate local TCP/IP port forwardings. */ | 855 | /* Initiate local TCP/IP port forwardings. */ |
844 | for (i = 0; i < options.num_local_forwards; i++) { | 856 | for (i = 0; i < options.num_local_forwards; i++) { |
845 | debug("Connections to local port %d forwarded to remote address %.200s:%d", | 857 | debug("Local connections to %.200s:%d forwarded to remote " |
846 | options.local_forwards[i].port, | 858 | "address %.200s:%d", |
847 | options.local_forwards[i].host, | 859 | (options.local_forwards[i].listen_host == NULL) ? |
848 | options.local_forwards[i].host_port); | 860 | (options.gateway_ports ? "*" : "LOCALHOST") : |
861 | options.local_forwards[i].listen_host, | ||
862 | options.local_forwards[i].listen_port, | ||
863 | options.local_forwards[i].connect_host, | ||
864 | options.local_forwards[i].connect_port); | ||
849 | success += channel_setup_local_fwd_listener( | 865 | success += channel_setup_local_fwd_listener( |
850 | options.local_forwards[i].port, | 866 | options.local_forwards[i].listen_host, |
851 | options.local_forwards[i].host, | 867 | options.local_forwards[i].listen_port, |
852 | options.local_forwards[i].host_port, | 868 | options.local_forwards[i].connect_host, |
869 | options.local_forwards[i].connect_port, | ||
853 | options.gateway_ports); | 870 | options.gateway_ports); |
854 | } | 871 | } |
855 | if (i > 0 && success == 0) | 872 | if (i > 0 && success == 0) |
@@ -857,14 +874,17 @@ ssh_init_forwarding(void) | |||
857 | 874 | ||
858 | /* Initiate remote TCP/IP port forwardings. */ | 875 | /* Initiate remote TCP/IP port forwardings. */ |
859 | for (i = 0; i < options.num_remote_forwards; i++) { | 876 | for (i = 0; i < options.num_remote_forwards; i++) { |
860 | debug("Connections to remote port %d forwarded to local address %.200s:%d", | 877 | debug("Remote connections from %.200s:%d forwarded to " |
861 | options.remote_forwards[i].port, | 878 | "local address %.200s:%d", |
862 | options.remote_forwards[i].host, | 879 | options.remote_forwards[i].listen_host, |
863 | options.remote_forwards[i].host_port); | 880 | options.remote_forwards[i].listen_port, |
881 | options.remote_forwards[i].connect_host, | ||
882 | options.remote_forwards[i].connect_port); | ||
864 | channel_request_remote_forwarding( | 883 | channel_request_remote_forwarding( |
865 | options.remote_forwards[i].port, | 884 | options.remote_forwards[i].listen_host, |
866 | options.remote_forwards[i].host, | 885 | options.remote_forwards[i].listen_port, |
867 | options.remote_forwards[i].host_port); | 886 | options.remote_forwards[i].connect_host, |
887 | options.remote_forwards[i].connect_port); | ||
868 | } | 888 | } |
869 | } | 889 | } |
870 | 890 | ||
@@ -1040,12 +1060,12 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) | |||
1040 | return; | 1060 | return; |
1041 | debug("remote forward %s for: listen %d, connect %s:%d", | 1061 | debug("remote forward %s for: listen %d, connect %s:%d", |
1042 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", | 1062 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", |
1043 | options.remote_forwards[i].port, | 1063 | options.remote_forwards[i].listen_port, |
1044 | options.remote_forwards[i].host, | 1064 | options.remote_forwards[i].connect_host, |
1045 | options.remote_forwards[i].host_port); | 1065 | options.remote_forwards[i].connect_port); |
1046 | if (type == SSH2_MSG_REQUEST_FAILURE) | 1066 | if (type == SSH2_MSG_REQUEST_FAILURE) |
1047 | logit("Warning: remote port forwarding failed for listen port %d", | 1067 | logit("Warning: remote port forwarding failed for listen " |
1048 | options.remote_forwards[i].port); | 1068 | "port %d", options.remote_forwards[i].listen_port); |
1049 | } | 1069 | } |
1050 | 1070 | ||
1051 | static void | 1071 | static void |