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

Collapse All | Expand All

(-)canohost.c (-1 / +1 lines)
Lines 300-306 get_remote_name_or_ip(u_int utmp_len, in Link Here
300
300
301
/* Returns the local/remote port for the socket. */
301
/* Returns the local/remote port for the socket. */
302
302
303
static int
303
int
304
get_sock_port(int sock, int local)
304
get_sock_port(int sock, int local)
305
{
305
{
306
	struct sockaddr_storage from;
306
	struct sockaddr_storage from;
(-)canohost.h (+2 lines)
Lines 23-25 char *get_local_name(int); Link Here
23
23
24
int		 get_remote_port(void);
24
int		 get_remote_port(void);
25
int		 get_local_port(void);
25
int		 get_local_port(void);
26
int		 get_sock_port(int, int);
27
(-)channels.c (-7 / +43 lines)
Lines 2415-2421 channel_set_af(int af) Link Here
2415
}
2415
}
2416
2416
2417
static int
2417
static int
2418
channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
2418
channel_setup_fwd_listener(int type, const char *listen_addr,
2419
    u_short listen_port, int *allocated_listen_port,
2419
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2420
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2420
{
2421
{
2421
	Channel *c;
2422
	Channel *c;
Lines 2423-2428 channel_setup_fwd_listener(int type, con Link Here
2423
	struct addrinfo hints, *ai, *aitop;
2424
	struct addrinfo hints, *ai, *aitop;
2424
	const char *host, *addr;
2425
	const char *host, *addr;
2425
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2426
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2427
	in_port_t *lport_p;
2426
2428
2427
	host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
2429
	host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
2428
	    listen_addr : host_to_connect;
2430
	    listen_addr : host_to_connect;
Lines 2491-2500 channel_setup_fwd_listener(int type, con Link Here
2491
		}
2493
		}
2492
		return 0;
2494
		return 0;
2493
	}
2495
	}
2494
2496
	if (allocated_listen_port != NULL)
2497
		*allocated_listen_port = 0;
2495
	for (ai = aitop; ai; ai = ai->ai_next) {
2498
	for (ai = aitop; ai; ai = ai->ai_next) {
2496
		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
2499
		switch (ai->ai_family) {
2500
		case AF_INET:
2501
			lport_p = &((struct sockaddr_in *)ai->ai_addr)->
2502
			    sin_port;
2503
			break;
2504
		case AF_INET6:
2505
			lport_p = &((struct sockaddr_in6 *)ai->ai_addr)->
2506
			    sin6_port;
2507
			break;
2508
		default:
2497
			continue;
2509
			continue;
2510
		}
2511
		/*
2512
		 * If allocating a port for -R forwards, then use the
2513
		 * same port for all address families.
2514
		 */
2515
		if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
2516
		    allocated_listen_port != NULL && *allocated_listen_port > 0)
2517
			*lport_p = htons(*allocated_listen_port);
2518
2498
		if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
2519
		if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
2499
		    strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
2520
		    strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
2500
			error("channel_setup_fwd_listener: getnameinfo failed");
2521
			error("channel_setup_fwd_listener: getnameinfo failed");
Lines 2510-2516 channel_setup_fwd_listener(int type, con Link Here
2510
2531
2511
		channel_set_reuseaddr(sock);
2532
		channel_set_reuseaddr(sock);
2512
2533
2513
		debug("Local forwarding listening on %s port %s.", ntop, strport);
2534
		debug("Local forwarding listening on %s port %s.",
2535
		    ntop, strport);
2514
2536
2515
		/* Bind the socket to the address. */
2537
		/* Bind the socket to the address. */
2516
		if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
2538
		if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
Lines 2525-2530 channel_setup_fwd_listener(int type, con Link Here
2525
			close(sock);
2547
			close(sock);
2526
			continue;
2548
			continue;
2527
		}
2549
		}
2550
2551
		/*
2552
		 * listen_port == 0 requests a dynamically allocated port -
2553
		 * record what we got.
2554
		 */
2555
		if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
2556
		    allocated_listen_port != NULL &&
2557
		    *allocated_listen_port == 0) {
2558
			*allocated_listen_port = get_sock_port(sock, 1);
2559
			debug("Allocated listen port %d",
2560
			    *allocated_listen_port);
2561
		}
2562
2528
		/* Allocate a channel number for the socket. */
2563
		/* Allocate a channel number for the socket. */
2529
		c = channel_new("port listener", type, sock, sock, -1,
2564
		c = channel_new("port listener", type, sock, sock, -1,
2530
		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
2565
		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
Lines 2568-2584 channel_setup_local_fwd_listener(const c Link Here
2568
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2603
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2569
{
2604
{
2570
	return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
2605
	return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
2571
	    listen_host, listen_port, host_to_connect, port_to_connect,
2606
	    listen_host, listen_port, NULL, host_to_connect, port_to_connect,
2572
	    gateway_ports);
2607
	    gateway_ports);
2573
}
2608
}
2574
2609
2575
/* protocol v2 remote port fwd, used by sshd */
2610
/* protocol v2 remote port fwd, used by sshd */
2576
int
2611
int
2577
channel_setup_remote_fwd_listener(const char *listen_address,
2612
channel_setup_remote_fwd_listener(const char *listen_address,
2578
    u_short listen_port, int gateway_ports)
2613
    u_short listen_port, int *allocated_listen_port, int gateway_ports)
2579
{
2614
{
2580
	return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
2615
	return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
2581
	    listen_address, listen_port, NULL, 0, gateway_ports);
2616
	    listen_address, listen_port, allocated_listen_port,
2617
	    NULL, 0, gateway_ports);
2582
}
2618
}
2583
2619
2584
/*
2620
/*
(-)channels.h (-1 / +1 lines)
Lines 246-252 int channel_request_remote_forwarding(c Link Here
246
int	 channel_setup_local_fwd_listener(const char *, u_short,
246
int	 channel_setup_local_fwd_listener(const char *, u_short,
247
	     const char *, u_short, int);
247
	     const char *, u_short, int);
248
void	 channel_request_rforward_cancel(const char *host, u_short port);
248
void	 channel_request_rforward_cancel(const char *host, u_short port);
249
int	 channel_setup_remote_fwd_listener(const char *, u_short, int);
249
int	 channel_setup_remote_fwd_listener(const char *, u_short, int *, int);
250
int	 channel_cancel_rport_listener(const char *, u_short);
250
int	 channel_cancel_rport_listener(const char *, u_short);
251
251
252
/* x11 forwarding */
252
/* x11 forwarding */
(-)clientloop.c (-1 / +1 lines)
Lines 840-846 process_cmdline(void) Link Here
840
		}
