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 2438-2444 channel_set_af(int af) Link Here
2438
}
2438
}
2439
2439
2440
static int
2440
static int
2441
channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
2441
channel_setup_fwd_listener(int type, const char *listen_addr,
2442
    u_short listen_port, int *allocated_listen_port,
2442
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2443
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2443
{
2444
{
2444
	Channel *c;
2445
	Channel *c;
Lines 2446-2451 channel_setup_fwd_listener(int type, con Link Here
2446
	struct addrinfo hints, *ai, *aitop;
2447
	struct addrinfo hints, *ai, *aitop;
2447
	const char *host, *addr;
2448
	const char *host, *addr;
2448
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2449
	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2450
	in_port_t *lport_p;
2449
2451
2450
	host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
2452
	host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
2451
	    listen_addr : host_to_connect;
2453
	    listen_addr : host_to_connect;
Lines 2514-2523 channel_setup_fwd_listener(int type, con Link Here
2514
		}
2516
		}
2515
		return 0;
2517
		return 0;
2516
	}
2518
	}
2517
2519
	if (allocated_listen_port != NULL)
2520
		*allocated_listen_port = 0;
2518
	for (ai = aitop; ai; ai = ai->ai_next) {
2521
	for (ai = aitop; ai; ai = ai->ai_next) {
2519
		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
2522
		switch (ai->ai_family) {
2523
		case AF_INET:
2524
			lport_p = &((struct sockaddr_in *)ai->ai_addr)->
2525
			    sin_port;
2526
			break;
2527
		case AF_INET6:
2528
			lport_p = &((struct sockaddr_in6 *)ai->ai_addr)->
2529
			    sin6_port;
2530
			break;
2531
		default:
2520
			continue;
2532
			continue;
2533
		}
2534
		/*
2535
		 * If allocating a port for -R forwards, then use the
2536
		 * same port for all address families.
2537
		 */
2538
		if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
2539
		    allocated_listen_port != NULL && *allocated_listen_port > 0)
2540
			*lport_p = htons(*allocated_listen_port);
2541
2521
		if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
2542
		if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
2522
		    strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
2543
		    strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
2523
			error("channel_setup_fwd_listener: getnameinfo failed");
2544
			error("channel_setup_fwd_listener: getnameinfo failed");
Lines 2533-2539 channel_setup_fwd_listener(int type, con Link Here
2533
2554
2534
		channel_set_reuseaddr(sock);
2555
		channel_set_reuseaddr(sock);
2535
2556
2536
		debug("Local forwarding listening on %s port %s.", ntop, strport);
2557
		debug("Local forwarding listening on %s port %s.",
2558
		    ntop, strport);
2537
2559
2538
		/* Bind the socket to the address. */
2560
		/* Bind the socket to the address. */
2539
		if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
2561
		if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
Lines 2548-2553 channel_setup_fwd_listener(int type, con Link Here
2548
			close(sock);
2570
			close(sock);
2549
			continue;
2571
			continue;
2550
		}
2572
		}
2573
2574
		/*
2575
		 * listen_port == 0 requests a dynamically allocated port -
2576
		 * record what we got.
2577
		 */
2578
		if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
2579
		    allocated_listen_port != NULL &&
2580
		    *allocated_listen_port == 0) {
2581
			*allocated_listen_port = get_sock_port(sock, 1);
2582
			debug("Allocated listen port %d",
2583
			    *allocated_listen_port);
2584
		}
2585
2551
		/* Allocate a channel number for the socket. */
2586
		/* Allocate a channel number for the socket. */
2552
		c = channel_new("port listener", type, sock, sock, -1,
2587
		c = channel_new("port listener", type, sock, sock, -1,
2553
		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
2588
		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
Lines 2590-2606 channel_setup_local_fwd_listener(const c Link Here
2590
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2625
    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2591
{
2626
{
2592
	return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
2627
	return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
2593
	    listen_host, listen_port, host_to_connect, port_to_connect,
2628
	    listen_host, listen_port, NULL, host_to_connect, port_to_connect,
2594
	    gateway_ports);
2629
	    gateway_ports);
2595
}
2630
}
2596
2631
2597
/* protocol v2 remote port fwd, used by sshd */
2632
/* protocol v2 remote port fwd, used by sshd */
2598
int
2633
int
2599
channel_setup_remote_fwd_listener(const char *listen_address,
2634
channel_setup_remote_fwd_listener(const char *listen_address,
2600
    u_short listen_port, int gateway_ports)
2635
    u_short listen_port, int *allocated_listen_port, int gateway_ports)
2601
{
2636
{
2602
	return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
2637
	return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
2603
	    listen_address, listen_port, NULL, 0, gateway_ports);
2638
	    listen_address, listen_port, allocated_listen_port,
2639
	    NULL, 0, gateway_ports);
2604
}
2640
}
2605
2641
2606
/*
2642
/*
(-)channels.h (-1 / +1 lines)
Lines 244-250 int channel_request_remote_forwarding(c Link Here
244
int	 channel_setup_local_fwd_listener(const char *, u_short,
244
int	 channel_setup_local_fwd_listener(const char *, u_short,
245
	     const char *, u_short, int);
245
	     const char *, u_short, int);
246
void	 channel_request_rforward_cancel(const char *host, u_short port);
246
void	 channel_request_rforward_cancel(const char *host, u_short port);
247
int	 channel_setup_remote_fwd_listener(const char *, u_short, int);
247
int	 channel_setup_remote_fwd_listener(const char *, u_short, int *, int);
248
int	 channel_cancel_rport_listener(const char *, u_short);
248
int	 channel_cancel_rport_listener(const char *, u_short);
249
249
250
/* x11 forwarding */
250
/* 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 (-3 / +8 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 (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1282
		goto fail_free;
1283
		goto fail_free;
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