- markus@cvs.openbsd.org 2011/09/23 07:45:05
[mux.c readconf.h channels.h compat.h compat.c ssh.c readconf.c channels.c version.h]
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@
diff --git a/mux.c b/mux.c
index 6b63d81..52aec62 100644
--- a/mux.c
+++ b/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>
*
@@ -601,12 +601,16 @@
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);
}
@@ -745,8 +749,9 @@
} 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));
@@ -781,7 +786,7 @@
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 ||
@@ -836,9 +841,13 @@
/*
* 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 */