diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | auth-options.c | 28 | ||||
-rw-r--r-- | channels.c | 82 | ||||
-rw-r--r-- | channels.h | 10 | ||||
-rw-r--r-- | clientloop.c | 49 | ||||
-rw-r--r-- | compat.c | 20 | ||||
-rw-r--r-- | compat.h | 3 | ||||
-rw-r--r-- | misc.c | 44 | ||||
-rw-r--r-- | misc.h | 3 | ||||
-rw-r--r-- | readconf.c | 157 | ||||
-rw-r--r-- | readconf.h | 14 | ||||
-rw-r--r-- | servconf.c | 65 | ||||
-rw-r--r-- | ssh.1 | 59 | ||||
-rw-r--r-- | ssh.c | 110 | ||||
-rw-r--r-- | ssh_config.5 | 70 | ||||
-rw-r--r-- | sshd_config.5 | 15 |
16 files changed, 525 insertions, 214 deletions
@@ -19,6 +19,14 @@ | |||
19 | [ssh_config.5] | 19 | [ssh_config.5] |
20 | bz#849: document timeout on untrusted x11 forwarding sessions. Reported by | 20 | bz#849: document timeout on untrusted x11 forwarding sessions. Reported by |
21 | orion AT cora.nwra.com; ok markus@ | 21 | orion AT cora.nwra.com; ok markus@ |
22 | - djm@cvs.openbsd.org 2005/03/01 10:09:52 | ||
23 | [auth-options.c channels.c channels.h clientloop.c compat.c compat.h] | ||
24 | [misc.c misc.h readconf.c readconf.h servconf.c ssh.1 ssh.c ssh_config.5] | ||
25 | [sshd_config.5] | ||
26 | bz#413: allow optional specification of bind address for port forwardings. | ||
27 | Patch originally by Dan Astorian, but worked on by several people | ||
28 | Adds GatewayPorts=clientspecified option on server to allow remote | ||
29 | forwards to bind to client-specified ports. | ||
22 | 30 | ||
23 | 20050226 | 31 | 20050226 |
24 | - (dtucker) [openbsd-compat/bsd-openpty.c openbsd-compat/inet_ntop.c] | 32 | - (dtucker) [openbsd-compat/bsd-openpty.c openbsd-compat/inet_ntop.c] |
@@ -2195,4 +2203,4 @@ | |||
2195 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 2203 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
2196 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 2204 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
2197 | 2205 | ||
2198 | $Id: ChangeLog,v 1.3671 2005/03/01 10:17:31 djm Exp $ | 2206 | $Id: ChangeLog,v 1.3672 2005/03/01 10:24:33 djm Exp $ |
diff --git a/auth-options.c b/auth-options.c index 0e146ab15..04d12d66e 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include "includes.h" | 12 | #include "includes.h" |
13 | RCSID("$OpenBSD: auth-options.c,v 1.28 2003/06/02 09:17:34 markus Exp $"); | 13 | RCSID("$OpenBSD: auth-options.c,v 1.29 2005/03/01 10:09:52 djm Exp $"); |
14 | 14 | ||
15 | #include "xmalloc.h" | 15 | #include "xmalloc.h" |
16 | #include "match.h" | 16 | #include "match.h" |
@@ -217,7 +217,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) | |||
217 | } | 217 | } |
218 | cp = "permitopen=\""; | 218 | cp = "permitopen=\""; |
219 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | 219 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { |
220 | char host[256], sport[6]; | 220 | char *host, *p; |
221 | u_short port; | 221 | u_short port; |
222 | char *patterns = xmalloc(strlen(opts) + 1); | 222 | char *patterns = xmalloc(strlen(opts) + 1); |
223 | 223 | ||
@@ -236,25 +236,29 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) | |||
236 | if (!*opts) { | 236 | if (!*opts) { |
237 | debug("%.100s, line %lu: missing end quote", | 237 | debug("%.100s, line %lu: missing end quote", |
238 | file, linenum); | 238 | file, linenum); |
239 | auth_debug_add("%.100s, line %lu: missing end quote", | 239 | auth_debug_add("%.100s, line %lu: missing " |
240 | file, linenum); | 240 | "end quote", file, linenum); |
241 | xfree(patterns); | 241 | xfree(patterns); |
242 | goto bad_option; | 242 | goto bad_option; |
243 | } | 243 | } |
244 | patterns[i] = 0; | 244 | patterns[i] = 0; |
245 | opts++; | 245 | opts++; |
246 | if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 && | 246 | p = patterns; |
247 | sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) { | 247 | host = hpdelim(&p); |
248 | debug("%.100s, line %lu: Bad permitopen specification " | 248 | if (host == NULL || strlen(host) >= NI_MAXHOST) { |
249 | "<%.100s>", file, linenum, patterns); | 249 | debug("%.100s, line %lu: Bad permitopen " |
250 | "specification <%.100s>", file, linenum, | ||
251 | patterns); | ||
250 | auth_debug_add("%.100s, line %lu: " | 252 | auth_debug_add("%.100s, line %lu: " |
251 | "Bad permitopen specification", file, linenum); | 253 | "Bad permitopen specification", file, |
254 | linenum); | ||
252 | xfree(patterns); | 255 | xfree(patterns); |
253 | goto bad_option; | 256 | goto bad_option; |
254 | } | 257 | } |
255 | if ((port = a2port(sport)) == 0) { | 258 | host = cleanhostname(host); |
256 | debug("%.100s, line %lu: Bad permitopen port <%.100s>", | 259 | if (p == NULL || (port = a2port(p)) == 0) { |
257 | file, linenum, sport); | 260 | debug("%.100s, line %lu: Bad permitopen port " |
261 | "<%.100s>", file, linenum, p ? p : ""); | ||
258 | auth_debug_add("%.100s, line %lu: " | 262 | auth_debug_add("%.100s, line %lu: " |
259 | "Bad permitopen port", file, linenum); | 263 | "Bad permitopen port", file, linenum); |
260 | xfree(patterns); | 264 | xfree(patterns); |
diff --git a/channels.c b/channels.c index 8550e51ca..1be213bce 100644 --- a/channels.c +++ b/channels.c | |||
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: channels.c,v 1.211 2004/10/29 21:47:15 djm Exp $"); | 42 | RCSID("$OpenBSD: channels.c,v 1.212 2005/03/01 10:09:52 djm Exp $"); |
43 | 43 | ||
44 | #include "ssh.h" | 44 | #include "ssh.h" |
45 | #include "ssh1.h" | 45 | #include "ssh1.h" |
@@ -2179,14 +2179,14 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por | |||
2179 | const char *host_to_connect, u_short port_to_connect, int gateway_ports) | 2179 | const char *host_to_connect, u_short port_to_connect, int gateway_ports) |
2180 | { | 2180 | { |
2181 | Channel *c; | 2181 | Channel *c; |
2182 | int success, sock, on = 1; | 2182 | int sock, r, success = 0, on = 1, wildcard = 0, is_client; |
2183 | struct addrinfo hints, *ai, *aitop; | 2183 | struct addrinfo hints, *ai, *aitop; |
2184 | const char *host; | 2184 | const char *host, *addr; |
2185 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 2185 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
2186 | 2186 | ||
2187 | success = 0; | ||
2188 | host = (type == SSH_CHANNEL_RPORT_LISTENER) ? | 2187 | host = (type == SSH_CHANNEL_RPORT_LISTENER) ? |
2189 | listen_addr : host_to_connect; | 2188 | listen_addr : host_to_connect; |
2189 | is_client = (type == SSH_CHANNEL_PORT_LISTENER); | ||
2190 | 2190 | ||
2191 | if (host == NULL) { | 2191 | if (host == NULL) { |
2192 | error("No forward host name."); | 2192 | error("No forward host name."); |
@@ -2198,16 +2198,60 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por | |||
2198 | } | 2198 | } |
2199 | 2199 | ||
2200 | /* | 2200 | /* |
2201 | * Determine whether or not a port forward listens to loopback, | ||
2202 | * specified address or wildcard. On the client, a specified bind | ||
2203 | * address will always override gateway_ports. On the server, a | ||
2204 | * gateway_ports of 1 (``yes'') will override the client's | ||
2205 | * specification and force a wildcard bind, whereas a value of 2 | ||
2206 | * (``clientspecified'') will bind to whatever address the client | ||
2207 | * asked for. | ||
2208 | * | ||
2209 | * Special-case listen_addrs are: | ||
2210 | * | ||
2211 | * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR | ||
2212 | * "" (empty string), "*" -> wildcard v4/v6 | ||
2213 | * "localhost" -> loopback v4/v6 | ||
2214 | */ | ||
2215 | addr = NULL; | ||
2216 | if (listen_addr == NULL) { | ||
2217 | /* No address specified: default to gateway_ports setting */ | ||
2218 | if (gateway_ports) | ||
2219 | wildcard = 1; | ||
2220 | } else if (gateway_ports || is_client) { | ||
2221 | if (((datafellows & SSH_OLD_FORWARD_ADDR) && | ||
2222 | strcmp(listen_addr, "0.0.0.0") == 0) || | ||
2223 | *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || | ||
2224 | (!is_client && gateway_ports == 1)) | ||
2225 | wildcard = 1; | ||
2226 | else if (strcmp(listen_addr, "localhost") != 0) | ||
2227 | addr = listen_addr; | ||
2228 | } | ||
2229 | |||
2230 | debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s", | ||
2231 | type, wildcard, (addr == NULL) ? "NULL" : addr); | ||
2232 | |||
2233 | /* | ||
2201 | * getaddrinfo returns a loopback address if the hostname is | 2234 | * getaddrinfo returns a loopback address if the hostname is |
2202 | * set to NULL and hints.ai_flags is not AI_PASSIVE | 2235 | * set to NULL and hints.ai_flags is not AI_PASSIVE |
2203 | */ | 2236 | */ |
2204 | memset(&hints, 0, sizeof(hints)); | 2237 | memset(&hints, 0, sizeof(hints)); |
2205 | hints.ai_family = IPv4or6; | 2238 | hints.ai_family = IPv4or6; |
2206 | hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; | 2239 | hints.ai_flags = wildcard ? AI_PASSIVE : 0; |
2207 | hints.ai_socktype = SOCK_STREAM; | 2240 | hints.ai_socktype = SOCK_STREAM; |
2208 | snprintf(strport, sizeof strport, "%d", listen_port); | 2241 | snprintf(strport, sizeof strport, "%d", listen_port); |
2209 | if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) | 2242 | if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) { |
2210 | packet_disconnect("getaddrinfo: fatal error"); | 2243 | if (addr == NULL) { |
2244 | /* This really shouldn't happen */ | ||
2245 | packet_disconnect("getaddrinfo: fatal error: %s", | ||
2246 | gai_strerror(r)); | ||
2247 | } else { | ||
2248 | verbose("channel_setup_fwd_listener: " | ||
2249 | "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); | ||
2250 | packet_send_debug("channel_setup_fwd_listener: " | ||
2251 | "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); | ||
2252 | } | ||
2253 | aitop = NULL; | ||
2254 | } | ||
2211 | 2255 | ||
2212 | for (ai = aitop; ai; ai = ai->ai_next) { | 2256 | for (ai = aitop; ai; ai = ai->ai_next) { |
2213 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) | 2257 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) |
@@ -2290,11 +2334,12 @@ channel_cancel_rport_listener(const char *host, u_short port) | |||
2290 | 2334 | ||
2291 | /* protocol local port fwd, used by ssh (and sshd in v1) */ | 2335 | /* protocol local port fwd, used by ssh (and sshd in v1) */ |
2292 | int | 2336 | int |
2293 | channel_setup_local_fwd_listener(u_short listen_port, | 2337 | channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, |
2294 | const char *host_to_connect, u_short port_to_connect, int gateway_ports) | 2338 | const char *host_to_connect, u_short port_to_connect, int gateway_ports) |
2295 | { | 2339 | { |
2296 | return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, | 2340 | return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, |
2297 | NULL, listen_port, host_to_connect, port_to_connect, gateway_ports); | 2341 | listen_host, listen_port, host_to_connect, port_to_connect, |
2342 | gateway_ports); | ||
2298 | } | 2343 | } |
2299 | 2344 | ||
2300 | /* protocol v2 remote port fwd, used by sshd */ | 2345 | /* protocol v2 remote port fwd, used by sshd */ |
@@ -2312,7 +2357,7 @@ channel_setup_remote_fwd_listener(const char *listen_address, | |||
2312 | */ | 2357 | */ |
2313 | 2358 | ||
2314 | void | 2359 | void |
2315 | channel_request_remote_forwarding(u_short listen_port, | 2360 | channel_request_remote_forwarding(const char *listen_host, u_short listen_port, |
2316 | const char *host_to_connect, u_short port_to_connect) | 2361 | const char *host_to_connect, u_short port_to_connect) |
2317 | { | 2362 | { |
2318 | int type, success = 0; | 2363 | int type, success = 0; |
@@ -2323,7 +2368,14 @@ channel_request_remote_forwarding(u_short listen_port, | |||
2323 | 2368 | ||
2324 | /* Send the forward request to the remote side. */ | 2369 | /* Send the forward request to the remote side. */ |
2325 | if (compat20) { | 2370 | if (compat20) { |
2326 | const char *address_to_bind = "0.0.0.0"; | 2371 | const char *address_to_bind; |
2372 | if (listen_host == NULL) | ||
2373 | address_to_bind = "localhost"; | ||
2374 | else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) | ||
2375 | address_to_bind = ""; | ||
2376 | else | ||
2377 | address_to_bind = listen_host; | ||
2378 | |||
2327 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 2379 | packet_start(SSH2_MSG_GLOBAL_REQUEST); |
2328 | packet_put_cstring("tcpip-forward"); | 2380 | packet_put_cstring("tcpip-forward"); |
2329 | packet_put_char(1); /* boolean: want reply */ | 2381 | packet_put_char(1); /* boolean: want reply */ |
@@ -2369,10 +2421,9 @@ channel_request_remote_forwarding(u_short listen_port, | |||
2369 | * local side. | 2421 | * local side. |
2370 | */ | 2422 | */ |
2371 | void | 2423 | void |
2372 | channel_request_rforward_cancel(u_short port) | 2424 | channel_request_rforward_cancel(const char *host, u_short port) |
2373 | { | 2425 | { |
2374 | int i; | 2426 | int i; |
2375 | const char *address_to_bind = "0.0.0.0"; | ||
2376 | 2427 | ||
2377 | if (!compat20) | 2428 | if (!compat20) |
2378 | return; | 2429 | return; |
@@ -2389,7 +2440,7 @@ channel_request_rforward_cancel(u_short port) | |||
2389 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 2440 | packet_start(SSH2_MSG_GLOBAL_REQUEST); |
2390 | packet_put_cstring("cancel-tcpip-forward"); | 2441 | packet_put_cstring("cancel-tcpip-forward"); |
2391 | packet_put_char(0); | 2442 | packet_put_char(0); |
2392 | packet_put_cstring(address_to_bind); | 2443 | packet_put_cstring(host == NULL ? "" : host); |
2393 | packet_put_int(port); | 2444 | packet_put_int(port); |
2394 | packet_send(); | 2445 | packet_send(); |
2395 | 2446 | ||
@@ -2430,7 +2481,8 @@ channel_input_port_forward_request(int is_root, int gateway_ports) | |||
2430 | #endif | 2481 | #endif |
2431 | 2482 | ||
2432 | /* Initiate forwarding */ | 2483 | /* Initiate forwarding */ |
2433 | channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports); | 2484 | channel_setup_local_fwd_listener(NULL, port, hostname, |
2485 | host_port, gateway_ports); | ||
2434 | 2486 | ||
2435 | /* Free the argument string. */ | 2487 | /* Free the argument string. */ |
2436 | xfree(hostname); | 2488 | xfree(hostname); |
diff --git a/channels.h b/channels.h index c47de55c0..fc20fb2c3 100644 --- a/channels.h +++ b/channels.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.h,v 1.75 2004/10/29 21:47:15 djm Exp $ */ | 1 | /* $OpenBSD: channels.h,v 1.76 2005/03/01 10:09:52 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -203,9 +203,11 @@ void channel_clear_permitted_opens(void); | |||
203 | void channel_input_port_forward_request(int, int); | 203 | void channel_input_port_forward_request(int, int); |
204 | int channel_connect_to(const char *, u_short); | 204 | int channel_connect_to(const char *, u_short); |
205 | int channel_connect_by_listen_address(u_short); | 205 | int channel_connect_by_listen_address(u_short); |
206 | void channel_request_remote_forwarding(u_short, const char *, u_short); | 206 | void channel_request_remote_forwarding(const char *, u_short, |
207 | void channel_request_rforward_cancel(u_short port); | 207 | const char *, u_short); |
208 | int channel_setup_local_fwd_listener(u_short, const char *, u_short, int); | 208 | int channel_setup_local_fwd_listener(const char *, u_short, |
209 | const char *, u_short, int); | ||
210 | void channel_request_rforward_cancel(const char *host, u_short port); | ||
209 | int channel_setup_remote_fwd_listener(const char *, u_short, int); | 211 | int channel_setup_remote_fwd_listener(const char *, u_short, int); |
210 | int channel_cancel_rport_listener(const char *, u_short); | 212 | int channel_cancel_rport_listener(const char *, u_short); |
211 | 213 | ||
diff --git a/clientloop.c b/clientloop.c index 033a98a5b..1e250883f 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -59,7 +59,7 @@ | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "includes.h" | 61 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.134 2004/11/07 00:01:46 djm Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.135 2005/03/01 10:09:52 djm Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -763,11 +763,11 @@ static void | |||
763 | process_cmdline(void) | 763 | process_cmdline(void) |
764 | { | 764 | { |
765 | void (*handler)(int); | 765 | void (*handler)(int); |
766 | char *s, *cmd; | 766 | char *s, *cmd, *cancel_host; |
767 | u_short fwd_port, fwd_host_port; | ||
768 | char buf[1024], sfwd_port[6], sfwd_host_port[6]; | ||
769 | int delete = 0; | 767 | int delete = 0; |
770 | int local = 0; | 768 | int local = 0; |
769 | u_short cancel_port; | ||
770 | Forward fwd; | ||
771 | 771 | ||
772 | leave_raw_mode(); | 772 | leave_raw_mode(); |
773 | handler = signal(SIGINT, SIG_IGN); | 773 | handler = signal(SIGINT, SIG_IGN); |
@@ -813,37 +813,38 @@ process_cmdline(void) | |||
813 | s++; | 813 | s++; |
814 | 814 | ||
815 | if (delete) { | 815 | if (delete) { |
816 | if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) { | 816 | cancel_port = 0; |
817 | logit("Bad forwarding specification."); | 817 | cancel_host = hpdelim(&s); /* may be NULL */ |
818 | goto out; | 818 | if (s != NULL) { |
819 | cancel_port = a2port(s); | ||
820 | cancel_host = cleanhostname(cancel_host); | ||
821 | } else { | ||
822 | cancel_port = a2port(cancel_host); | ||
823 | cancel_host = NULL; | ||
819 | } | 824 | } |
820 | if ((fwd_host_port = a2port(sfwd_host_port)) == 0) { | 825 | if (cancel_port == 0) { |
821 | logit("Bad forwarding port(s)."); | 826 | logit("Bad forwarding close port"); |
822 | goto out; | 827 | goto out; |
823 | } | 828 | } |
824 | channel_request_rforward_cancel(fwd_host_port); | 829 | channel_request_rforward_cancel(cancel_host, cancel_port); |
825 | } else { | 830 | } else { |
826 | if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]", | 831 | if (!parse_forward(&fwd, s)) { |
827 | sfwd_port, buf, sfwd_host_port) != 3 && | ||
828 | sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", | ||
829 | sfwd_port, buf, sfwd_host_port) != 3) { | ||
830 | logit("Bad forwarding specification."); | 832 | logit("Bad forwarding specification."); |
831 | goto out; | 833 | goto out; |
832 | } | 834 | } |
833 | if ((fwd_port = a2port(sfwd_port)) == 0 || | ||
834 | (fwd_host_port = a2port(sfwd_host_port)) == 0) { | ||
835 | logit("Bad forwarding port(s)."); | ||
836 | goto out; | ||
837 | } | ||
838 | if (local) { | 835 | if (local) { |
839 | if (channel_setup_local_fwd_listener(fwd_port, buf, | 836 | if (channel_setup_local_fwd_listener(fwd.listen_host, |
840 | fwd_host_port, options.gateway_ports) < 0) { | 837 | fwd.listen_port, fwd.connect_host, |
838 | fwd.connect_port, options.gateway_ports) < 0) { | ||
841 | logit("Port forwarding failed."); | 839 | logit("Port forwarding failed."); |
842 | goto out; | 840 | goto out; |
843 | } | 841 | } |
844 | } else | 842 | } else { |
845 | channel_request_remote_forwarding(fwd_port, buf, | 843 | channel_request_remote_forwarding(fwd.listen_host, |
846 | fwd_host_port); | 844 | fwd.listen_port, fwd.connect_host, |
845 | fwd.connect_port); | ||
846 | } | ||
847 | |||
847 | logit("Forwarding port."); | 848 | logit("Forwarding port."); |
848 | } | 849 | } |
849 | 850 | ||
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: compat.c,v 1.70 2003/11/02 11:01:03 markus Exp $"); | 26 | RCSID("$OpenBSD: compat.c,v 1.71 2005/03/01 10:09:52 djm Exp $"); |
27 | 27 | ||
28 | #include "buffer.h" | 28 | #include "buffer.h" |
29 | #include "packet.h" | 29 | #include "packet.h" |
@@ -62,24 +62,28 @@ compat_datafellows(const char *version) | |||
62 | "OpenSSH_2.1*," | 62 | "OpenSSH_2.1*," |
63 | "OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| | 63 | "OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| |
64 | SSH_OLD_DHGEX|SSH_BUG_NOREKEY| | 64 | SSH_OLD_DHGEX|SSH_BUG_NOREKEY| |
65 | SSH_BUG_EXTEOF}, | 65 | SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, |
66 | { "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| | 66 | { "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| |
67 | SSH_OLD_DHGEX|SSH_BUG_NOREKEY| | 67 | SSH_OLD_DHGEX|SSH_BUG_NOREKEY| |
68 | SSH_BUG_EXTEOF}, | 68 | SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, |
69 | { "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| | 69 | { "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| |
70 | SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, | 70 | SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| |
71 | SSH_OLD_FORWARD_ADDR}, | ||
71 | { "OpenSSH_2.5.0p1*," | 72 | { "OpenSSH_2.5.0p1*," |
72 | "OpenSSH_2.5.1p1*", | 73 | "OpenSSH_2.5.1p1*", |
73 | SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| | 74 | SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| |
74 | SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, | 75 | SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| |
76 | SSH_OLD_FORWARD_ADDR}, | ||
75 | { "OpenSSH_2.5.0*," | 77 | { "OpenSSH_2.5.0*," |
76 | "OpenSSH_2.5.1*," | 78 | "OpenSSH_2.5.1*," |
77 | "OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY| | 79 | "OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY| |
78 | SSH_BUG_EXTEOF}, | 80 | SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, |
79 | { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, | 81 | { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| |
82 | SSH_OLD_FORWARD_ADDR}, | ||
80 | { "OpenSSH_2.*," | 83 | { "OpenSSH_2.*," |
81 | "OpenSSH_3.0*," | 84 | "OpenSSH_3.0*," |
82 | "OpenSSH_3.1*", SSH_BUG_EXTEOF}, | 85 | "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, |
86 | { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR }, | ||
83 | { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, | 87 | { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, |
84 | { "OpenSSH*", 0 }, | 88 | { "OpenSSH*", 0 }, |
85 | { "*MindTerm*", 0 }, | 89 | { "*MindTerm*", 0 }, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: compat.h,v 1.38 2004/07/11 17:48:47 deraadt Exp $ */ | 1 | /* $OpenBSD: compat.h,v 1.39 2005/03/01 10:09:52 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. |
@@ -55,6 +55,7 @@ | |||
55 | #define SSH_BUG_EXTEOF 0x00200000 | 55 | #define SSH_BUG_EXTEOF 0x00200000 |
56 | #define SSH_BUG_PROBE 0x00400000 | 56 | #define SSH_BUG_PROBE 0x00400000 |
57 | #define SSH_BUG_FIRSTKEX 0x00800000 | 57 | #define SSH_BUG_FIRSTKEX 0x00800000 |
58 | #define SSH_OLD_FORWARD_ADDR 0x01000000 | ||
58 | 59 | ||
59 | void enable_compat13(void); | 60 | void enable_compat13(void); |
60 | void enable_compat20(void); | 61 | void enable_compat20(void); |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: misc.c,v 1.27 2004/12/11 01:48:56 dtucker Exp $"); | 26 | RCSID("$OpenBSD: misc.c,v 1.28 2005/03/01 10:09:52 djm Exp $"); |
27 | 27 | ||
28 | #include "misc.h" | 28 | #include "misc.h" |
29 | #include "log.h" | 29 | #include "log.h" |
@@ -275,6 +275,48 @@ convtime(const char *s) | |||
275 | return total; | 275 | return total; |
276 | } | 276 | } |
277 | 277 | ||
278 | /* | ||
279 | * Search for next delimiter between hostnames/addresses and ports. | ||
280 | * Argument may be modified (for termination). | ||
281 | * Returns *cp if parsing succeeds. | ||
282 | * *cp is set to the start of the next delimiter, if one was found. | ||
283 | * If this is the last field, *cp is set to NULL. | ||
284 | */ | ||
285 | char * | ||
286 | hpdelim(char **cp) | ||
287 | { | ||
288 | char *s, *old; | ||
289 | |||
290 | if (cp == NULL || *cp == NULL) | ||
291 | return NULL; | ||
292 | |||
293 | old = s = *cp; | ||
294 | if (*s == '[') { | ||
295 | if ((s = strchr(s, ']')) == NULL) | ||
296 | return NULL; | ||
297 | else | ||
298 | s++; | ||
299 | } else if ((s = strpbrk(s, ":/")) == NULL) | ||
300 | s = *cp + strlen(*cp); /* skip to end (see first case below) */ | ||
301 | |||
302 | switch (*s) { | ||
303 | case '\0': | ||
304 | *cp = NULL; /* no more fields*/ | ||
305 | break; | ||
306 | |||
307 | case ':': | ||
308 | case '/': | ||
309 | *s = '\0'; /* terminate */ | ||
310 | *cp = s + 1; | ||
311 | break; | ||
312 | |||
313 | default: | ||
314 | return NULL; | ||
315 | } | ||
316 | |||
317 | return old; | ||
318 | } | ||
319 | |||
278 | char * | 320 | char * |
279 | cleanhostname(char *host) | 321 | cleanhostname(char *host) |
280 | { | 322 | { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.h,v 1.20 2004/12/11 01:48:56 dtucker Exp $ */ | 1 | /* $OpenBSD: misc.h,v 1.21 2005/03/01 10:09:52 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -20,6 +20,7 @@ int set_nonblock(int); | |||
20 | int unset_nonblock(int); | 20 | int unset_nonblock(int); |
21 | void set_nodelay(int); | 21 | void set_nodelay(int); |
22 | int a2port(const char *); | 22 | int a2port(const char *); |
23 | char *hpdelim(char **); | ||
23 | char *cleanhostname(char *); | 24 | char *cleanhostname(char *); |
24 | char *colon(char *); | 25 | char *colon(char *); |
25 | long convtime(const char *); | 26 | long convtime(const char *); |
diff --git a/readconf.c b/readconf.c index a4fe1fe02..c3dc71e66 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: readconf.c,v 1.134 2004/07/11 17:48:47 deraadt Exp $"); | 15 | RCSID("$OpenBSD: readconf.c,v 1.135 2005/03/01 10:09:52 djm Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "xmalloc.h" | 18 | #include "xmalloc.h" |
@@ -206,21 +206,23 @@ static struct { | |||
206 | */ | 206 | */ |
207 | 207 | ||
208 | void | 208 | void |
209 | add_local_forward(Options *options, u_short port, const char *host, | 209 | add_local_forward(Options *options, const Forward *newfwd) |
210 | u_short host_port) | ||
211 | { | 210 | { |
212 | Forward *fwd; | 211 | Forward *fwd; |
213 | #ifndef NO_IPPORT_RESERVED_CONCEPT | 212 | #ifndef NO_IPPORT_RESERVED_CONCEPT |
214 | extern uid_t original_real_uid; | 213 | extern uid_t original_real_uid; |
215 | if (port < IPPORT_RESERVED && original_real_uid != 0) | 214 | if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0) |
216 | fatal("Privileged ports can only be forwarded by root."); | 215 | fatal("Privileged ports can only be forwarded by root."); |
217 | #endif | 216 | #endif |
218 | if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) | 217 | if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) |
219 | fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); | 218 | fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); |
220 | fwd = &options->local_forwards[options->num_local_forwards++]; | 219 | fwd = &options->local_forwards[options->num_local_forwards++]; |
221 | fwd->port = port; | 220 | |
222 | fwd->host = xstrdup(host); | 221 | fwd->listen_host = (newfwd->listen_host == NULL) ? |
223 | fwd->host_port = host_port; | 222 | NULL : xstrdup(newfwd->listen_host); |
223 | fwd->listen_port = newfwd->listen_port; | ||
224 | fwd->connect_host = xstrdup(newfwd->connect_host); | ||
225 | fwd->connect_port = newfwd->connect_port; | ||
224 | } | 226 | } |
225 | 227 | ||
226 | /* | 228 | /* |
@@ -229,17 +231,19 @@ add_local_forward(Options *options, u_short port, const char *host, | |||
229 | */ | 231 | */ |
230 | 232 | ||
231 | void | 233 | void |
232 | add_remote_forward(Options *options, u_short port, const char *host, | 234 | add_remote_forward(Options *options, const Forward *newfwd) |
233 | u_short host_port) | ||
234 | { | 235 | { |
235 | Forward *fwd; | 236 | Forward *fwd; |
236 | if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) | 237 | if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) |
237 | fatal("Too many remote forwards (max %d).", | 238 | fatal("Too many remote forwards (max %d).", |
238 | SSH_MAX_FORWARDS_PER_DIRECTION); | 239 | SSH_MAX_FORWARDS_PER_DIRECTION); |
239 | fwd = &options->remote_forwards[options->num_remote_forwards++]; | 240 | fwd = &options->remote_forwards[options->num_remote_forwards++]; |
240 | fwd->port = port; | 241 | |
241 | fwd->host = xstrdup(host); | 242 | fwd->listen_host = (newfwd->listen_host == NULL) ? |
242 | fwd->host_port = host_port; | 243 | NULL : xstrdup(newfwd->listen_host); |
244 | fwd->listen_port = newfwd->listen_port; | ||
245 | fwd->connect_host = xstrdup(newfwd->connect_host); | ||
246 | fwd->connect_port = newfwd->connect_port; | ||
243 | } | 247 | } |
244 | 248 | ||
245 | static void | 249 | static void |
@@ -247,11 +251,15 @@ clear_forwardings(Options *options) | |||
247 | { | 251 | { |
248 | int i; | 252 | int i; |
249 | 253 | ||
250 | for (i = 0; i < options->num_local_forwards; i++) | 254 | for (i = 0; i < options->num_local_forwards; i++) { |
251 | xfree(options->local_forwards[i].host); | 255 | xfree(options->local_forwards[i].listen_host); |
256 | xfree(options->local_forwards[i].connect_host); | ||
257 | } | ||
252 | options->num_local_forwards = 0; | 258 | options->num_local_forwards = 0; |
253 | for (i = 0; i < options->num_remote_forwards; i++) | 259 | for (i = 0; i < options->num_remote_forwards; i++) { |
254 | xfree(options->remote_forwards[i].host); | 260 | xfree(options->remote_forwards[i].listen_host); |
261 | xfree(options->remote_forwards[i].connect_host); | ||
262 | } | ||
255 | options->num_remote_forwards = 0; | 263 | options->num_remote_forwards = 0; |
256 | } | 264 | } |
257 | 265 | ||
@@ -284,11 +292,10 @@ process_config_line(Options *options, const char *host, | |||
284 | char *line, const char *filename, int linenum, | 292 | char *line, const char *filename, int linenum, |
285 | int *activep) | 293 | int *activep) |
286 | { | 294 | { |
287 | char buf[256], *s, **charptr, *endofnumber, *keyword, *arg; | 295 | char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; |
288 | int opcode, *intptr, value; | 296 | int opcode, *intptr, value; |
289 | size_t len; | 297 | size_t len; |
290 | u_short fwd_port, fwd_host_port; | 298 | Forward fwd; |
291 | char sfwd_host_port[6]; | ||
292 | 299 | ||
293 | /* Strip trailing whitespace */ | 300 | /* Strip trailing whitespace */ |
294 | for(len = strlen(line) - 1; len > 0; len--) { | 301 | for(len = strlen(line) - 1; len > 0; len--) { |
@@ -645,30 +652,26 @@ parse_int: | |||
645 | case oLocalForward: | 652 | case oLocalForward: |
646 | case oRemoteForward: | 653 | case oRemoteForward: |
647 | arg = strdelim(&s); | 654 | arg = strdelim(&s); |
648 | if (!arg || *arg == '\0') | 655 | if (arg == NULL || *arg == '\0') |
649 | fatal("%.200s line %d: Missing port argument.", | 656 | fatal("%.200s line %d: Missing port argument.", |
650 | filename, linenum); | 657 | filename, linenum); |
651 | if ((fwd_port = a2port(arg)) == 0) | 658 | arg2 = strdelim(&s); |
652 | fatal("%.200s line %d: Bad listen port.", | 659 | if (arg2 == NULL || *arg2 == '\0') |
660 | fatal("%.200s line %d: Missing target argument.", | ||
653 | filename, linenum); | 661 | filename, linenum); |
654 | arg = strdelim(&s); | 662 | |
655 | if (!arg || *arg == '\0') | 663 | /* construct a string for parse_forward */ |
656 | fatal("%.200s line %d: Missing second argument.", | 664 | snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); |
657 | filename, linenum); | 665 | |
658 | if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && | 666 | if (parse_forward(&fwd, fwdarg) == 0) |
659 | sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2) | ||
660 | fatal("%.200s line %d: Bad forwarding specification.", | 667 | fatal("%.200s line %d: Bad forwarding specification.", |
661 | filename, linenum); | 668 | filename, linenum); |
662 | if ((fwd_host_port = a2port(sfwd_host_port)) == 0) | 669 | |
663 | fatal("%.200s line %d: Bad forwarding port.", | ||
664 | filename, linenum); | ||
665 | if (*activep) { | 670 | if (*activep) { |
666 | if (opcode == oLocalForward) | 671 | if (opcode == oLocalForward) |
667 | add_local_forward(options, fwd_port, buf, | 672 | add_local_forward(options, &fwd); |
668 | fwd_host_port); | ||
669 | else if (opcode == oRemoteForward) | 673 | else if (opcode == oRemoteForward) |
670 | add_remote_forward(options, fwd_port, buf, | 674 | add_remote_forward(options, &fwd); |
671 | fwd_host_port); | ||
672 | } | 675 | } |
673 | break; | 676 | break; |
674 | 677 | ||
@@ -677,12 +680,25 @@ parse_int: | |||
677 | if (!arg || *arg == '\0') | 680 | if (!arg || *arg == '\0') |
678 | fatal("%.200s line %d: Missing port argument.", | 681 | fatal("%.200s line %d: Missing port argument.", |
679 | filename, linenum); | 682 | filename, linenum); |
680 | fwd_port = a2port(arg); | 683 | memset(&fwd, '\0', sizeof(fwd)); |
681 | if (fwd_port == 0) | 684 | fwd.connect_host = "socks"; |
685 | fwd.listen_host = hpdelim(&arg); | ||
686 | if (fwd.listen_host == NULL || | ||
687 | strlen(fwd.listen_host) >= NI_MAXHOST) | ||
688 | fatal("%.200s line %d: Bad forwarding specification.", | ||
689 | filename, linenum); | ||
690 | if (arg) { | ||
691 | fwd.listen_port = a2port(arg); | ||
692 | fwd.listen_host = cleanhostname(fwd.listen_host); | ||
693 | } else { | ||
694 | fwd.listen_port = a2port(fwd.listen_host); | ||
695 | fwd.listen_host = ""; | ||
696 | } | ||
697 | if (fwd.listen_port == 0) | ||
682 | fatal("%.200s line %d: Badly formatted port number.", | 698 | fatal("%.200s line %d: Badly formatted port number.", |
683 | filename, linenum); | 699 | filename, linenum); |
684 | if (*activep) | 700 | if (*activep) |
685 | add_local_forward(options, fwd_port, "socks", 0); | 701 | add_local_forward(options, &fwd); |
686 | break; | 702 | break; |
687 | 703 | ||
688 | case oClearAllForwardings: | 704 | case oClearAllForwardings: |
@@ -1045,3 +1061,68 @@ fill_default_options(Options * options) | |||
1045 | /* options->host_key_alias should not be set by default */ | 1061 | /* options->host_key_alias should not be set by default */ |
1046 | /* options->preferred_authentications will be set in ssh */ | 1062 | /* options->preferred_authentications will be set in ssh */ |
1047 | } | 1063 | } |
1064 | |||
1065 | /* | ||
1066 | * parse_forward | ||
1067 | * parses a string containing a port forwarding specification of the form: | ||
1068 | * [listenhost:]listenport:connecthost:connectport | ||
1069 | * returns number of arguments parsed or zero on error | ||
1070 | */ | ||
1071 | int | ||
1072 | parse_forward(Forward *fwd, const char *fwdspec) | ||
1073 | { | ||
1074 | int i; | ||
1075 | char *p, *cp, *fwdarg[4]; | ||
1076 | |||
1077 | memset(fwd, '\0', sizeof(*fwd)); | ||
1078 | |||
1079 | cp = p = xstrdup(fwdspec); | ||
1080 | |||
1081 | /* skip leading spaces */ | ||
1082 | while (*cp && isspace(*cp)) | ||
1083 | cp++; | ||
1084 | |||
1085 | for (i = 0; i < 4; ++i) | ||
1086 | if ((fwdarg[i] = hpdelim(&cp)) == NULL) | ||
1087 | break; | ||
1088 | |||
1089 | /* Check for trailing garbage in 4-arg case*/ | ||
1090 | if (cp != NULL) | ||
1091 | i = 0; /* failure */ | ||
1092 | |||
1093 | switch (i) { | ||
1094 | case 3: | ||
1095 | fwd->listen_host = NULL; | ||
1096 | fwd->listen_port = a2port(fwdarg[0]); | ||
1097 | fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); | ||
1098 | fwd->connect_port = a2port(fwdarg[2]); | ||
1099 | break; | ||
1100 | |||
1101 | case 4: | ||
1102 | fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); | ||
1103 | fwd->listen_port = a2port(fwdarg[1]); | ||
1104 | fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); | ||
1105 | fwd->connect_port = a2port(fwdarg[3]); | ||
1106 | break; | ||
1107 | default: | ||
1108 | i = 0; /* failure */ | ||
1109 | } | ||
1110 | |||
1111 | xfree(p); | ||
1112 | |||
1113 | if (fwd->listen_port == 0 && fwd->connect_port == 0) | ||
1114 | goto fail_free; | ||
1115 | |||
1116 | if (fwd->connect_host != NULL && | ||
1117 | strlen(fwd->connect_host) >= NI_MAXHOST) | ||
1118 | goto fail_free; | ||
1119 | |||
1120 | return (i); | ||
1121 | |||
1122 | fail_free: | ||
1123 | if (fwd->connect_host != NULL) | ||
1124 | xfree(fwd->connect_host); | ||
1125 | if (fwd->listen_host != NULL) | ||
1126 | xfree(fwd->listen_host); | ||
1127 | return (0); | ||
1128 | } | ||
diff --git a/readconf.h b/readconf.h index ded422585..03b772a2d 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.64 2004/07/11 17:48:47 deraadt Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.65 2005/03/01 10:09:52 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -21,9 +21,10 @@ | |||
21 | /* Data structure for representing a forwarding request. */ | 21 | /* Data structure for representing a forwarding request. */ |
22 | 22 | ||
23 | typedef struct { | 23 | typedef struct { |
24 | u_short port; /* Port to forward. */ | 24 | char *listen_host; /* Host (address) to listen on. */ |
25 | char *host; /* Host to connect. */ | 25 | u_short listen_port; /* Port to forward. */ |
26 | u_short host_port; /* Port to connect on host. */ | 26 | char *connect_host; /* Host to connect. */ |
27 | u_short connect_port; /* Port to connect on connect_host. */ | ||
27 | } Forward; | 28 | } Forward; |
28 | /* Data structure for representing option data. */ | 29 | /* Data structure for representing option data. */ |
29 | 30 | ||
@@ -117,11 +118,12 @@ typedef struct { | |||
117 | void initialize_options(Options *); | 118 | void initialize_options(Options *); |
118 | void fill_default_options(Options *); | 119 | void fill_default_options(Options *); |
119 | int read_config_file(const char *, const char *, Options *, int); | 120 | int read_config_file(const char *, const char *, Options *, int); |
121 | int parse_forward(Forward *, const char *); | ||
120 | 122 | ||
121 | int | 123 | int |
122 | process_config_line(Options *, const char *, char *, const char *, int, int *); | 124 | process_config_line(Options *, const char *, char *, const char *, int, int *); |
123 | 125 | ||
124 | void add_local_forward(Options *, u_short, const char *, u_short); | 126 | void add_local_forward(Options *, const Forward *); |
125 | void add_remote_forward(Options *, u_short, const char *, u_short); | 127 | void add_remote_forward(Options *, const Forward *); |
126 | 128 | ||
127 | #endif /* READCONF_H */ | 129 | #endif /* READCONF_H */ |
diff --git a/servconf.c b/servconf.c index 541a9c85b..2d1a0c362 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include "includes.h" | 12 | #include "includes.h" |
13 | RCSID("$OpenBSD: servconf.c,v 1.138 2004/12/23 23:11:00 djm Exp $"); | 13 | RCSID("$OpenBSD: servconf.c,v 1.139 2005/03/01 10:09:52 djm Exp $"); |
14 | 14 | ||
15 | #include "ssh.h" | 15 | #include "ssh.h" |
16 | #include "log.h" | 16 | #include "log.h" |
@@ -440,6 +440,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
440 | char *cp, **charptr, *arg, *p; | 440 | char *cp, **charptr, *arg, *p; |
441 | int *intptr, value, i, n; | 441 | int *intptr, value, i, n; |
442 | ServerOpCodes opcode; | 442 | ServerOpCodes opcode; |
443 | u_short port; | ||
443 | 444 | ||
444 | cp = line; | 445 | cp = line; |
445 | arg = strdelim(&cp); | 446 | arg = strdelim(&cp); |
@@ -512,39 +513,21 @@ parse_time: | |||
512 | 513 | ||
513 | case sListenAddress: | 514 | case sListenAddress: |
514 | arg = strdelim(&cp); | 515 | arg = strdelim(&cp); |
515 | if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) | 516 | if (arg == NULL || *arg == '\0') |
516 | fatal("%s line %d: missing inet addr.", | 517 | fatal("%s line %d: missing address", |
517 | filename, linenum); | 518 | filename, linenum); |
518 | if (*arg == '[') { | 519 | p = hpdelim(&arg); |
519 | if ((p = strchr(arg, ']')) == NULL) | 520 | if (p == NULL) |
520 | fatal("%s line %d: bad ipv6 inet addr usage.", | 521 | fatal("%s line %d: bad address:port usage", |
521 | filename, linenum); | ||
522 | arg++; | ||
523 | memmove(p, p+1, strlen(p+1)+1); | ||
524 | } else if (((p = strchr(arg, ':')) == NULL) || | ||
525 | (strchr(p+1, ':') != NULL)) { | ||
526 | add_listen_addr(options, arg, 0); | ||
527 | break; | ||
528 | } | ||
529 | if (*p == ':') { | ||
530 | u_short port; | ||
531 | |||
532 | p++; | ||
533 | if (*p == '\0') | ||
534 | fatal("%s line %d: bad inet addr:port usage.", | ||
535 | filename, linenum); | ||
536 | else { | ||
537 | *(p-1) = '\0'; | ||
538 | if ((port = a2port(p)) == 0) | ||
539 | fatal("%s line %d: bad port number.", | ||
540 | filename, linenum); | ||
541 | add_listen_addr(options, arg, port); | ||
542 | } | ||
543 | } else if (*p == '\0') | ||
544 | add_listen_addr(options, arg, 0); | ||
545 | else | ||
546 | fatal("%s line %d: bad inet addr usage.", | ||
547 | filename, linenum); | 522 | filename, linenum); |
523 | p = cleanhostname(p); | ||
524 | if (arg == NULL) | ||
525 | port = 0; | ||
526 | else if ((port = a2port(arg)) == 0) | ||
527 | fatal("%s line %d: bad port number", filename, linenum); | ||
528 | |||
529 | add_listen_addr(options, p, port); | ||
530 | |||
548 | break; | 531 | break; |
549 | 532 | ||
550 | case sAddressFamily: | 533 | case sAddressFamily: |
@@ -742,7 +725,23 @@ parse_flag: | |||
742 | 725 | ||
743 | case sGatewayPorts: | 726 | case sGatewayPorts: |
744 | intptr = &options->gateway_ports; | 727 | intptr = &options->gateway_ports; |
745 | goto parse_flag; | 728 | arg = strdelim(&cp); |
729 | if (!arg || *arg == '\0') | ||
730 | fatal("%s line %d: missing yes/no/clientspecified " | ||
731 | "argument.", filename, linenum); | ||
732 | value = 0; /* silence compiler */ | ||
733 | if (strcmp(arg, "clientspecified") == 0) | ||
734 | value = 2; | ||
735 | else if (strcmp(arg, "yes") == 0) | ||
736 | value = 1; | ||
737 | else if (strcmp(arg, "no") == 0) | ||
738 | value = 0; | ||
739 | else | ||
740 | fatal("%s line %d: Bad yes/no/clientspecified " | ||
741 | "argument: %s", filename, linenum, arg); | ||
742 | if (*intptr == -1) | ||
743 | *intptr = value; | ||
744 | break; | ||
746 | 745 | ||
747 | case sUseDNS: | 746 | case sUseDNS: |
748 | intptr = &options->use_dns; | 747 | intptr = &options->use_dns; |
@@ -34,7 +34,7 @@ | |||
34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | .\" | 36 | .\" |
37 | .\" $OpenBSD: ssh.1,v 1.199 2004/11/07 17:42:36 jmc Exp $ | 37 | .\" $OpenBSD: ssh.1,v 1.200 2005/03/01 10:09:52 djm Exp $ |
38 | .Dd September 25, 1999 | 38 | .Dd September 25, 1999 |
39 | .Dt SSH 1 | 39 | .Dt SSH 1 |
40 | .Os | 40 | .Os |
@@ -53,13 +53,13 @@ | |||
53 | .Op Fl i Ar identity_file | 53 | .Op Fl i Ar identity_file |
54 | .Oo Fl L Xo | 54 | .Oo Fl L Xo |
55 | .Sm off | 55 | .Sm off |
56 | .Oo Ar bind_address : Oc | ||
56 | .Ar port : | 57 | .Ar port : |
57 | .Ar host : | 58 | .Ar host : |
58 | .Ar hostport | 59 | .Ar hostport |
59 | .Sm on | 60 | .Sm on |
60 | .Xc | 61 | .Xc |
61 | .Oc | 62 | .Oc |
62 | .Ek | ||
63 | .Op Fl l Ar login_name | 63 | .Op Fl l Ar login_name |
64 | .Op Fl m Ar mac_spec | 64 | .Op Fl m Ar mac_spec |
65 | .Op Fl O Ar ctl_cmd | 65 | .Op Fl O Ar ctl_cmd |
@@ -69,6 +69,7 @@ | |||
69 | .Ek | 69 | .Ek |
70 | .Oo Fl R Xo | 70 | .Oo Fl R Xo |
71 | .Sm off | 71 | .Sm off |
72 | .Oo Ar bind_address : Oc | ||
72 | .Ar port : | 73 | .Ar port : |
73 | .Ar host : | 74 | .Ar host : |
74 | .Ar hostport | 75 | .Ar hostport |
@@ -570,6 +571,7 @@ configuration files). | |||
570 | Disables forwarding (delegation) of GSSAPI credentials to the server. | 571 | Disables forwarding (delegation) of GSSAPI credentials to the server. |
571 | .It Fl L Xo | 572 | .It Fl L Xo |
572 | .Sm off | 573 | .Sm off |
574 | .Oo Ar bind_address : Oc | ||
573 | .Ar port : host : hostport | 575 | .Ar port : host : hostport |
574 | .Sm on | 576 | .Sm on |
575 | .Xc | 577 | .Xc |
@@ -577,7 +579,9 @@ Specifies that the given port on the local (client) host is to be | |||
577 | forwarded to the given host and port on the remote side. | 579 | forwarded to the given host and port on the remote side. |
578 | This works by allocating a socket to listen to | 580 | This works by allocating a socket to listen to |
579 | .Ar port | 581 | .Ar port |
580 | on the local side, and whenever a connection is made to this port, the | 582 | on the local side, optionally bound to the specified |
583 | .Ar bind_address . | ||
584 | Whenever a connection is made to this port, the | ||
581 | connection is forwarded over the secure channel, and a connection is | 585 | connection is forwarded over the secure channel, and a connection is |
582 | made to | 586 | made to |
583 | .Ar host | 587 | .Ar host |
@@ -585,14 +589,30 @@ port | |||
585 | .Ar hostport | 589 | .Ar hostport |
586 | from the remote machine. | 590 | from the remote machine. |
587 | Port forwardings can also be specified in the configuration file. | 591 | Port forwardings can also be specified in the configuration file. |
588 | Only root can forward privileged ports. | ||
589 | IPv6 addresses can be specified with an alternative syntax: | 592 | IPv6 addresses can be specified with an alternative syntax: |
590 | .Sm off | 593 | .Sm off |
591 | .Xo | 594 | .Xo |
595 | .Oo Ar bind_address / Oc | ||
592 | .Ar port No / Ar host No / | 596 | .Ar port No / Ar host No / |
593 | .Ar hostport . | 597 | .Ar hostport |
594 | .Xc | 598 | .Xc |
595 | .Sm on | 599 | .Sm on |
600 | or by enclosing the address in square brackets. | ||
601 | Only the superuser can forward privileged ports. | ||
602 | By default, the local port is bound in accordance with the | ||
603 | .Cm GatewayPorts | ||
604 | setting. | ||
605 | However, an explicit | ||
606 | .Ar bind_address | ||
607 | may be used to bind the connection to a specific address. | ||
608 | The | ||
609 | .Ar bind_address | ||
610 | of | ||
611 | .Dq localhost | ||
612 | indicates that the listening port be bound for local use only, while an | ||
613 | empty address or | ||
614 | .Dq * | ||
615 | indicates that the port should be available from all interfaces. | ||
596 | .It Fl l Ar login_name | 616 | .It Fl l Ar login_name |
597 | Specifies the user to log in as on the remote machine. | 617 | Specifies the user to log in as on the remote machine. |
598 | This also may be specified on a per-host basis in the configuration file. | 618 | This also may be specified on a per-host basis in the configuration file. |
@@ -724,6 +744,7 @@ Quiet mode. | |||
724 | Causes all warning and diagnostic messages to be suppressed. | 744 | Causes all warning and diagnostic messages to be suppressed. |
725 | .It Fl R Xo | 745 | .It Fl R Xo |
726 | .Sm off | 746 | .Sm off |
747 | .Oo Ar bind_address : Oc | ||
727 | .Ar port : host : hostport | 748 | .Ar port : host : hostport |
728 | .Sm on | 749 | .Sm on |
729 | .Xc | 750 | .Xc |
@@ -738,16 +759,34 @@ made to | |||
738 | port | 759 | port |
739 | .Ar hostport | 760 | .Ar hostport |
740 | from the local machine. | 761 | from the local machine. |
762 | .Pp | ||
741 | Port forwardings can also be specified in the configuration file. | 763 | Port forwardings can also be specified in the configuration file. |
742 | Privileged ports can be forwarded only when | 764 | Privileged ports can be forwarded only when |
743 | logging in as root on the remote machine. | 765 | logging in as root on the remote machine. |
744 | IPv6 addresses can be specified with an alternative syntax: | 766 | IPv6 addresses can be specified by enclosing the address in square braces or |
745 | .Sm off | 767 | using an alternative syntax: |
746 | .Xo | 768 | .Xo |
747 | .Ar port No / Ar host No / | 769 | .Sm off |
748 | .Ar hostport . | 770 | .Oo Ar bind_address / Oc |
749 | .Xc | 771 | .Ar host/port/hostport |
750 | .Sm on | 772 | .Sm on |
773 | .Xc . | ||
774 | .Pp | ||
775 | By default, the listening socket on the server will be bound to the loopback | ||
776 | interface only. | ||
777 | This may be overriden by specifying a | ||
778 | .Ar bind_address . | ||
779 | An empty | ||
780 | .Ar bind_address , | ||
781 | or the address | ||
782 | .Ql * | ||
783 | indicates that the remote socket should listen on all interfaces. | ||
784 | Specifying a remote | ||
785 | .Ar bind_address | ||
786 | will only succeed if the server's | ||
787 | .Cm GatewayPorts | ||
788 | option is enabled (see | ||
789 | .Xr sshd_config 5 ). | ||
751 | .It Fl S Ar ctl_path | 790 | .It Fl S Ar ctl_path |
752 | Specifies the location of a control socket for connection sharing. | 791 | Specifies the location of a control socket for connection sharing. |
753 | Refer to the description of | 792 | Refer to the description of |
@@ -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 |
diff --git a/ssh_config.5 b/ssh_config.5 index 8f6d851b4..6b6cfc5e9 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -34,7 +34,7 @@ | |||
34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | .\" | 36 | .\" |
37 | .\" $OpenBSD: ssh_config.5,v 1.42 2005/02/28 00:54:10 djm Exp $ | 37 | .\" $OpenBSD: ssh_config.5,v 1.43 2005/03/01 10:09:52 djm Exp $ |
38 | .Dd September 25, 1999 | 38 | .Dd September 25, 1999 |
39 | .Dt SSH_CONFIG 5 | 39 | .Dt SSH_CONFIG 5 |
40 | .Os | 40 | .Os |
@@ -480,12 +480,37 @@ The default is to use the server specified list. | |||
480 | Specifies that a TCP/IP port on the local machine be forwarded over | 480 | Specifies that a TCP/IP port on the local machine be forwarded over |
481 | the secure channel to the specified host and port from the remote machine. | 481 | the secure channel to the specified host and port from the remote machine. |
482 | The first argument must be a port number, and the second must be | 482 | The first argument must be a port number, and the second must be |
483 | .Ar host:port . | 483 | .Xo |
484 | IPv6 addresses can be specified with an alternative syntax: | 484 | .Sm off |
485 | .Ar host/port . | 485 | .Oo Ar bind_address : Oc |
486 | Multiple forwardings may be specified, and additional | 486 | .Ar host:port |
487 | forwardings can be given on the command line. | 487 | .Sm on |
488 | .Xc . | ||
489 | IPv6 addresses can be specified by enclosing addresses in square brackets or | ||
490 | by using an alternative syntax: | ||
491 | .Xo | ||
492 | .Sm off | ||
493 | .Oo Ar bind_address / Oc | ||
494 | .Ar host/port | ||
495 | .Sm on | ||
496 | .Xc . | ||
497 | Multiple forwardings may be specified, and additional forwardings can be | ||
498 | given on the command line. | ||
488 | Only the superuser can forward privileged ports. | 499 | Only the superuser can forward privileged ports. |
500 | By default, the local port is bound in accordance with the | ||
501 | .Cm GatewayPorts | ||
502 | setting. | ||
503 | However, an explicit | ||
504 | .Ar bind_address | ||
505 | may be used to bind the connection to a specific address. | ||
506 | The | ||
507 | .Ar bind_address | ||
508 | of | ||
509 | .Dq localhost | ||
510 | indicates that the listening port be bound for local use only, while an | ||
511 | empty address or | ||
512 | .Dq * | ||
513 | indicates that the port should be available from all interfaces. | ||
489 | .It Cm LogLevel | 514 | .It Cm LogLevel |
490 | Gives the verbosity level that is used when logging messages from | 515 | Gives the verbosity level that is used when logging messages from |
491 | .Nm ssh . | 516 | .Nm ssh . |
@@ -592,12 +617,39 @@ This option applies to protocol version 2 only. | |||
592 | Specifies that a TCP/IP port on the remote machine be forwarded over | 617 | Specifies that a TCP/IP port on the remote machine be forwarded over |
593 | the secure channel to the specified host and port from the local machine. | 618 | the secure channel to the specified host and port from the local machine. |
594 | The first argument must be a port number, and the second must be | 619 | The first argument must be a port number, and the second must be |
595 | .Ar host:port . | 620 | .Xo |
596 | IPv6 addresses can be specified with an alternative syntax: | 621 | .Sm off |
597 | .Ar host/port . | 622 | .Oo Ar bind_address : Oc |
623 | .Ar host:port | ||
624 | .Sm on | ||
625 | .Xc . | ||
626 | IPv6 addresses can be specified by enclosing any addresses in square brackets | ||
627 | or by using the alternative syntax: | ||
628 | .Xo | ||
629 | .Sm off | ||
630 | .Oo Ar bind_address / Oc | ||
631 | .Ar host/port | ||
632 | .Sm on | ||
633 | .Xc . | ||
598 | Multiple forwardings may be specified, and additional | 634 | Multiple forwardings may be specified, and additional |
599 | forwardings can be given on the command line. | 635 | forwardings can be given on the command line. |
600 | Only the superuser can forward privileged ports. | 636 | Only the superuser can forward privileged ports. |
637 | .Pp | ||
638 | If the | ||
639 | .Ar bind_address | ||
640 | is not specified, the default is to only bind to loopback addresses. | ||
641 | If the | ||
642 | .Ar bind_address | ||
643 | is | ||
644 | .Ql * | ||
645 | or an empty string, then the forwarding is requested to listen on all | ||
646 | interfaces. | ||
647 | Specifying a remote | ||
648 | .Ar bind_address | ||
649 | will only succeed if the server's | ||
650 | .Cm GatewayPorts | ||
651 | option is enabled (see | ||
652 | .Xr sshd_config 5 ). | ||
601 | .It Cm RhostsRSAAuthentication | 653 | .It Cm RhostsRSAAuthentication |
602 | Specifies whether to try rhosts based authentication with RSA host | 654 | Specifies whether to try rhosts based authentication with RSA host |
603 | authentication. | 655 | authentication. |
diff --git a/sshd_config.5 b/sshd_config.5 index da6d97c68..8d291e61d 100644 --- a/sshd_config.5 +++ b/sshd_config.5 | |||
@@ -34,7 +34,7 @@ | |||
34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | .\" | 36 | .\" |
37 | .\" $OpenBSD: sshd_config.5,v 1.38 2005/01/08 00:41:19 jmc Exp $ | 37 | .\" $OpenBSD: sshd_config.5,v 1.39 2005/03/01 10:09:52 djm Exp $ |
38 | .Dd September 25, 1999 | 38 | .Dd September 25, 1999 |
39 | .Dt SSHD_CONFIG 5 | 39 | .Dt SSHD_CONFIG 5 |
40 | .Os | 40 | .Os |
@@ -256,12 +256,15 @@ This prevents other remote hosts from connecting to forwarded ports. | |||
256 | .Cm GatewayPorts | 256 | .Cm GatewayPorts |
257 | can be used to specify that | 257 | can be used to specify that |
258 | .Nm sshd | 258 | .Nm sshd |
259 | should bind remote port forwardings to the wildcard address, | 259 | should allow remote port forwardings to bind to non-loopback addresses, thus |
260 | thus allowing remote hosts to connect to forwarded ports. | 260 | allowing other hosts to connect. |
261 | The argument must be | 261 | The argument may be |
262 | .Dq no | ||
263 | to force remote port forwardings to be available to the local host only, | ||
262 | .Dq yes | 264 | .Dq yes |
263 | or | 265 | to force remote port forwardings to bind to the wildcard address, or |
264 | .Dq no . | 266 | .Dq clientspecified |
267 | to allow the client to select the address to which the forwarding is bound. | ||
265 | The default is | 268 | The default is |
266 | .Dq no . | 269 | .Dq no . |
267 | .It Cm GSSAPIAuthentication | 270 | .It Cm GSSAPIAuthentication |