Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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@
  • Loading branch information...
commit 36c574406d8a6e0eea3b05bb30ca6a89c1ddfcca 1 parent ff6e35f
@mfriedl mfriedl authored
View
51 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)
{
View
3  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);
View
3  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|
View
3  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);
View
19 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 */
View
3  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;
}
View
3  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. */
View
29 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. */
View
4 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"
Please sign in to comment.
Something went wrong with that request. Please try again.