840
		}
841
		channel_request_rforward_cancel(cancel_host, cancel_port);
841
		channel_request_rforward_cancel(cancel_host, cancel_port);
842
	} else {
842
	} else {
843
		if (!parse_forward(&fwd, s, dynamic ? 1 : 0)) {
843
		if (!parse_forward(&fwd, s, dynamic, remote)) {
844
			logit("Bad forwarding specification.");
844
			logit("Bad forwarding specification.");
845
			goto out;
845
			goto out;
846
		}
846
		}
(-)readconf.c (-4 / +9 lines)
Lines 730-736 parse_int: Link Here
730
		}
730
		}
731
731
732
		if (parse_forward(&fwd, fwdarg,
732
		if (parse_forward(&fwd, fwdarg,
733
		    opcode == oDynamicForward ? 1 : 0) == 0)
733
		    opcode == oDynamicForward ? 1 : 0,
734
		    opcode == oRemoteForward ? 1 : 0) == 0)
734
			fatal("%.200s line %d: Bad forwarding specification.",
735
			fatal("%.200s line %d: Bad forwarding specification.",
735
			    filename, linenum);
736
			    filename, linenum);
736
737
Lines 1215-1221 fill_default_options(Options * options) Link Here
1215
 * returns number of arguments parsed or zero on error
1216
 * returns number of arguments parsed or zero on error
1216
 */
1217
 */
