changeset 583:0d43d4ea4819

merge of '0adbc6745a5ada0b6780b0683209f5b26b1a335d' and 'a014a978f213e6ff424e7d10794ae426375f3191'
author Matt Johnston <matt@ucc.asn.au>
date Sun, 21 Mar 2010 06:07:22 +0000
parents 6b9d12477953 (current diff) 6cb1bd7be8b3 (diff)
children 0442c18da5c9
files
diffstat 6 files changed, 92 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/cli-runopts.c	Sun Mar 21 06:06:42 2010 +0000
+++ b/cli-runopts.c	Sun Mar 21 06:07:22 2010 +0000
@@ -71,11 +71,11 @@
 					"-A    Enable agent auth forwarding\n"
 #endif
 #ifdef ENABLE_CLI_LOCALTCPFWD
-					"-L <listenport:remotehost:remoteport> Local port forwarding\n"
+					"-L <[listenaddress:]listenport:remotehost:remoteport> Local port forwarding\n"
 					"-g    Allow remote hosts to connect to forwarded ports\n"
 #endif
 #ifdef ENABLE_CLI_REMOTETCPFWD
-					"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
+					"-R <[listenaddress:]listenport:remotehost:remoteport> Remote port forwarding\n"
 #endif
 					"-W <receive_window_buffer> (default %d, larger may be faster, max 1MB)\n"
 					"-K <keepalive>  (0 is never, default %d)\n"
@@ -628,13 +628,15 @@
 }
 
 #ifdef ENABLE_CLI_ANYTCPFWD
