View | Details | Raw Unified | Return to bug 413 | Differences between
and this patch

Collapse All | Expand All

(-)auth-options.c (-11 / +15 lines)
Lines 217-223 auth_parse_options(struct passwd *pw, ch Link Here
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
Lines 236-260 auth_parse_options(struct passwd *pw, ch Link Here
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);
(-)channels.c (-14 / +60 lines)
Lines 2173-2184 channel_setup_fwd_listener(int type, con Link Here
2173
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2173
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2174
{
2174
{
2175
	Channel *c;
2175
	Channel *c;
2176
	int success, sock, on = 1;
2176
	int sock, r, success = 0, on = 1, wildcard = 0;
2177
	struct addrinfo hints, *ai, *aitop;
2177
	struct addrinfo hints, *ai, *aitop;
2178
	const char *host;
2178
	const char *host, *addr;
2179
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2179
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2180
2180
2181
	success = 0;
2182
	host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
2181
	host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
2183
	    listen_addr : host_to_connect;
2182
	    listen_addr : host_to_connect;
2184
2183
Lines 2192-2207 channel_setup_fwd_listener(int type, con Link Here
2192
	}
2191
	}
2193
2192
2194
	/*
2193
	/*
2194
	 * Determine whether or not a port forward listens to loopback,
2195
	 * specified address or wildcard. These cases are only considered
2196
	 * if gateway_ports is activated.
2197
	 *
2198
	 * Special-case listen_addrs are:
2199
	 *
2200
	 * "0.0.0.0"               -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
2201
	 * "" (empty string), "*"  -> wildcard v4/v6
2202
	 * "localhost"             -> loopback v4/v6
2203
	 */
2204
	addr = NULL;
2205
	if (listen_addr == NULL) {
2206
		/* No address specified: default to gateway_ports setting */
2207
		if (gateway_ports)
2208
			wildcard = 1;
2209
	} else if (gateway_ports || type == SSH_CHANNEL_PORT_LISTENER) {
2210
		if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
2211
		    strcmp(listen_addr, "0.0.0.0") == 0) ||
2212
		    *listen_addr == '\0' || strcmp(listen_addr, "*") == 0)
2213
			wildcard = 1;
2214
		else if (strcmp(listen_addr, "localhost") != 0)
2215
			addr = listen_addr;
2216
	}
2217
2218
	debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s",
2219
	    type, wildcard, (addr == NULL) ? "NULL" : addr);
2220
2221
	/*
2195
	 * getaddrinfo returns a loopback address if the hostname is
2222
	 * getaddrinfo returns a loopback address if the hostname is
2196
	 * set to NULL and hints.ai_flags is not AI_PASSIVE
2223
	 * set to NULL and hints.ai_flags is not AI_PASSIVE
2197
	 */
2224
	 */
2198
	memset(&hints, 0, sizeof(hints));
2225
	memset(&hints, 0, sizeof(hints));
2199
	hints.ai_family = IPv4or6;
2226
	hints.ai_family = IPv4or6;
2200
	hints.ai_flags = gateway_ports ? AI_PASSIVE : 0;
2227
	hints.ai_flags = wildcard ? AI_PASSIVE : 0;
2201
	hints.ai_socktype = SOCK_STREAM;
2228
	hints.ai_socktype = SOCK_STREAM;
2202
	snprintf(strport, sizeof strport, "%d", listen_port);
2229
	snprintf(strport, sizeof strport, "%d", listen_port);
2203
	if (getaddrinfo(NULL, strport, &hints, &aitop) != 0)
2230
	if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
2204
		packet_disconnect("getaddrinfo: fatal error");
