diff options
author | 2014-06-27 16:41:56 +0000 | |
---|---|---|
committer | 2014-06-27 16:41:56 +0000 | |
commit | f7ab312325305bcdb84d0903fe8fd84c4e3e7aa0 (patch) | |
tree | cf2cc38d91000082904fa7957b3434cfd7e5606a | |
parent | Do not KASSERT an unsigned value being >= 0 after decrementing it; instead, (diff) | |
download | wireguard-openbsd-f7ab312325305bcdb84d0903fe8fd84c4e3e7aa0.tar.xz wireguard-openbsd-f7ab312325305bcdb84d0903fe8fd84c4e3e7aa0.zip |
fix remote fwding with same listen port but different listen address
with gerhard@, ok djm@
-rw-r--r-- | usr.bin/ssh/channels.c | 96 | ||||
-rw-r--r-- | usr.bin/ssh/channels.h | 5 | ||||
-rw-r--r-- | usr.bin/ssh/clientloop.c | 4 | ||||
-rw-r--r-- | usr.bin/ssh/ssh.c | 6 |
4 files changed, 79 insertions, 32 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index 5421e15215e..9ec2d45a710 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.332 2014/04/28 03:09:18 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.333 2014/06/27 16:41:56 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -106,7 +106,8 @@ static int channel_max_fd = 0; typedef struct { char *host_to_connect; /* Connect to 'host'. */ u_short port_to_connect; /* Connect to 'port'. */ - u_short listen_port; /* Remote side should listen port number. */ + char *listen_host; /* Remote side should listen address. */ + u_short listen_port; /* Remote side should listen port. */ } ForwardPermission; /* List of all permitted host/port pairs to connect by the user. */ @@ -3001,11 +3002,52 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port, idx = num_permitted_opens++; permitted_opens[idx].host_to_connect = xstrdup(host_to_connect); permitted_opens[idx].port_to_connect = port_to_connect; + permitted_opens[idx].listen_host = listen_host ? + xstrdup(listen_host) : NULL; permitted_opens[idx].listen_port = listen_port; } return (idx); } +static int +open_match(ForwardPermission *allowed_open, const char *requestedhost, + u_short requestedport) +{ + if (allowed_open->host_to_connect == NULL) + return 0; + if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT && + allowed_open->port_to_connect != requestedport) + return 0; + if (strcmp(allowed_open->host_to_connect, requestedhost) != 0) + return 0; + return 1; +} + +/* + * Note that in he listen host/port case + * we don't support FWD_PERMIT_ANY_PORT and + * need to translate between the configured-host (listen_host) + * and what we've sent to the remote server (channel_rfwd_bind_host) + */ +static int +open_listen_match(ForwardPermission *allowed_open, const char *requestedhost, + u_short requestedport, int translate) +{ + const char *allowed_host; + + if (allowed_open->host_to_connect == NULL) + return 0; + if (allowed_open->listen_port != requestedport) + return 0; + allowed_host = translate ? + channel_rfwd_bind_host(allowed_open->listen_host) : + allowed_open->listen_host; + if (allowed_host == NULL || + strcmp(allowed_host, requestedhost) != 0) + return 0; + return 1; +} + /* * Request cancellation of remote forwarding of connection host:port from * local side. @@ -3019,8 +3061,7 @@ channel_request_rforward_cancel(const char *host, u_short port) return -1; for (i = 0; i < num_permitted_opens; i++) { - if (permitted_opens[i].host_to_connect != NULL && - permitted_opens[i].listen_port == port) + if (open_listen_match(&permitted_opens[i], host, port, 0)) break; } if (i >= num_permitted_opens) { @@ -3034,10 +3075,12 @@ channel_request_rforward_cancel(const char *host, u_short port) packet_put_int(port); packet_send(); - permitted_opens[i].listen_port = 0; permitted_opens[i].port_to_connect = 0; + permitted_opens[i].listen_port = 0; free(permitted_opens[i].host_to_connect); permitted_opens[i].host_to_connect = NULL; + free(permitted_opens[i].listen_host); + permitted_opens[i].listen_host = NULL; return 0; } @@ -3101,6 +3144,8 @@ channel_add_permitted_opens(char *host, int port) num_permitted_opens + 1, sizeof(*permitted_opens)); permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); permitted_opens[num_permitted_opens].port_to_connect = port; + permitted_opens[num_permitted_opens].listen_host = NULL; + permitted_opens[num_permitted_opens].listen_port = 0; num_permitted_opens++; all_opens_permitted = 0; @@ -3132,6 +3177,8 @@ channel_update_permitted_opens(int idx, int newport) permitted_opens[idx].port_to_connect = 0; free(permitted_opens[idx].host_to_connect); permitted_opens[idx].host_to_connect = NULL; + free(permitted_opens[idx].listen_host); + permitted_opens[idx].listen_host = NULL; } } @@ -3145,6 +3192,8 @@ channel_add_adm_permitted_opens(char *host, int port) permitted_adm_opens[num_adm_permitted_opens].host_to_connect = xstrdup(host); permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port; + permitted_adm_opens[num_adm_permitted_opens].listen_host = NULL; + permitted_adm_opens[num_adm_permitted_opens].listen_port = 0; return ++num_adm_permitted_opens; } @@ -3162,8 +3211,10 @@ channel_clear_permitted_opens(void) { int i; - for (i = 0; i < num_permitted_opens; i++) + for (i = 0; i < num_permitted_opens; i++) { free(permitted_opens[i].host_to_connect); + free(permitted_opens[i].listen_host); + } free(permitted_opens); permitted_opens = NULL; num_permitted_opens = 0; @@ -3174,8 +3225,10 @@ channel_clear_adm_permitted_opens(void) { int i; - for (i = 0; i < num_adm_permitted_opens; i++) + for (i = 0; i < num_adm_permitted_opens; i++) { free(permitted_adm_opens[i].host_to_connect); + free(permitted_adm_opens[i].listen_host); + } free(permitted_adm_opens); permitted_adm_opens = NULL; num_adm_permitted_opens = 0; @@ -3213,15 +3266,6 @@ permitopen_port(const char *p) return -1; } -static int -port_match(u_short allowedport, u_short requestedport) -{ - if (allowedport == FWD_PERMIT_ANY_PORT || - allowedport == requestedport) - return 1; - return 0; -} - /* Try to start non-blocking connect to next host in cctx list */ static int connect_next(struct channel_connect *cctx) @@ -3316,13 +3360,14 @@ connect_to(const char *host, u_short port, char *ctype, char *rname) } Channel * -channel_connect_by_listen_address(u_short listen_port, char *ctype, char *rname) +channel_connect_by_listen_address(const char *listen_host, + u_short listen_port, char *ctype, char *rname) { int i; for (i = 0; i < num_permitted_opens; i++) { - if (permitted_opens[i].host_to_connect != NULL && - port_match(permitted_opens[i].listen_port, listen_port)) { + if (open_listen_match(&permitted_opens[i], listen_host, + listen_port, 1)) { return connect_to( permitted_opens[i].host_to_connect, permitted_opens[i].port_to_connect, ctype, rname); @@ -3342,20 +3387,19 @@ channel_connect_to(const char *host, u_short port, char *ctype, char *rname) permit = all_opens_permitted; if (!permit) { for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].host_to_connect != NULL && - port_match(permitted_opens[i].port_to_connect, port) && - strcmp(permitted_opens[i].host_to_connect, host) == 0) + if (open_match(&permitted_opens[i], host, port)) { permit = 1; + break; + } } if (num_adm_permitted_opens > 0) { permit_adm = 0; for (i = 0; i < num_adm_permitted_opens; i++) - if (permitted_adm_opens[i].host_to_connect != NULL && - port_match(permitted_adm_opens[i].port_to_connect, port) && - strcmp(permitted_adm_opens[i].host_to_connect, host) - == 0) + if (open_match(&permitted_adm_opens[i], host, port)) { permit_adm = 1; + break; + } } if (!permit || !permit_adm) { diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h index 9e5fe0e8bc1..a7537cb453c 100644 --- a/usr.bin/ssh/channels.h +++ b/usr.bin/ssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.113 2013/06/07 15:37:52 dtucker Exp $ */ +/* $OpenBSD: channels.h,v 1.114 2014/06/27 16:41:56 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -263,7 +263,8 @@ void channel_print_adm_permitted_opens(void); int channel_input_port_forward_request(int, int); Channel *channel_connect_to(const char *, u_short, char *, char *); Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); -Channel *channel_connect_by_listen_address(u_short, char *, char *); +Channel *channel_connect_by_listen_address(const char *, u_short, + char *, char *); int channel_request_remote_forwarding(const char *, u_short, const char *, u_short); int channel_setup_local_fwd_listener(const char *, u_short, diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index b5227e6a108..4153688c8ca 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.259 2014/04/29 13:10:30 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.260 2014/06/27 16:41:56 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1837,7 +1837,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) "originator %s port %d", listen_address, listen_port, originator_address, originator_port); - c = channel_connect_by_listen_address(listen_port, + c = channel_connect_by_listen_address(listen_address, listen_port, "forwarded-tcpip", originator_address); free(originator_address); diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index 2a1529d67c5..17f6363a236 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.403 2014/06/24 02:19:48 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.404 2014/06/27 16:41:56 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1231,8 +1231,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) Forward *rfwd = (Forward *)ctxt; /* XXX verbose() on failure? */ - debug("remote forward %s for: listen %d, connect %s:%d", + debug("remote forward %s for: listen %s%s%d, connect %s:%d", type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", + rfwd->listen_host == NULL ? "" : rfwd->listen_host, + rfwd->listen_host == NULL ? "" : ":", rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); if (rfwd->listen_port == 0) { if (type == SSH2_MSG_REQUEST_SUCCESS) { |