1217
int
1218
int
1218
parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd)
1219
parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1219
{
1220
{
1220
	int i;
1221
	int i;
1221
	char *p, *cp, *fwdarg[4];
1222
	char *p, *cp, *fwdarg[4];
Lines 1278-1289 parse_forward(Forward *fwd, const char * Link Here
1278
			goto fail_free;
1279
			goto fail_free;
1279
	}
1280
	}
1280
1281
1281
	if (fwd->listen_port == 0)
1282
	if (!remotefwd && fwd->listen_port == 0)
1282
		goto fail_free;
1283
		goto fail_free; /* XXX discriminate between error and 0 */
1283
1284
1284
	if (fwd->connect_host != NULL &&
1285
	if (fwd->connect_host != NULL &&
1285
	    strlen(fwd->connect_host) >= NI_MAXHOST)
1286
	    strlen(fwd->connect_host) >= NI_MAXHOST)
1286
		goto fail_free;
1287
		goto fail_free;
1288
	if (fwd->listen_host != NULL &&
1289
	    strlen(fwd->listen_host) >= NI_MAXHOST)
1290
		goto fail_free;
1291
1287
1292
1288
	return (i);
1293
	return (i);
1289
1294
(-)readconf.h (-1 / +1 lines)
Lines 134-140 typedef struct { Link Here
134
void     initialize_options(Options *);
134
void     initialize_options(Options *);
135
void     fill_default_options(Options *);
135
void     fill_default_options(Options *);
136
int	 read_config_file(const char *, const char *, Options *, int);
136
int	 read_config_file(const char *, const char *, Options *, int);
137
int	 parse_forward(Forward *, const char *, int);
137
int	 parse_forward(Forward *, const char *, int, int);
138
138
139
int
139
int
140
process_config_line(Options *, const char *, char *, const char *, int, int *);
140
process_config_line(Options *, const char *, char *, const char *, int, int *);
(-)serverloop.c (-3 / +7 lines)
Lines 1058-1064 server_input_global_request(int type, u_ Link Here
1058
{
1058
{
1059
	char *rtype;
1059
	char *rtype;
1060
	int want_reply;
1060
	int want_reply;
1061
	int success = 0;
1061
	int success = 0, allocated_listen_port = 0;
1062
1062
1063
	rtype = packet_get_string(NULL);
1063
	rtype = packet_get_string(NULL);
1064
	want_reply = packet_get_char();
1064
	want_reply = packet_get_char();
Lines 1081-1093 server_input_global_request(int type, u_ Link Here
1081
		/* check permissions */
1081
		/* check permissions */
1082
		if (!options.allow_tcp_forwarding ||
1082
		if (!options.allow_tcp_forwarding ||
1083
		    no_port_forwarding_flag ||
1083
		    no_port_forwarding_flag ||
1084
		    (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)) {
1084
		    (listen_port != 0 && listen_port < IPPORT_RESERVED &&
1085
		    pw->pw_uid != 0)) {
1085
			success = 0;
1086
			success = 0;
1086
			packet_send_debug("Server has disabled port forwarding.");
1087
			packet_send_debug("Server has disabled port forwarding.");
1087
		} else {
1088
		} else {
1088
			/* Start listening on the port */
1089
			/* Start listening on the port */
1089
			success = channel_setup_remote_fwd_listener(
1090
			success = channel_setup_remote_fwd_listener(
1090
			    listen_address, listen_port, options.gateway_ports);
1091
			    listen_address, listen_port,
1092
			    &allocated_listen_port, options.gateway_ports);
1091
		}
1093
		}
1092
		xfree(listen_address);
1094
		xfree(listen_address);
1093
	} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
1095
	} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
Lines 1109-1114 server_input_global_request(int type, u_ Link Here
1109
	if (want_reply) {
1111
	if (want_reply) {
1110
		packet_start(success ?
1112
		packet_start(success ?
1111
		    SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
1113
		    SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
1114
		if (success && allocated_listen_port > 0)
1115
			packet_put_int(allocated_listen_port);
1112
		packet_send();
1116
		packet_send();
1113
		packet_write_wait();
1117
		packet_write_wait();
1114
	}
1118
	}
(-)ssh.c (-3 / +10 lines)
Lines 440-446 main(int ac, char **av) Link Here
440
			break;
440
			break;
441
441
442
		case 'L':
442
		case 'L':
443
			if (parse_forward(&fwd, optarg, 0))
443
			if (parse_forward(&fwd, optarg, 0, 0))
444
				add_local_forward(&options, &fwd);
444
				add_local_forward(&options, &fwd);
445
			else {
445
			else {
446
				fprintf(stderr,
446
				fprintf(stderr,
Lines 451-457 main(int ac, char **av) Link Here
451
			break;
451
			break;
452
452
453
		case 'R':
453
		case 'R':
454
			if (parse_forward(&fwd, optarg, 0)) {
454
			if (parse_forward(&fwd, optarg, 0, 1)) {
455
				add_remote_forward(&options, &fwd);
455
				add_remote_forward(&options, &fwd);
456
			} else {
456
			} else {
457
				fprintf(stderr,
457
				fprintf(stderr,
Lines 462-468 main(int ac, char **av) Link Here
462
			break;
462
			break;
463
463
464
		case 'D':
464
		case 'D':
465
			if (parse_forward(&fwd, optarg, 1)) {
465
			if (parse_forward(&fwd, optarg, 1, 0)) {
466
				add_local_forward(&options, &fwd);
466
				add_local_forward(&options, &fwd);
467
			} else {
467
			} else {
468
				fprintf(stderr,
468
				fprintf(stderr,
Lines 818-826 ssh_confirm_remote_forward(int type, u_i Link Here
818
{
818
{
819
	Forward *rfwd = (Forward *)ctxt;
819
	Forward *rfwd = (Forward *)ctxt;
820
820
821
	/* XXX verbose() on failure? */
821
	debug("remote forward %s for: listen %d, connect %s:%d",
822
	debug("remote forward %s for: listen %d, connect %s:%d",
822
	    type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
823
	    type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
823
	    rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
824
	    rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
825
	if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) {
826
		logit("Allocated port %u for remote forward to %s:%d",
827
			packet_get_int(),
828
			rfwd->connect_host, rfwd->connect_port);
829
	}
830
	
824
	if (type == SSH2_MSG_REQUEST_FAILURE) {
831
	if (type == SSH2_MSG_REQUEST_FAILURE) {
825
		if (options.exit_on_forward_failure)
832
		if (options.exit_on_forward_failure)
826
			fatal("Error: remote port forwarding failed for "
833
			fatal("Error: remote port forwarding failed for "

Return to bug 1003