2231
		if (addr == NULL) {
2232
			/* This really shouldn't happen */
2233
			packet_disconnect("getaddrinfo: fatal error: %s",
2234
			    gai_strerror(r));
2235
		} else {
2236
			verbose("channel_setup_fwd_listener: "
2237
			    "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
2238
			packet_send_debug("channel_setup_fwd_listener: "
2239
			    "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
2240
		}
2241
		aitop = NULL;
2242
	}
2205
2243
2206
	for (ai = aitop; ai; ai = ai->ai_next) {
2244
	for (ai = aitop; ai; ai = ai->ai_next) {
2207
		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
2245
		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
Lines 2280-2290 channel_cancel_rport_listener(const char Link Here
2280
2318
2281
/* protocol local port fwd, used by ssh (and sshd in v1) */
2319
/* protocol local port fwd, used by ssh (and sshd in v1) */
2282
int
2320
int
2283
channel_setup_local_fwd_listener(u_short listen_port,
2321
channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
2284
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2322
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2285
{
2323
{
2286
	return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
2324
	return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
2287
	    NULL, listen_port, host_to_connect, port_to_connect, gateway_ports);
2325
	    listen_host, listen_port, host_to_connect, port_to_connect,
2326
	    gateway_ports);
2288
}
2327
}
2289
2328
2290
/* protocol v2 remote port fwd, used by sshd */
2329
/* protocol v2 remote port fwd, used by sshd */
Lines 2302-2308 channel_setup_remote_fwd_listener(const Link Here
2302
 */
2341
 */
2303
2342
2304
void
2343
void
2305
channel_request_remote_forwarding(u_short listen_port,
2344
channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
2306
    const char *host_to_connect, u_short port_to_connect)
2345
    const char *host_to_connect, u_short port_to_connect)
2307
{
2346
{
2308
	int type, success = 0;
2347
	int type, success = 0;
Lines 2313-2319 channel_request_remote_forwarding(u_shor Link Here
2313
2352
2314
	/* Send the forward request to the remote side. */
2353
	/* Send the forward request to the remote side. */
2315
	if (compat20) {
2354
	if (compat20) {
2316
		const char *address_to_bind = "0.0.0.0";
2355
		const char *address_to_bind;
2356
		if (listen_host == NULL)
2357
			address_to_bind = "localhost";
2358
		else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0)
2359
			address_to_bind = "";
2360
		else
2361
			address_to_bind = listen_host;
2362
2317
		packet_start(SSH2_MSG_GLOBAL_REQUEST);
2363
		packet_start(SSH2_MSG_GLOBAL_REQUEST);
2318
		packet_put_cstring("tcpip-forward");
2364
		packet_put_cstring("tcpip-forward");
2319
		packet_put_char(1);			/* boolean: want reply */
2365
		packet_put_char(1);			/* boolean: want reply */
Lines 2359-2368 channel_request_remote_forwarding(u_shor Link Here
2359
 * local side.
2405
 * local side.
2360
 */
2406
 */
2361
void
2407
void
2362
channel_request_rforward_cancel(u_short port)
2408
channel_request_rforward_cancel(const char *host, u_short port)
2363
{
2409
{
2364
	int i;
2410
	int i;
2365
	const char *address_to_bind = "0.0.0.0";
2366
2411
2367
	if (!compat20)
2412
	if (!compat20)
2368
		return;
2413
		return;
Lines 2379-2385 channel_request_rforward_cancel(u_short Link Here
2379
	packet_start(SSH2_MSG_GLOBAL_REQUEST);
2424
	packet_start(SSH2_MSG_GLOBAL_REQUEST);
2380
	packet_put_cstring("cancel-tcpip-forward");
2425
	packet_put_cstring("cancel-tcpip-forward");
2381
	packet_put_char(0);
2426
	packet_put_char(0);
2382
	packet_put_cstring(address_to_bind);
2427
	packet_put_cstring(host == NULL ? "" : host);
2383
	packet_put_int(port);
2428
	packet_put_int(port);
2384
	packet_send();
2429
	packet_send();
2385
2430
Lines 2418-2424 channel_input_port_forward_request(int i Link Here
2418
		packet_disconnect("Dynamic forwarding denied.");
2463
		packet_disconnect("Dynamic forwarding denied.");
2419
2464
2420
	/* Initiate forwarding */
2465
	/* Initiate forwarding */
2421
	channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports);
2466
	channel_setup_local_fwd_listener(NULL, port, hostname,
2467
	    host_port, gateway_ports);
2422
2468
2423
	/* Free the argument string. */
2469
	/* Free the argument string. */
2424
	xfree(hostname);
2470
	xfree(hostname);
(-)channels.h (-3 / +5 lines)
Lines 202-210 void channel_clear_permitted_opens(void Link Here
202
void     channel_input_port_forward_request(int, int);
202
void     channel_input_port_forward_request(int, int);
203
int	 channel_connect_to(const char *, u_short);
203
int	 channel_connect_to(const char *, u_short);
204
int	 channel_connect_by_listen_address(u_short);
204
int	 channel_connect_by_listen_address(u_short);
205
void	 channel_request_remote_forwarding(u_short, const char *, u_short);
205
void	 channel_request_remote_forwarding(const char *, u_short,
206
void	 channel_request_rforward_cancel(u_short port);
206
	     const char *, u_short);
207
int	 channel_setup_local_fwd_listener(u_short, const char *, u_short, int);
207
int	 channel_setup_local_fwd_listener(const char *, u_short,
208
	     const char *, u_short, int);
209
void	 channel_request_rforward_cancel(const char *host, u_short port);
208
int	 channel_setup_remote_fwd_listener(const char *, u_short, int);
210
int	 channel_setup_remote_fwd_listener(const char *, u_short, int);
209
int	 channel_cancel_rport_listener(const char *, u_short);
211
int	 channel_cancel_rport_listener(const char *, u_short);
210
212
(-)clientloop.c (-23 / +24 lines)
Lines 763-773 static void Link Here
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);
Lines 813-849 process_cmdline(void) Link Here
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
(-)compat.c (-7 / +11 lines)
Lines 62-85 compat_datafellows(const char *version) Link Here
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 },
(-)compat.h (+1 lines)
Lines 55-60 Link Here
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);
(-)misc.c (+42 lines)
Lines 269-274 convtime(const char *s) Link Here
269
	return total;
269
	return total;
270
}
270
}
271
271
272
/*
273
 * Search for next delimiter between hostnames/addresses and ports.
274
 * Argument may be modified (for termination).
275
 * Returns *cp if parsing succeeds.
276
 * *cp is set to the start of the next delimiter, if one was found.
277
 * If this is the last field, *cp is set to NULL.
278
 */
279
char *
280
hpdelim(char **cp)
281
{
282
	char *s, *old;
283
284
	if (cp == NULL || *cp == NULL)
285
		return NULL;
286
287
	old = s = *cp;
288
	if (*s == '[') {
289
		if ((s = strchr(s, ']')) == NULL)
290
			return NULL;
291
		else
292
			s++;
293
	} else if ((s = strpbrk(s, ":/")) == NULL)
294
		s = *cp + strlen(*cp); /* skip to end (see first case below) */
295
296
	switch (*s) {
297
	case '\0':
298
		*cp = NULL;	/* no more fields*/
299
		break;
300
	
301
	case ':':
302
	case '/':
303
		*s = '\0';	/* terminate */
304
		*cp = s + 1;
305
		break;
306
	
307
	default:
308
		return NULL;
309
	}
310
311
	return old;
312
}
313
272
char *
314
char *
273
cleanhostname(char *host)
315
cleanhostname(char *host)
274
{
316
{
(-)misc.h (+1 lines)
Lines 20-25 int set_nonblock(int); Link Here
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 *);
(-)readconf.c (-37 / +118 lines)
Lines 206-224 static struct { Link Here
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
	extern uid_t original_real_uid;
212
	extern uid_t original_real_uid;
214
	if (port < IPPORT_RESERVED && original_real_uid != 0)
213
	if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
215
		fatal("Privileged ports can only be forwarded by root.");
214
		fatal("Privileged ports can only be forwarded by root.");
216
	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
215
	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
217
		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
216
		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
218
	fwd = &options->local_forwards[options->num_local_forwards++];
217
	fwd = &options->local_forwards[options->num_local_forwards++];
219
	fwd->port = port;
218
220
	fwd->host = xstrdup(host);
219
	fwd->listen_host = (newfwd->listen_host == NULL) ?
221
	fwd->host_port = host_port;
220
	    NULL : xstrdup(newfwd->listen_host);
221
	fwd->listen_port = newfwd->listen_port;
222
	fwd->connect_host = xstrdup(newfwd->connect_host);
223
	fwd->connect_port = newfwd->connect_port;
222
}
224
}
223
225
224
/*
226
/*
Lines 227-243 add_local_forward(Options *options, u_sh Link Here
227
 */
229
 */
228
230
229
void
231
void
230
add_remote_forward(Options *options, u_short port, const char *host,
232
add_remote_forward(Options *options, const Forward *newfwd)
231
		   u_short host_port)
232
{
233
{
233
	Forward *fwd;
234
	Forward *fwd;
234
	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
235
	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
235
		fatal("Too many remote forwards (max %d).",
236
		fatal("Too many remote forwards (max %d).",
236
		    SSH_MAX_FORWARDS_PER_DIRECTION);
237
		    SSH_MAX_FORWARDS_PER_DIRECTION);
237
	fwd = &options->remote_forwards[options->num_remote_forwards++];
238
	fwd = &options->remote_forwards[options->num_remote_forwards++];
238
	fwd->port = port;
239
239
	fwd->host = xstrdup(host);
240
	fwd->listen_host = (newfwd->listen_host == NULL) ?
240
	fwd->host_port = host_port;
241
	    NULL : xstrdup(newfwd->listen_host);
242
	fwd->listen_port = newfwd->listen_port;
243
	fwd->connect_host = xstrdup(newfwd->connect_host);
244
	fwd->connect_port = newfwd->connect_port;
241
}
245
}
242
246
243
static void
247
static void
Lines 245-255 clear_forwardings(Options *options) Link Here
245
{
249
{
246
	int i;
250
	int i;
247
251
248
	for (i = 0; i < options->num_local_forwards; i++)
252
	for (i = 0; i < options->num_local_forwards; i++) {
249
		xfree(options->local_forwards[i].host);
253
		xfree(options->local_forwards[i].listen_host);
254
		xfree(options->local_forwards[i].connect_host);
255
	}
250
	options->num_local_forwards = 0;
256
	options->num_local_forwards = 0;
251
	for (i = 0; i < options->num_remote_forwards; i++)
257
	for (i = 0; i < options->num_remote_forwards; i++) {
252
		xfree(options->remote_forwards[i].host);
258
		xfree(options->remote_forwards[i].listen_host);
259
		xfree(options->remote_forwards[i].connect_host);
260
	}
253
	options->num_remote_forwards = 0;
261
	options->num_remote_forwards = 0;
254
}
262
}
255
263
Lines 282-292 process_config_line(Options *options, co Link Here
282
		    char *line, const char *filename, int linenum,
290
		    char *line, const char *filename, int linenum,
283
		    int *activep)
291
		    int *activep)
284
{
292
{
285
	char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
293
	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
286
	int opcode, *intptr, value;
294
	int opcode, *intptr, value;
287
	size_t len;
295
	size_t len;
288
	u_short fwd_port, fwd_host_port;
296
	Forward fwd;
289
	char sfwd_host_port[6];
290
297
291
	/* Strip trailing whitespace */
298
	/* Strip trailing whitespace */
292
	for(len = strlen(line) - 1; len > 0; len--) {
299
	for(len = strlen(line) - 1; len > 0; len--) {
Lines 643-672 parse_int: Link Here
643
	case oLocalForward:
650
	case oLocalForward:
644
	case oRemoteForward:
651
	case oRemoteForward:
645
		arg = strdelim(&s);
652
		arg = strdelim(&s);
646
		if (!arg || *arg == '\0')
653
		if (arg == NULL || *arg == '\0')
647
			fatal("%.200s line %d: Missing port argument.",
654
			fatal("%.200s line %d: Missing port argument.",
648
			    filename, linenum);
655
			    filename, linenum);
649
		if ((fwd_port = a2port(arg)) == 0)
656
		arg2 = strdelim(&s);
650
			fatal("%.200s line %d: Bad listen port.",
657
		if (arg2 == NULL || *arg2 == '\0')
658
			fatal("%.200s line %d: Missing target argument.",
651
			    filename, linenum);
659
			    filename, linenum);
652
		arg = strdelim(&s);
660
653
		if (!arg || *arg == '\0')
661
		/* construct a string for parse_forward */
654
			fatal("%.200s line %d: Missing second argument.",
662
		snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
655
			    filename, linenum);
663
656
		if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
664
		if (parse_forward(&fwd, fwdarg) == 0)
657
		    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
658
			fatal("%.200s line %d: Bad forwarding specification.",
665
			fatal("%.200s line %d: Bad forwarding specification.",
659
			    filename, linenum);
666
			    filename, linenum);
660
		if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
667
661
			fatal("%.200s line %d: Bad forwarding port.",
662
			    filename, linenum);
663
		if (*activep) {
668
		if (*activep) {
664
			if (opcode == oLocalForward)
669
			if (opcode == oLocalForward)
665
				add_local_forward(options, fwd_port, buf,
670
				add_local_forward(options, &fwd);
666
				    fwd_host_port);
667
			else if (opcode == oRemoteForward)
671
			else if (opcode == oRemoteForward)
668
				add_remote_forward(options, fwd_port, buf,
672
				add_remote_forward(options, &fwd);
669
				    fwd_host_port);
670
		}
673
		}
671
		break;
674
		break;
672
675
Lines 675-686 parse_int: Link Here
675
		if (!arg || *arg == '\0')
678
		if (!arg || *arg == '\0')
676
			fatal("%.200s line %d: Missing port argument.",
679
			fatal("%.200s line %d: Missing port argument.",
677
			    filename, linenum);
680
			    filename, linenum);
678
		fwd_port = a2port(arg);
681
		memset(&fwd, '\0', sizeof(fwd));
679
		if (fwd_port == 0)
682
		fwd.connect_host = "socks";
683
		fwd.listen_host = hpdelim(&arg);
684
		if (fwd.listen_host == NULL ||
685
		    strlen(fwd.listen_host) >= NI_MAXHOST)
686
			fatal("%.200s line %d: Bad forwarding specification.",
687
			    filename, linenum);
688
		if (arg) {
689
			fwd.listen_port = a2port(arg);
690
			fwd.listen_host = cleanhostname(fwd.listen_host);
691
		} else {
692
			fwd.listen_port = a2port(fwd.listen_host);
693
			fwd.listen_host = "";
694
		}
695
		if (fwd.listen_port == 0)
680
			fatal("%.200s line %d: Badly formatted port number.",
696
			fatal("%.200s line %d: Badly formatted port number.",
681
			    filename, linenum);
697
			    filename, linenum);
682
		if (*activep)
698
		if (*activep)
683
			add_local_forward(options, fwd_port, "socks", 0);
699
			add_local_forward(options, &fwd);
684
		break;
700
		break;
685
701
686
	case oClearAllForwardings:
702
	case oClearAllForwardings:
Lines 1042-1045 fill_default_options(Options * options) Link Here
1042
	/* options->hostname will be set in the main program if appropriate */
1058
	/* options->hostname will be set in the main program if appropriate */
1043
	/* options->host_key_alias should not be set by default */
1059
	/* options->host_key_alias should not be set by default */
1044
	/* options->preferred_authentications will be set in ssh */
1060
	/* options->preferred_authentications will be set in ssh */
1061
}
1062
1063
/*
1064
 * parse_forward
1065
 * parses a string containing a port forwarding specification of the form:
1066
 *	[listenhost:]listenport:connecthost:connectport
1067
 * returns number of arguments parsed or zero on error
1068
 */
1069
int
1070
parse_forward(Forward *fwd, const char *fwdspec)
1071
{
1072
	int i;
1073
	char *p, *cp, *fwdarg[4];
1074
1075
	memset(fwd, '\0', sizeof(*fwd));
1076
1077
	cp = p = xstrdup(fwdspec);
1078
1079
	/* skip leading spaces */
1080
	while (*cp && isspace(*cp))
1081
		cp++;
1082
1083
	for (i = 0; i < 4; ++i)
1084
		if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1085
			break;
1086
1087
	/* Check for trailing garbage in 4-arg case*/
1088
	if (cp != NULL)
1089
		i = 0;	/* failure */
1090
1091
	switch (i) {
1092
	case 3:
1093
		fwd->listen_host = NULL;
1094
		fwd->listen_port = a2port(fwdarg[0]);
1095
		fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1096
		fwd->connect_port = a2port(fwdarg[2]);
1097
		break;
1098
1099
	case 4:
1100
		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1101
		fwd->listen_port = a2port(fwdarg[1]);
1102
		fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1103
		fwd->connect_port = a2port(fwdarg[3]);
1104
		break;
1105
	default:
1106
		i = 0; /* failure */
1107
	}
1108
1109
	xfree(p);
1110
1111
	if (fwd->listen_port == 0 && fwd->connect_port == 0)
1112
		goto fail_free;
1113
1114
	if (fwd->connect_host != NULL &&
1115
	    strlen(fwd->connect_host) >= NI_MAXHOST)
1116
		goto fail_free;
1117
1118
	return (i);
1119
1120
 fail_free:
1121
	if (fwd->connect_host != NULL)
1122
		xfree(fwd->connect_host);
1123
	if (fwd->listen_host != NULL)
1124
		xfree(fwd->listen_host);
1125
	return (0);
1045
}
1126
}
(-)readconf.h (-5 / +7 lines)
Lines 21-29 Link Here
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
Lines 117-127 typedef struct { Link Here
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 */
(-)servconf.c (-32 / +15 lines)
Lines 405-410 process_server_config_line(ServerOptions Link Here
405
	char *cp, **charptr, *arg, *p;
405
	char *cp, **charptr, *arg, *p;
406
	int *intptr, value, i, n;
406
	int *intptr, value, i, n;
407
	ServerOpCodes opcode;
407
	ServerOpCodes opcode;
408
	u_short port;
408
409
409
	cp = line;
410
	cp = line;
410
	arg = strdelim(&cp);
411
	arg = strdelim(&cp);
Lines 471-509 parse_time: Link Here
471
472
472
	case sListenAddress:
473
	case sListenAddress:
473
		arg = strdelim(&cp);
474
		arg = strdelim(&cp);
474
		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
475
		if (arg == NULL || *arg == '\0')
475
			fatal("%s line %d: missing inet addr.",
476
			fatal("%s line %d: missing address",
476
			    filename, linenum);
477
		if (*arg == '[') {
478
			if ((p = strchr(arg, ']')) == NULL)
479
				fatal("%s line %d: bad ipv6 inet addr usage.",
480
				    filename, linenum);
481
			arg++;
482
			memmove(p, p+1, strlen(p+1)+1);
483
		} else if (((p = strchr(arg, ':')) == NULL) ||
484
			    (strchr(p+1, ':') != NULL)) {
485
			add_listen_addr(options, arg, 0);
486
			break;
487
		}
488
		if (*p == ':') {
489
			u_short port;
490
491
			p++;
492
			if (*p == '\0')
493
				fatal("%s line %d: bad inet addr:port usage.",
494
				    filename, linenum);
495
			else {
496
				*(p-1) = '\0';
497
				if ((port = a2port(p)) == 0)
498
					fatal("%s line %d: bad port number.",
499
					    filename, linenum);
500
				add_listen_addr(options, arg, port);
501
			}
502
		} else if (*p == '\0')
503
			add_listen_addr(options, arg, 0);
504
		else
505
			fatal("%s line %d: bad inet addr usage.",
506
			    filename, linenum);
477
			    filename, linenum);
478
		p = hpdelim(&arg);
479
		if (p == NULL)
480
			fatal("%s line %d: bad address:port usage",
481
			    filename, linenum);
482
		p = cleanhostname(p);
483
		if (arg == NULL)
484
			port = 0;
485
		else if ((port = a2port(arg)) == 0)
486
			fatal("%s line %d: bad port number", filename, linenum);
487
488
		add_listen_addr(options, p, port);
489
507
		break;
490
		break;
508
491
509
	case sAddressFamily:
492
	case sAddressFamily:
(-)ssh.1 (-9 / +48 lines)
Lines 53-65 Link Here
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
Lines 69-74 Link Here
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
Lines 570-575 configuration files). Link Here
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
Lines 577-583 Specifies that the given port on the loc Link Here
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
Lines 585-598 port Link Here
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.
Lines 724-729 Quiet mode. Link Here
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
Lines 738-753 made to Link Here
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
(-)ssh.c (-44 / +64 lines)
Lines 158-166 usage(void) Link Here
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);
Lines 178-191 int Link Here
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
	/*
190
	/*
191
	 * Save the original real uid.  It will be needed later (uid-swapping
191
	 * Save the original real uid.  It will be needed later (uid-swapping
Lines 396-434 again: Link Here
396
			break;
396
			break;
397
397
398
		case 'L':
398
		case 'L':
399
		case 'R':
399
			if (parse_forward(&fwd, optarg))
400
			if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]",
400
				add_local_forward(&options, &fwd);
401
			    sfwd_port, buf, sfwd_host_port) != 3 &&
401
			else {
402
			    sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]",
403
			    sfwd_port, buf, sfwd_host_port) != 3) {
404
				fprintf(stderr,
402
				fprintf(stderr,
405
				    "Bad forwarding specification '%s'\n",
403
				    "Bad local forwarding specification '%s'\n",
406
				    optarg);
404
				    optarg);
407
				usage();
405
				exit(1);
408
				/* NOTREACHED */
409
			}
406
			}
410
			if ((fwd_port = a2port(sfwd_port)) == 0 ||
407
			break;
411
			    (fwd_host_port = a2port(sfwd_host_port)) == 0) {
408
409
		case 'R':
410
			if (parse_forward(&fwd, optarg)) {
411
				add_remote_forward(&options, &fwd);
412
			} else {
412
				fprintf(stderr,
413
				fprintf(stderr,
413
				    "Bad forwarding port(s) '%s'\n", optarg);
414
				    "Bad remote forwarding specification "
415
				    "'%s'\n", optarg);
414
				exit(1);
416
				exit(1);
415
			}
417
			}
416
			if (opt == 'L')
417
				add_local_forward(&options, fwd_port, buf,
418
				    fwd_host_port);
419
			else if (opt == 'R')
420
				add_remote_forward(&options, fwd_port, buf,
421
				    fwd_host_port);
422
			break;
418
			break;
423
419
424
		case 'D':
420
		case 'D':
425
			fwd_port = a2port(optarg);
421
			cp = p = xstrdup(optarg);
426
			if (fwd_port == 0) {
422
			memset(&fwd, '\0', sizeof(fwd));
423
			fwd.connect_host = "socks";
424
			if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
425
				fprintf(stderr, "Bad dynamic forwarding "
426
				    "specification '%.100s'\n", optarg);
427
				exit(1);
428
			}
429
			if (cp != NULL) {
430
				fwd.listen_port = a2port(cp);
431
				fwd.listen_host = cleanhostname(fwd.listen_host);
432
			} else {
433
				fwd.listen_port = a2port(fwd.listen_host);
434
				fwd.listen_host = "";
435
			}
436
437
			if (fwd.listen_port == 0) {
427
				fprintf(stderr, "Bad dynamic port '%s'\n",
438
				fprintf(stderr, "Bad dynamic port '%s'\n",
428
				    optarg);
439
				    optarg);
429
				exit(1);
440
				exit(1);
430
			}
441
			}
431
			add_local_forward(&options, fwd_port, "socks", 0);
442
			add_local_forward(&options, &fwd);
443
			xfree(p);
432
			break;
444
			break;
433
445
434
		case 'C':
446
		case 'C':
Lines 831-844 ssh_init_forwarding(void) Link Here
831
843
832
	/* Initiate local TCP/IP port forwardings. */
844
	/* Initiate local TCP/IP port forwardings. */
833
	for (i = 0; i < options.num_local_forwards; i++) {
845
	for (i = 0; i < options.num_local_forwards; i++) {
834
		debug("Connections to local port %d forwarded to remote address %.200s:%d",
846
		debug("Local connections to %.200s:%d forwarded to remote "
835
		    options.local_forwards[i].port,
847
		    "address %.200s:%d",
836
		    options.local_forwards[i].host,
848
		    (options.local_forwards[i].listen_host == NULL) ? 
837
		    options.local_forwards[i].host_port);
849
		    (options.gateway_ports ? "*" : "LOCALHOST") : 
850
		    options.local_forwards[i].listen_host,
851
		    options.local_forwards[i].listen_port,
852
		    options.local_forwards[i].connect_host,
853
		    options.local_forwards[i].connect_port);
838
		success += channel_setup_local_fwd_listener(
854
		success += channel_setup_local_fwd_listener(
839
		    options.local_forwards[i].port,
855
		    options.local_forwards[i].listen_host,
840
		    options.local_forwards[i].host,
856
		    options.local_forwards[i].listen_port,
841
		    options.local_forwards[i].host_port,
857
		    options.local_forwards[i].connect_host,
858
		    options.local_forwards[i].connect_port,
842
		    options.gateway_ports);
859
		    options.gateway_ports);
843
	}
860
	}
844
	if (i > 0 && success == 0)
861
	if (i > 0 && success == 0)
Lines 846-859 ssh_init_forwarding(void) Link Here
846
863
847
	/* Initiate remote TCP/IP port forwardings. */
864
	/* Initiate remote TCP/IP port forwardings. */
848
	for (i = 0; i < options.num_remote_forwards; i++) {
865
	for (i = 0; i < options.num_remote_forwards; i++) {
849
		debug("Connections to remote port %d forwarded to local address %.200s:%d",
866
		debug("Remote connections from %.200s:%d forwarded to "
850
		    options.remote_forwards[i].port,
867
		    "local address %.200s:%d",
851
		    options.remote_forwards[i].host,
868
		    options.remote_forwards[i].listen_host,
852
		    options.remote_forwards[i].host_port);
869
		    options.remote_forwards[i].listen_port,
870
		    options.remote_forwards[i].connect_host,
871
		    options.remote_forwards[i].connect_port);
853
		channel_request_remote_forwarding(
872
		channel_request_remote_forwarding(
854
		    options.remote_forwards[i].port,
873
		    options.remote_forwards[i].listen_host,
855
		    options.remote_forwards[i].host,
874
		    options.remote_forwards[i].listen_port,
856
		    options.remote_forwards[i].host_port);
875
		    options.remote_forwards[i].connect_host,
876
		    options.remote_forwards[i].connect_port);
857
	}
877
	}
858
}
878
}
859
879
Lines 1029-1040 client_global_request_reply_fwd(int type Link Here
1029
		return;
1049
		return;
1030
	debug("remote forward %s for: listen %d, connect %s:%d",
1050
	debug("remote forward %s for: listen %d, connect %s:%d",
1031
	    type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1051
	    type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1032
	    options.remote_forwards[i].port,
1052
	    options.remote_forwards[i].listen_port,
1033
	    options.remote_forwards[i].host,
1053
	    options.remote_forwards[i].connect_host,
1034
	    options.remote_forwards[i].host_port);
1054
	    options.remote_forwards[i].connect_port);
1035
	if (type == SSH2_MSG_REQUEST_FAILURE)
1055
	if (type == SSH2_MSG_REQUEST_FAILURE)
1036
		logit("Warning: remote port forwarding failed for listen port %d",
1056
		logit("Warning: remote port forwarding failed for listen "
1037
		    options.remote_forwards[i].port);
1057
		    "port %d", options.remote_forwards[i].listen_port);
1038
}
1058
}
1039
1059
1040
static void
1060
static void
(-)ssh_config.5 (-8 / +60 lines)
Lines 475-486 The default is to use the server specifi Link Here
475
Specifies that a TCP/IP port on the local machine be forwarded over
475
Specifies that a TCP/IP port on the local machine be forwarded over
476
the secure channel to the specified host and port from the remote machine.
476
the secure channel to the specified host and port from the remote machine.
477
The first argument must be a port number, and the second must be
477
The first argument must be a port number, and the second must be
478
.Ar host:port .
478
.Xo
479
IPv6 addresses can be specified with an alternative syntax:
479
.Sm off
480
.Ar host/port .
480
.Oo Ar bind_address : Oc
481
Multiple forwardings may be specified, and additional
481
.Ar host:port
482
forwardings can be given on the command line.
482
.Sm on
483
.Xc .
484
IPv6 addresses can be specified by enclosing addresses in square brackets or 
485
by using an alternative syntax:
486
.Xo
487
.Sm off
488
.Oo Ar bind_address / Oc
489
.Ar host/port
490
.Sm on
491
.Xc .
492
Multiple forwardings may be specified, and additional forwardings can be 
493
given on the command line.
483
Only the superuser can forward privileged ports.
494
Only the superuser can forward privileged ports.
495
By default, the local port is bound in accordance with the
496
.Cm GatewayPorts
497
setting.
498
However, an explicit
499
.Ar bind_address
500
may be used to bind the connection to a specific address.
501
The
502
.Ar bind_address
503
of
504
.Dq localhost
505
indicates that the listening port be bound for local use only, while an 
506
empty address or 
507
.Dq *
508
indicates that the port should be available from all interfaces.
484
.It Cm LogLevel
509
.It Cm LogLevel
485
Gives the verbosity level that is used when logging messages from
510
Gives the verbosity level that is used when logging messages from
486
.Nm ssh .
511
.Nm ssh .
Lines 587-598 This option applies to protocol version Link Here
587
Specifies that a TCP/IP port on the remote machine be forwarded over
612
Specifies that a TCP/IP port on the remote machine be forwarded over
588
the secure channel to the specified host and port from the local machine.
613
the secure channel to the specified host and port from the local machine.
589
The first argument must be a port number, and the second must be
614
The first argument must be a port number, and the second must be
590
.Ar host:port .
615
.Xo
591
IPv6 addresses can be specified with an alternative syntax:
616
.Sm off
592
.Ar host/port .
617
.Oo Ar bind_address : Oc
618
.Ar host:port
619
.Sm on
620
.Xc .
621
IPv6 addresses can be specified by enclosing any addresses in square brackets
622
or by using the alternative syntax:
623
.Xo
624
.Sm off
625
.Oo Ar bind_address / Oc
626
.Ar host/port
627
.Sm on
628
.Xc .
593
Multiple forwardings may be specified, and additional
629
Multiple forwardings may be specified, and additional
594
forwardings can be given on the command line.
630
forwardings can be given on the command line.
595
Only the superuser can forward privileged ports.
631
Only the superuser can forward privileged ports.
632
.Pp
633
If the
634
.Ar bind_address
635
is not specified, the default is to only bind to loopback addresses.
636
If the
637
.Ar bind_address
638
is
639
.Ql *
640
or an empty string, then the forwarding is requested to listen on all
641
interfaces.
642
Specifying a remote
643
.Ar bind_address
644
will only succeed if the server's 
645
.Cm GatewayPorts 
646
option is enabled (see
647
.Xr sshd_config 5 ).
596
.It Cm RhostsRSAAuthentication
648
.It Cm RhostsRSAAuthentication
597
Specifies whether to try rhosts based authentication with RSA host
649
Specifies whether to try rhosts based authentication with RSA host
598
authentication.
650
authentication.
(-)sshd_config.5 (-2 / +2 lines)
Lines 256-263 This prevents other remote hosts from co Link Here
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 must be
262
.Dq yes
262
.Dq yes
263
or
263
or

Return to bug 413