summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2009-02-14 16:28:21 +1100
committerDamien Miller <djm@mindrot.org>2009-02-14 16:28:21 +1100
commit4bf648f7766ba764d7a78b1dbb26df4f0d42a8c9 (patch)
treecc576e28218cb3ad9617a12eabe68c21a7e09614 /channels.c
parentfdd66fc750228b5d040c45bc36565299374b72c8 (diff)
- djm@cvs.openbsd.org 2009/02/12 03:00:56
[canohost.c canohost.h channels.c channels.h clientloop.c readconf.c] [readconf.h serverloop.c ssh.c] support remote port forwarding with a zero listen port (-R0:...) to dyamically allocate a listen port at runtime (this is actually specified in rfc4254); bz#1003 ok markus@
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c52
1 files changed, 44 insertions, 8 deletions
diff --git a/channels.c b/channels.c
index 0b1c34c83..dea60ba24 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.294 2009/01/22 09:49:57 djm Exp $ */ 1/* $OpenBSD: channels.c,v 1.295 2009/02/12 03:00:56 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2460,7 +2460,8 @@ channel_set_af(int af)
2460} 2460}
2461 2461
2462static int 2462static int
2463channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port, 2463channel_setup_fwd_listener(int type, const char *listen_addr,
2464 u_short listen_port, int *allocated_listen_port,
2464 const char *host_to_connect, u_short port_to_connect, int gateway_ports) 2465 const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2465{ 2466{
2466 Channel *c; 2467 Channel *c;
@@ -2468,6 +2469,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2468 struct addrinfo hints, *ai, *aitop; 2469 struct addrinfo hints, *ai, *aitop;
2469 const char *host, *addr; 2470 const char *host, *addr;
2470 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 2471 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2472 in_port_t *lport_p;
2471 2473
2472 host = (type == SSH_CHANNEL_RPORT_LISTENER) ? 2474 host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
2473 listen_addr : host_to_connect; 2475 listen_addr : host_to_connect;
@@ -2536,10 +2538,29 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2536 } 2538 }
2537 return 0; 2539 return 0;
2538 } 2540 }
2539 2541 if (allocated_listen_port != NULL)
2542 *allocated_listen_port = 0;
2540 for (ai = aitop; ai; ai = ai->ai_next) { 2543 for (ai = aitop; ai; ai = ai->ai_next) {
2541 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 2544 switch (ai->ai_family) {
2545 case AF_INET:
2546 lport_p = &((struct sockaddr_in *)ai->ai_addr)->
2547 sin_port;
2548 break;
2549 case AF_INET6:
2550 lport_p = &((struct sockaddr_in6 *)ai->ai_addr)->
2551 sin6_port;
2552 break;
2553 default:
2542 continue; 2554 continue;
2555 }
2556 /*
2557 * If allocating a port for -R forwards, then use the
2558 * same port for all address families.
2559 */
2560 if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
2561 allocated_listen_port != NULL && *allocated_listen_port > 0)
2562 *lport_p = htons(*allocated_listen_port);
2563
2543 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), 2564 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
2544 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { 2565 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
2545 error("channel_setup_fwd_listener: getnameinfo failed"); 2566 error("channel_setup_fwd_listener: getnameinfo failed");
@@ -2555,7 +2576,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2555 2576
2556 channel_set_reuseaddr(sock); 2577 channel_set_reuseaddr(sock);
2557 2578
2558 debug("Local forwarding listening on %s port %s.", ntop, strport); 2579 debug("Local forwarding listening on %s port %s.",
2580 ntop, strport);
2559 2581
2560 /* Bind the socket to the address. */ 2582 /* Bind the socket to the address. */
2561 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { 2583 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
@@ -2574,6 +2596,19 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2574 close(sock); 2596 close(sock);
2575 continue; 2597 continue;
2576 } 2598 }
2599
2600 /*
2601 * listen_port == 0 requests a dynamically allocated port -
2602 * record what we got.
2603 */
2604 if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 &&
2605 allocated_listen_port != NULL &&
2606 *allocated_listen_port == 0) {
2607 *allocated_listen_port = get_sock_port(sock, 1);
2608 debug("Allocated listen port %d",
2609 *allocated_listen_port);
2610 }
2611
2577 /* Allocate a channel number for the socket. */ 2612 /* Allocate a channel number for the socket. */
2578 c = channel_new("port listener", type, sock, sock, -1, 2613 c = channel_new("port listener", type, sock, sock, -1,
2579 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 2614 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
@@ -2616,17 +2651,18 @@ channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
2616 const char *host_to_connect, u_short port_to_connect, int gateway_ports) 2651 const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2617{ 2652{
2618 return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, 2653 return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
2619 listen_host, listen_port, host_to_connect, port_to_connect, 2654 listen_host, listen_port, NULL, host_to_connect, port_to_connect,
2620 gateway_ports); 2655 gateway_ports);
2621} 2656}
2622 2657
2623/* protocol v2 remote port fwd, used by sshd */ 2658/* protocol v2 remote port fwd, used by sshd */
2624int 2659int
2625channel_setup_remote_fwd_listener(const char *listen_address, 2660channel_setup_remote_fwd_listener(const char *listen_address,
2626 u_short listen_port, int gateway_ports) 2661 u_short listen_port, int *allocated_listen_port, int gateway_ports)
2627{ 2662{
2628 return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER, 2663 return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
2629 listen_address, listen_port, NULL, 0, gateway_ports); 2664 listen_address, listen_port, allocated_listen_port,
2665 NULL, 0, gateway_ports);
2630} 2666}
2631 2667
2632/* 2668/*