-/* Turn a "listenport:remoteaddr:remoteport" string into into a forwarding
+/* Turn a "[listenaddr:]listenport:remoteaddr:remoteport" string into into a forwarding
  * set, and add it to the forwarding list */
 static void addforward(const char* origstr, m_list *fwdlist) {
 
+	char *part1 = NULL, *part2 = NULL, *part3 = NULL, *part4 = NULL;
+	char * listenaddr = NULL;
 	char * listenport = NULL;
+	char * connectaddr = NULL;
 	char * connectport = NULL;
-	char * connectaddr = NULL;
 	struct TCPFwdEntry* newfwd = NULL;
 	char * str = NULL;
 
@@ -644,23 +646,41 @@
 	   is never free()d. */ 
 	str = m_strdup(origstr);
 
-	listenport = str;
+	part1 = str;
 
-	connectaddr = strchr(str, ':');
-	if (connectaddr == NULL) {
-		TRACE(("connectaddr == NULL"))
+	part2 = strchr(str, ':');
+	if (part2 == NULL) {
+		TRACE(("part2 == NULL"))
+		goto fail;
+	}
+	*part2 = '\0';
+	part2++;
+
+	part3 = strchr(part2, ':');
+	if (part3 == NULL) {
+		TRACE(("part3 == NULL"))
 		goto fail;
 	}
-	*connectaddr = '\0';
-	connectaddr++;
+	*part3 = '\0';
+	part3++;
+
+	part4 = strchr(part3, ':');
+	if (part4) {
+		*part4 = '\0';
+		part4++;
+	}
 
-	connectport = strchr(connectaddr, ':');
-	if (connectport == NULL) {
-		TRACE(("connectport == NULL"))
-		goto fail;
+	if (part4) {
+		listenaddr = part1;
+		listenport = part2;
+		connectaddr = part3;
+		connectport = part4;
+	} else {
+		listenaddr = NULL;
+		listenport = part1;
+		connectaddr = part2;
+		connectport = part3;
 	}
-	*connectport = '\0';
-	connectport++;
 
 	newfwd = m_malloc(sizeof(struct TCPFwdEntry));
 
@@ -676,6 +696,7 @@
 		goto fail;
 	}
 
+	newfwd->listenaddr = listenaddr;
 	newfwd->connectaddr = connectaddr;
 
 	if (newfwd->listenport > 65535) {
--- a/cli-tcpfwd.c	Sun Mar 21 06:06:42 2010 +0000
+++ b/cli-tcpfwd.c	Sun Mar 21 06:07:22 2010 +0000
@@ -45,7 +45,9 @@
 #endif
 
 #ifdef ENABLE_CLI_LOCALTCPFWD
-static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
+static int cli_localtcp(const char* listenaddr, 
+		unsigned int listenport, 
+		const char* remoteaddr,
 		unsigned int remoteport);
 static const struct ChanType cli_chan_tcplocal = {
 	1, /* sepfds */
@@ -66,11 +68,14 @@
 
 	for (iter = cli_opts.localfwds->first; iter; iter = iter->next) {
 		struct TCPFwdEntry * fwd = (struct TCPFwdEntry*)iter->item;
-		ret = cli_localtcp(fwd->listenport,
+		ret = cli_localtcp(
+				fwd->listenaddr,
+				fwd->listenport,
 				fwd->connectaddr,
 				fwd->connectport);
 		if (ret == DROPBEAR_FAILURE) {
-			dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
+			dropbear_log(LOG_WARNING, "Failed local port forward %s:%d:%s:%d",
+					fwd->listenaddr,
 					fwd->listenport,
 					fwd->connectaddr,
 					fwd->connectport);
@@ -80,7 +85,9 @@
 
 }
 
-static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
+static int cli_localtcp(const char* listenaddr, 
+		unsigned int listenport, 
+		const char* remoteaddr,
 		unsigned int remoteport) {
 
 	struct TCPListener* tcpinfo = NULL;
@@ -94,10 +101,17 @@
 	tcpinfo->sendaddr = m_strdup(remoteaddr);
 	tcpinfo->sendport = remoteport;
 
-	if (opts.listen_fwd_all) {
-		tcpinfo->listenaddr = m_strdup("");
-	} else {
-		tcpinfo->listenaddr = m_strdup("localhost");
+	if (listenaddr)
+	{
+		tcpinfo->listenaddr = m_strdup(listenaddr);
+	}
+	else
+	{
+		if (opts.listen_fwd_all) {
+			tcpinfo->listenaddr = m_strdup("");
+		} else {
+			tcpinfo->listenaddr = m_strdup("localhost");
+		}
 	}
 	tcpinfo->listenport = listenport;
 
@@ -115,7 +129,7 @@
 #endif /* ENABLE_CLI_LOCALTCPFWD */
 
 #ifdef  ENABLE_CLI_REMOTETCPFWD
-static void send_msg_global_request_remotetcp(int port) {
+static void send_msg_global_request_remotetcp(const char *addr, int port) {
 
 	char* listenspec = NULL;
 	TRACE(("enter send_msg_global_request_remotetcp"))
@@ -124,13 +138,7 @@
 	buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
 	buf_putstring(ses.writepayload, "tcpip-forward", 13);
 	buf_putbyte(ses.writepayload, 1); /* want_reply */
-	if (opts.listen_fwd_all) {
-		listenspec = "";
-	} else {
-		listenspec = "localhost";
-	}
-	/* TODO: IPv6? */;
-	buf_putstring(ses.writepayload, listenspec, strlen(listenspec));
+	buf_putstring(ses.writepayload, addr, strlen(addr));
 	buf_putint(ses.writepayload, port);
 
 	encrypt_packet();
@@ -173,7 +181,17 @@
 
 	for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
 		struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item;
-		send_msg_global_request_remotetcp(fwd->listenport);
+		if (!fwd->listenaddr)
+		{
+			// we store the addresses so that we can compare them
+			// when the server sends them back
+			if (opts.listen_fwd_all) {
+				fwd->listenaddr = m_strdup("");
+			} else {
+				fwd->listenaddr = m_strdup("localhost");
+			}
+		}
+		send_msg_global_request_remotetcp(fwd->listenaddr, fwd->listenport);
 	}
 
 	TRACE(("leave setup_remotetcp"))
@@ -181,6 +199,7 @@
 
 static int newtcpforwarded(struct Channel * channel) {
 
+    char *origaddr = NULL;
 	unsigned int origport;
 	m_list_elem * iter = NULL;
 	struct TCPFwdEntry *fwd;
@@ -188,23 +207,23 @@
 	int sock;
 	int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
 
-	/* We don't care what address they connected to */
-	buf_eatstring(ses.payload);
-
+	origaddr = buf_getstring(ses.payload, NULL);
 	origport = buf_getint(ses.payload);
 
 	/* Find which port corresponds */
 	for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) {
 		fwd = (struct TCPFwdEntry*)iter->item;
-		if (origport == fwd->listenport) {
+		if (origport == fwd->listenport
+				&& (strcmp(origaddr, fwd->listenaddr) == 0)) {
 			break;
 		}
 	}
 
 	if (iter == NULL) {
 		/* We didn't request forwarding on that port */
-		dropbear_log(LOG_INFO, "Server send unrequested port, from port %d", 
-										origport);
+        cleantext(origaddr);
+		dropbear_log(LOG_INFO, "Server sent unrequested forward from \"%s:%d\"", 
+                origaddr, origport);
 		goto out;
 	}
 	
@@ -226,6 +245,7 @@
 	err = SSH_OPEN_IN_PROGRESS;
 
 out:
+	m_free(origaddr);
 	TRACE(("leave newtcpdirect: err %d", err))
 	return err;
 }
--- a/svr-chansession.c	Sun Mar 21 06:06:42 2010 +0000
+++ b/svr-chansession.c	Sun Mar 21 06:07:22 2010 +0000
@@ -33,7 +33,6 @@
 #include "termcodes.h"
 #include "ssh.h"
 #include "random.h"
-#include "utmp.h"
 #include "x11fwd.h"
 #include "agentfwd.h"
 #include "runopts.h"
--- a/svr-tcpfwd.c	Sun Mar 21 06:06:42 2010 +0000
+++ b/svr-tcpfwd.c	Sun Mar 21 06:07:22 2010 +0000
@@ -206,11 +206,20 @@
 	tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
 	tcpinfo->sendaddr = NULL;
 	tcpinfo->sendport = 0;
-	tcpinfo->listenaddr = bindaddr;
 	tcpinfo->listenport = port;
 	tcpinfo->chantype = &svr_chan_tcpremote;
 	tcpinfo->tcp_type = forwarded;
 
+	if (!opts.listen_fwd_all 
+			|| (strcmp(tcpinfo->listenaddr, "localhost") == 0) ) {
+        // NULL means "localhost only"
+        tcpinfo->listenaddr = NULL;
+	}
+    else
+    {
+        tcpinfo->listenaddr = bindaddr;
+    }
+
 	ret = listen_tcpfwd(tcpinfo);
 
 out:
--- a/tcp-accept.c	Sun Mar 21 06:06:42 2010 +0000
+++ b/tcp-accept.c	Sun Mar 21 06:07:22 2010 +0000
@@ -104,21 +104,13 @@
 	struct Listener *listener = NULL;
 	int nsocks;
 	char* errstring = NULL;
-	/* listen_spec = NULL indicates localhost */
-	const char* listen_spec = NULL;
 
 	TRACE(("enter listen_tcpfwd"))
 
 	/* first we try to bind, so don't need to do so much cleanup on failure */
 	snprintf(portstring, sizeof(portstring), "%d", tcpinfo->listenport);
 
-	/* a listenaddr of "" will indicate all interfaces */
-	if (opts.listen_fwd_all 
-			&& (strcmp(tcpinfo->listenaddr, "localhost") != 0) ) {
-		listen_spec = tcpinfo->listenaddr;
-	}
-
-	nsocks = dropbear_listen(listen_spec, portstring, socks, 
+	nsocks = dropbear_listen(tcpinfo->listenaddr, portstring, socks, 
 			DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd);
 	if (nsocks < 0) {
 		dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring);
--- a/tcpfwd.h	Sun Mar 21 06:06:42 2010 +0000
+++ b/tcpfwd.h	Sun Mar 21 06:07:22 2010 +0000
@@ -48,6 +48,7 @@
 struct TCPFwdEntry {
 	const unsigned char* connectaddr;
 	unsigned int connectport;
+	const unsigned char* listenaddr;
 	unsigned int listenport;
 	unsigned int have_reply; /* is set to 1 after a reply has been received
 								when setting up the forwarding */