diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2011-09-23 07:45:06 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2011-09-23 07:45:06 +0000 |
commit | f1b8f8141af617d4556a047743774317a54d6acc (patch) | |
tree | 3aaedbfabdf6f5891b80dd0de017b28e4bccaeb8 /usr.bin | |
parent | 7a921840a0ad3319626b94772a68794b0b515f3f (diff) |
unbreak remote portforwarding with dynamic allocated listen ports:
1) send the actual listen port in the open message (instead of 0).
this allows multiple forwardings with a dynamic listen port
2) update the matching permit-open entry, so we can identify where
to connect to
report: den at skbkontur.ru and P. Szczygielski
feedback and ok djm@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/channels.c | 51 | ||||
-rw-r--r-- | usr.bin/ssh/channels.h | 3 | ||||
-rw-r--r-- | usr.bin/ssh/compat.c | 3 | ||||
-rw-r--r-- | usr.bin/ssh/compat.h | 3 | ||||
-rw-r--r-- | usr.bin/ssh/mux.c | 19 | ||||
-rw-r--r-- | usr.bin/ssh/readconf.c | 3 | ||||
-rw-r--r-- | usr.bin/ssh/readconf.h | 3 | ||||
-rw-r--r-- | usr.bin/ssh/ssh.c | 29 | ||||
-rw-r--r-- | usr.bin/ssh/version.h | 4 |
9 files changed, 88 insertions, 30 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index d7bba49a33b..17cb139a0b6 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.314 2011/09/23 00:22:04 dtucker Exp $ */ +/* $OpenBSD: channels.c,v 1.315 2011/09/23 07:45:05 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -2786,8 +2786,12 @@ channel_setup_fwd_listener(int type, const char *listen_addr, 0, "port listener", 1); c->path = xstrdup(host); c->host_port = port_to_connect; - c->listening_port = listen_port; c->listening_addr = addr == NULL ? NULL : xstrdup(addr); + if (listen_port == 0 && allocated_listen_port != NULL && + !(datafellows & SSH_BUG_DYNAMIC_RPORT)) + c->listening_port = *allocated_listen_port; + else + c->listening_port = listen_port; success = 1; } if (success == 0) @@ -2896,12 +2900,14 @@ channel_rfwd_bind_host(const char *listen_host) /* * Initiate forwarding of connections to port "port" on remote host through * the secure channel to host:port from local side. + * Returns handle (index) for updating the dynamic listen port with + * channel_update_permitted_opens(). */ int channel_request_remote_forwarding(const char *listen_host, u_short listen_port, const char *host_to_connect, u_short port_to_connect) { - int type, success = 0; + int type, success = 0, idx = -1; /* Send the forward request to the remote side. */ if (compat20) { @@ -2940,12 +2946,12 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port, /* Record that connection to this host/port is permitted. */ permitted_opens = xrealloc(permitted_opens, num_permitted_opens + 1, sizeof(*permitted_opens)); - permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); - permitted_opens[num_permitted_opens].port_to_connect = port_to_connect; - permitted_opens[num_permitted_opens].listen_port = listen_port; - num_permitted_opens++; + 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_port = listen_port; } - return (success ? 0 : -1); + return (idx); } /* @@ -3048,6 +3054,35 @@ channel_add_permitted_opens(char *host, int port) all_opens_permitted = 0; } +/* + * Update the listen port for a dynamic remote forward, after + * the actual 'newport' has been allocated. If 'newport' < 0 is + * passed then they entry will be invalidated. + */ +void +channel_update_permitted_opens(int idx, int newport) +{ + if (idx < 0 || idx >= num_permitted_opens) { + debug("channel_update_permitted_opens: index out of range:" + " %d num_permitted_opens %d", idx, num_permitted_opens); + return; + } + debug("%s allowed port %d for forwarding to host %s port %d", + newport > 0 ? "Updating" : "Removing", + newport, + permitted_opens[idx].host_to_connect, + permitted_opens[idx].port_to_connect); + if (newport >= 0) { + permitted_opens[idx].listen_port = + (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport; + } else { + permitted_opens[idx].listen_port = 0; + permitted_opens[idx].port_to_connect = 0; + xfree(permitted_opens[idx].host_to_connect); + permitted_opens[idx].host_to_connect = NULL; + } +} + int channel_add_adm_permitted_opens(char *host, int port) { diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h index 0d49a5f7917..e0ea704d05a 100644 --- a/usr.bin/ssh/channels.h +++ b/usr.bin/ssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.108 2011/09/23 00:22:04 dtucker Exp $ */ +/* $OpenBSD: channels.h,v 1.109 2011/09/23 07:45:05 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -252,6 +252,7 @@ void channel_set_af(int af); void channel_permit_all_opens(void); void channel_add_permitted_opens(char *, int); int channel_add_adm_permitted_opens(char *, int); +void channel_update_permitted_opens(int, int); void channel_clear_permitted_opens(void); void channel_clear_adm_permitted_opens(void); void channel_print_adm_permitted_opens(void); diff --git a/usr.bin/ssh/compat.c b/usr.bin/ssh/compat.c index 11b26281977..13c0e4e71d3 100644 --- a/usr.bin/ssh/compat.c +++ b/usr.bin/ssh/compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.c,v 1.78 2008/09/11 14:22:37 markus Exp $ */ +/* $OpenBSD: compat.c,v 1.79 2011/09/23 07:45:05 markus Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -90,6 +90,7 @@ compat_datafellows(const char *version) { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR }, { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, { "OpenSSH_4*", 0 }, + { "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT}, { "OpenSSH*", SSH_NEW_OPENSSH }, { "*MindTerm*", 0 }, { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| diff --git a/usr.bin/ssh/compat.h b/usr.bin/ssh/compat.h index 16cf282a7ae..3ae5d9c7836 100644 --- a/usr.bin/ssh/compat.h +++ b/usr.bin/ssh/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.42 2008/09/11 14:22:37 markus Exp $ */ +/* $OpenBSD: compat.h,v 1.43 2011/09/23 07:45:05 markus Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -58,6 +58,7 @@ #define SSH_OLD_FORWARD_ADDR 0x01000000 #define SSH_BUG_RFWD_ADDR 0x02000000 #define SSH_NEW_OPENSSH 0x04000000 +#define SSH_BUG_DYNAMIC_RPORT 0x08000000 void enable_compat13(void); void enable_compat20(void); diff --git a/usr.bin/ssh/mux.c b/usr.bin/ssh/mux.c index caaf4913fcd..34addc1a266 100644 --- a/usr.bin/ssh/mux.c +++ b/usr.bin/ssh/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.30 2011/09/09 22:46:44 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.31 2011/09/23 07:45:05 markus Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> * @@ -584,12 +584,16 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) buffer_put_int(&out, MUX_S_REMOTE_PORT); buffer_put_int(&out, fctx->rid); buffer_put_int(&out, rfwd->allocated_port); + channel_update_permitted_opens(rfwd->handle, + rfwd->allocated_port); } else { buffer_put_int(&out, MUX_S_OK); buffer_put_int(&out, fctx->rid); } goto out; } else { + if (rfwd->listen_port == 0) + channel_update_permitted_opens(rfwd->handle, -1); xasprintf(&failmsg, "remote port forwarding failed for " "listen port %d", rfwd->listen_port); } @@ -728,8 +732,9 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) } else { struct mux_channel_confirm_ctx *fctx; - if (channel_request_remote_forwarding(fwd.listen_host, - fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0) + fwd.handle = channel_request_remote_forwarding(fwd.listen_host, + fwd.listen_port, fwd.connect_host, fwd.connect_port); + if (fwd.handle < 0) goto fail; add_remote_forward(&options, &fwd); fctx = xcalloc(1, sizeof(*fctx)); @@ -764,7 +769,7 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) char *fwd_desc = NULL; const char *error_reason = NULL; u_int ftype; - int i, ret = 0; + int i, listen_port, ret = 0; fwd.listen_host = fwd.connect_host = NULL; if (buffer_get_int_ret(&ftype, m) != 0 || @@ -819,9 +824,13 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) /* * This shouldn't fail unless we confused the host/port * between options.remote_forwards and permitted_opens. + * However, for dynamic allocated listen ports we need + * to lookup the actual listen port. */ + listen_port = (fwd.listen_port == 0) ? + found_fwd->allocated_port : fwd.listen_port; if (channel_request_rforward_cancel(fwd.listen_host, - fwd.listen_port) == -1) + listen_port) == -1) error_reason = "port not in permitted opens"; } else { /* local and dynamic forwards */ /* Ditto */ diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index e1885f78615..8f40dc6a016 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.193 2011/05/24 07:15:47 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.194 2011/09/23 07:45:05 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -290,6 +290,7 @@ add_remote_forward(Options *options, const Forward *newfwd) fwd->listen_port = newfwd->listen_port; fwd->connect_host = newfwd->connect_host; fwd->connect_port = newfwd->connect_port; + fwd->handle = newfwd->handle; fwd->allocated_port = 0; } diff --git a/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h index 5944cff939a..be30ee0e113 100644 --- a/usr.bin/ssh/readconf.h +++ b/usr.bin/ssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.90 2011/05/24 07:15:47 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.91 2011/09/23 07:45:05 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -24,6 +24,7 @@ typedef struct { char *connect_host; /* Host to connect. */ int connect_port; /* Port to connect on connect_host. */ int allocated_port; /* Dynamically allocated listen port */ + int handle; /* Handle for dynamic listen ports */ } Forward; /* Data structure for representing option data. */ diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index be75d0148bc..b261601b4a9 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.365 2011/09/09 22:46:44 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.366 2011/09/23 07:45:05 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -970,11 +970,17 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) debug("remote forward %s for: listen %d, connect %s:%d", type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); - if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) { - rfwd->allocated_port = packet_get_int(); - logit("Allocated port %u for remote forward to %s:%d", - rfwd->allocated_port, - rfwd->connect_host, rfwd->connect_port); + if (rfwd->listen_port == 0) { + if (type == SSH2_MSG_REQUEST_SUCCESS) { + rfwd->allocated_port = packet_get_int(); + logit("Allocated port %u for remote forward to %s:%d", + rfwd->allocated_port, + rfwd->connect_host, rfwd->connect_port); + channel_update_permitted_opens(rfwd->handle, + rfwd->allocated_port); + } else { + channel_update_permitted_opens(rfwd->handle, -1); + } } if (type == SSH2_MSG_REQUEST_FAILURE) { @@ -1066,19 +1072,22 @@ ssh_init_forwarding(void) options.remote_forwards[i].listen_port, options.remote_forwards[i].connect_host, options.remote_forwards[i].connect_port); - if (channel_request_remote_forwarding( + options.remote_forwards[i].handle = + channel_request_remote_forwarding( options.remote_forwards[i].listen_host, options.remote_forwards[i].listen_port, options.remote_forwards[i].connect_host, - options.remote_forwards[i].connect_port) < 0) { + options.remote_forwards[i].connect_port); + if (options.remote_forwards[i].handle < 0) { if (options.exit_on_forward_failure) fatal("Could not request remote forwarding."); else logit("Warning: Could not request remote " "forwarding."); + } else { + client_register_global_confirm(ssh_confirm_remote_forward, + &options.remote_forwards[i]); } - client_register_global_confirm(ssh_confirm_remote_forward, - &options.remote_forwards[i]); } /* Initiate tunnel forwarding. */ diff --git a/usr.bin/ssh/version.h b/usr.bin/ssh/version.h index 1c878c0076a..c2d352ef187 100644 --- a/usr.bin/ssh/version.h +++ b/usr.bin/ssh/version.h @@ -1,3 +1,3 @@ -/* $OpenBSD: version.h,v 1.62 2011/08/02 23:13:01 djm Exp $ */ +/* $OpenBSD: version.h,v 1.63 2011/09/23 07:45:05 markus Exp $ */ -#define SSH_VERSION "OpenSSH_5.9" +#define SSH_VERSION "OpenSSH_6.0-beta" |