summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--channels.c51
-rw-r--r--channels.h3
-rw-r--r--compat.c3
-rw-r--r--compat.h3
-rw-r--r--mux.c19
-rw-r--r--readconf.c3
-rw-r--r--readconf.h3
-rw-r--r--ssh.c29
-rw-r--r--version.h4
10 files changed, 98 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e1780a50..461c3c168 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,16 @@
5 [channels.c auth-options.c servconf.c channels.h sshd.8] 5 [channels.c auth-options.c servconf.c channels.h sshd.8]
6 Add wildcard support to PermitOpen, allowing things like "PermitOpen 6 Add wildcard support to PermitOpen, allowing things like "PermitOpen
7 localhost:*". bz #1857, ok djm markus. 7 localhost:*". bz #1857, ok djm markus.
8 - markus@cvs.openbsd.org 2011/09/23 07:45:05
9 [mux.c readconf.h channels.h compat.h compat.c ssh.c readconf.c channels.c
10 version.h]
11 unbreak remote portforwarding with dynamic allocated listen ports:
12 1) send the actual listen port in the open message (instead of 0).
13 this allows multiple forwardings with a dynamic listen port
14 2) update the matching permit-open entry, so we can identify where
15 to connect to
16 report: den at skbkontur.ru and P. Szczygielski
17 feedback and ok djm@
8 18
920110929 1920110929
10 - (djm) [configure.ac defines.h] No need to detect sizeof(char); patch 20 - (djm) [configure.ac defines.h] No need to detect sizeof(char); patch
diff --git a/channels.c b/channels.c
index 00e9af84a..f6e9b4d8c 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.314 2011/09/23 00:22:04 dtucker Exp $ */ 1/* $OpenBSD: channels.c,v 1.315 2011/09/23 07:45:05 markus 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
@@ -2814,8 +2814,12 @@ channel_setup_fwd_listener(int type, const char *listen_addr,
2814 0, "port listener", 1); 2814 0, "port listener", 1);
2815 c->path = xstrdup(host); 2815 c->path = xstrdup(host);
2816 c->host_port = port_to_connect; 2816 c->host_port = port_to_connect;
2817 c->listening_port = listen_port;
2818 c->listening_addr = addr == NULL ? NULL : xstrdup(addr); 2817 c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
2818 if (listen_port == 0 && allocated_listen_port != NULL &&
2819 !(datafellows & SSH_BUG_DYNAMIC_RPORT))
2820 c->listening_port = *allocated_listen_port;
2821 else
2822 c->listening_port = listen_port;
2819 success = 1; 2823 success = 1;
2820 } 2824 }
2821 if (success == 0) 2825 if (success == 0)
@@ -2924,12 +2928,14 @@ channel_rfwd_bind_host(const char *listen_host)
2924/* 2928/*
2925 * Initiate forwarding of connections to port "port" on remote host through 2929 * Initiate forwarding of connections to port "port" on remote host through
2926 * the secure channel to host:port from local side. 2930 * the secure channel to host:port from local side.
2931 * Returns handle (index) for updating the dynamic listen port with
2932 * channel_update_permitted_opens().
2927 */ 2933 */
2928int 2934int
2929channel_request_remote_forwarding(const char *listen_host, u_short listen_port, 2935channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
2930 const char *host_to_connect, u_short port_to_connect) 2936 const char *host_to_connect, u_short port_to_connect)
2931{ 2937{
2932 int type, success = 0; 2938 int type, success = 0, idx = -1;
2933 2939
2934 /* Send the forward request to the remote side. */ 2940 /* Send the forward request to the remote side. */
2935 if (compat20) { 2941 if (compat20) {
@@ -2968,12 +2974,12 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
2968 /* Record that connection to this host/port is permitted. */ 2974 /* Record that connection to this host/port is permitted. */
2969 permitted_opens = xrealloc(permitted_opens, 2975 permitted_opens = xrealloc(permitted_opens,
2970 num_permitted_opens + 1, sizeof(*permitted_opens)); 2976 num_permitted_opens + 1, sizeof(*permitted_opens));
2971 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); 2977 idx = num_permitted_opens++;
2972 permitted_opens[num_permitted_opens].port_to_connect = port_to_connect; 2978 permitted_opens[idx].host_to_connect = xstrdup(host_to_connect);
2973 permitted_opens[num_permitted_opens].listen_port = listen_port; 2979 permitted_opens[idx].port_to_connect = port_to_connect;
2974 num_permitted_opens++; 2980 permitted_opens[idx].listen_port = listen_port;
2975 } 2981 }
2976 return (success ? 0 : -1); 2982 return (idx);
2977} 2983}
2978 2984
2979/* 2985/*
@@ -3078,6 +3084,35 @@ channel_add_permitted_opens(char *host, int port)
3078 all_opens_permitted = 0; 3084 all_opens_permitted = 0;
3079} 3085}
3080 3086
3087/*
3088 * Update the listen port for a dynamic remote forward, after
3089 * the actual 'newport' has been allocated. If 'newport' < 0 is
3090 * passed then they entry will be invalidated.
3091 */
3092void
3093channel_update_permitted_opens(int idx, int newport)
3094{
3095 if (idx < 0 || idx >= num_permitted_opens) {
3096 debug("channel_update_permitted_opens: index out of range:"
3097 " %d num_permitted_opens %d", idx, num_permitted_opens);
3098 return;
3099 }
3100 debug("%s allowed port %d for forwarding to host %s port %d",
3101 newport > 0 ? "Updating" : "Removing",
3102 newport,
3103 permitted_opens[idx].host_to_connect,
3104 permitted_opens[idx].port_to_connect);
3105 if (newport >= 0) {
3106 permitted_opens[idx].listen_port =
3107 (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
3108 } else {
3109 permitted_opens[idx].listen_port = 0;
3110 permitted_opens[idx].port_to_connect = 0;
3111 xfree(permitted_opens[idx].host_to_connect);
3112 permitted_opens[idx].host_to_connect = NULL;
3113 }
3114}
3115
3081int 3116int
3082channel_add_adm_permitted_opens(char *host, int port) 3117channel_add_adm_permitted_opens(char *host, int port)
3083{ 3118{
diff --git a/channels.h b/channels.h
index 6f316c824..c1f01c48b 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.108 2011/09/23 00:22:04 dtucker Exp $ */ 1/* $OpenBSD: channels.h,v 1.109 2011/09/23 07:45:05 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -253,6 +253,7 @@ void channel_set_af(int af);
253void channel_permit_all_opens(void); 253void channel_permit_all_opens(void);
254void channel_add_permitted_opens(char *, int); 254void channel_add_permitted_opens(char *, int);
255int channel_add_adm_permitted_opens(char *, int); 255int channel_add_adm_permitted_opens(char *, int);
256void channel_update_permitted_opens(int, int);
256void channel_clear_permitted_opens(void); 257void channel_clear_permitted_opens(void);
257void channel_clear_adm_permitted_opens(void); 258void channel_clear_adm_permitted_opens(void);
258void channel_print_adm_permitted_opens(void); 259void channel_print_adm_permitted_opens(void);
diff --git a/compat.c b/compat.c
index df3541df7..0dc089fd6 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.c,v 1.78 2008/09/11 14:22:37 markus Exp $ */ 1/* $OpenBSD: compat.c,v 1.79 2011/09/23 07:45:05 markus Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -92,6 +92,7 @@ compat_datafellows(const char *version)
92 { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR }, 92 { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR },
93 { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, 93 { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
94 { "OpenSSH_4*", 0 }, 94 { "OpenSSH_4*", 0 },
95 { "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT},
95 { "OpenSSH*", SSH_NEW_OPENSSH }, 96 { "OpenSSH*", SSH_NEW_OPENSSH },
96 { "*MindTerm*", 0 }, 97 { "*MindTerm*", 0 },
97 { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 98 { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
diff --git a/compat.h b/compat.h
index 16cf282a7..3ae5d9c78 100644
--- a/compat.h
+++ b/compat.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.h,v 1.42 2008/09/11 14:22:37 markus Exp $ */ 1/* $OpenBSD: compat.h,v 1.43 2011/09/23 07:45:05 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@@ -58,6 +58,7 @@
58#define SSH_OLD_FORWARD_ADDR 0x01000000 58#define SSH_OLD_FORWARD_ADDR 0x01000000
59#define SSH_BUG_RFWD_ADDR 0x02000000 59#define SSH_BUG_RFWD_ADDR 0x02000000
60#define SSH_NEW_OPENSSH 0x04000000 60#define SSH_NEW_OPENSSH 0x04000000
61#define SSH_BUG_DYNAMIC_RPORT 0x08000000
61 62
62void enable_compat13(void); 63void enable_compat13(void);
63void enable_compat20(void); 64void enable_compat20(void);
diff --git a/mux.c b/mux.c
index 6b63d813b..52aec62b0 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.30 2011/09/09 22:46:44 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.31 2011/09/23 07:45:05 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -601,12 +601,16 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
601 buffer_put_int(&out, MUX_S_REMOTE_PORT); 601 buffer_put_int(&out, MUX_S_REMOTE_PORT);
602 buffer_put_int(&out, fctx->rid); 602 buffer_put_int(&out, fctx->rid);
603 buffer_put_int(&out, rfwd->allocated_port); 603 buffer_put_int(&out, rfwd->allocated_port);
604 channel_update_permitted_opens(rfwd->handle,
605 rfwd->allocated_port);
604 } else { 606 } else {
605 buffer_put_int(&out, MUX_S_OK); 607 buffer_put_int(&out, MUX_S_OK);
606 buffer_put_int(&out, fctx->rid); 608 buffer_put_int(&out, fctx->rid);
607 } 609 }
608 goto out; 610 goto out;
609 } else { 611 } else {
612 if (rfwd->listen_port == 0)
613 channel_update_permitted_opens(rfwd->handle, -1);
610 xasprintf(&failmsg, "remote port forwarding failed for " 614 xasprintf(&failmsg, "remote port forwarding failed for "
611 "listen port %d", rfwd->listen_port); 615 "listen port %d", rfwd->listen_port);
612 } 616 }
@@ -745,8 +749,9 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
745 } else { 749 } else {
746 struct mux_channel_confirm_ctx *fctx; 750 struct mux_channel_confirm_ctx *fctx;
747 751
748 if (channel_request_remote_forwarding(fwd.listen_host, 752 fwd.handle = channel_request_remote_forwarding(fwd.listen_host,
749 fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0) 753 fwd.listen_port, fwd.connect_host, fwd.connect_port);
754 if (fwd.handle < 0)
750 goto fail; 755 goto fail;
751 add_remote_forward(&options, &fwd); 756 add_remote_forward(&options, &fwd);
752 fctx = xcalloc(1, sizeof(*fctx)); 757 fctx = xcalloc(1, sizeof(*fctx));
@@ -781,7 +786,7 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
781 char *fwd_desc = NULL; 786 char *fwd_desc = NULL;
782 const char *error_reason = NULL; 787 const char *error_reason = NULL;
783 u_int ftype; 788 u_int ftype;
784 int i, ret = 0; 789 int i, listen_port, ret = 0;
785 790
786 fwd.listen_host = fwd.connect_host = NULL; 791 fwd.listen_host = fwd.connect_host = NULL;
787 if (buffer_get_int_ret(&ftype, m) != 0 || 792 if (buffer_get_int_ret(&ftype, m) != 0 ||
@@ -836,9 +841,13 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
836 /* 841 /*
837 * This shouldn't fail unless we confused the host/port 842 * This shouldn't fail unless we confused the host/port
838 * between options.remote_forwards and permitted_opens. 843 * between options.remote_forwards and permitted_opens.
844 * However, for dynamic allocated listen ports we need
845 * to lookup the actual listen port.
839 */ 846 */
847 listen_port = (fwd.listen_port == 0) ?
848 found_fwd->allocated_port : fwd.listen_port;
840 if (channel_request_rforward_cancel(fwd.listen_host, 849 if (channel_request_rforward_cancel(fwd.listen_host,
841 fwd.listen_port) == -1) 850 listen_port) == -1)
842 error_reason = "port not in permitted opens"; 851 error_reason = "port not in permitted opens";
843 } else { /* local and dynamic forwards */ 852 } else { /* local and dynamic forwards */
844 /* Ditto */ 853 /* Ditto */
diff --git a/readconf.c b/readconf.c
index 91dfa566f..097bb0515 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.193 2011/05/24 07:15:47 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.194 2011/09/23 07:45:05 markus 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
@@ -294,6 +294,7 @@ add_remote_forward(Options *options, const Forward *newfwd)
294 fwd->listen_port = newfwd->listen_port; 294 fwd->listen_port = newfwd->listen_port;
295 fwd->connect_host = newfwd->connect_host; 295 fwd->connect_host = newfwd->connect_host;
296 fwd->connect_port = newfwd->connect_port; 296 fwd->connect_port = newfwd->connect_port;
297 fwd->handle = newfwd->handle;
297 fwd->allocated_port = 0; 298 fwd->allocated_port = 0;
298} 299}
299 300
diff --git a/readconf.h b/readconf.h
index 5944cff93..be30ee0e1 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.90 2011/05/24 07:15:47 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.91 2011/09/23 07:45:05 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -24,6 +24,7 @@ typedef struct {
24 char *connect_host; /* Host to connect. */ 24 char *connect_host; /* Host to connect. */
25 int connect_port; /* Port to connect on connect_host. */ 25 int connect_port; /* Port to connect on connect_host. */
26 int allocated_port; /* Dynamically allocated listen port */ 26 int allocated_port; /* Dynamically allocated listen port */
27 int handle; /* Handle for dynamic listen ports */
27} Forward; 28} Forward;
28/* Data structure for representing option data. */ 29/* Data structure for representing option data. */
29 30
diff --git a/ssh.c b/ssh.c
index f437dec1c..9cee95969 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.365 2011/09/09 22:46:44 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.366 2011/09/23 07:45:05 markus 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
@@ -1021,11 +1021,17 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1021 debug("remote forward %s for: listen %d, connect %s:%d", 1021 debug("remote forward %s for: listen %d, connect %s:%d",
1022 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 1022 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1023 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); 1023 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
1024 if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) { 1024 if (rfwd->listen_port == 0) {
1025 rfwd->allocated_port = packet_get_int(); 1025 if (type == SSH2_MSG_REQUEST_SUCCESS) {
1026 logit("Allocated port %u for remote forward to %s:%d", 1026 rfwd->allocated_port = packet_get_int();
1027 rfwd->allocated_port, 1027 logit("Allocated port %u for remote forward to %s:%d",
1028 rfwd->connect_host, rfwd->connect_port); 1028 rfwd->allocated_port,
1029 rfwd->connect_host, rfwd->connect_port);
1030 channel_update_permitted_opens(rfwd->handle,
1031 rfwd->allocated_port);
1032 } else {
1033 channel_update_permitted_opens(rfwd->handle, -1);
1034 }
1029 } 1035 }
1030 1036
1031 if (type == SSH2_MSG_REQUEST_FAILURE) { 1037 if (type == SSH2_MSG_REQUEST_FAILURE) {
@@ -1117,19 +1123,22 @@ ssh_init_forwarding(void)
1117 options.remote_forwards[i].listen_port, 1123 options.remote_forwards[i].listen_port,
1118 options.remote_forwards[i].connect_host, 1124 options.remote_forwards[i].connect_host,
1119 options.remote_forwards[i].connect_port); 1125 options.remote_forwards[i].connect_port);
1120 if (channel_request_remote_forwarding( 1126 options.remote_forwards[i].handle =
1127 channel_request_remote_forwarding(
1121 options.remote_forwards[i].listen_host, 1128 options.remote_forwards[i].listen_host,
1122 options.remote_forwards[i].listen_port, 1129 options.remote_forwards[i].listen_port,
1123 options.remote_forwards[i].connect_host, 1130 options.remote_forwards[i].connect_host,
1124 options.remote_forwards[i].connect_port) < 0) { 1131 options.remote_forwards[i].connect_port);
1132 if (options.remote_forwards[i].handle < 0) {
1125 if (options.exit_on_forward_failure) 1133 if (options.exit_on_forward_failure)
1126 fatal("Could not request remote forwarding."); 1134 fatal("Could not request remote forwarding.");
1127 else 1135 else
1128 logit("Warning: Could not request remote " 1136 logit("Warning: Could not request remote "
1129 "forwarding."); 1137 "forwarding.");
1138 } else {
1139 client_register_global_confirm(ssh_confirm_remote_forward,
1140 &options.remote_forwards[i]);
1130 } 1141 }
1131 client_register_global_confirm(ssh_confirm_remote_forward,
1132 &options.remote_forwards[i]);
1133 } 1142 }
1134 1143
1135 /* Initiate tunnel forwarding. */ 1144 /* Initiate tunnel forwarding. */
diff --git a/version.h b/version.h
index 6a1acb3b6..0c0dfcb72 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
1/* $OpenBSD: version.h,v 1.62 2011/08/02 23:13:01 djm Exp $ */ 1/* $OpenBSD: version.h,v 1.63 2011/09/23 07:45:05 markus Exp $ */
2 2
3#define SSH_VERSION "OpenSSH_5.9" 3#define SSH_VERSION "OpenSSH_6.0-beta"
4 4
5#define SSH_PORTABLE "p1" 5#define SSH_PORTABLE "p1"
6#define SSH_RELEASE SSH_VERSION SSH_PORTABLE 6#define SSH_RELEASE SSH_VERSION SSH_PORTABLE