From 1984aabc950904a9717735ae82b0bbf7d89d3478 Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Wed, 9 May 2012 21:09:34 +0800
Subject: [PATCH] Server shouldn't return "localhost" in response to -R forward
 connections if that wasn't what the client requested.

---
 svr-tcpfwd.c | 17 ++++++++++-------
 tcp-accept.c |  3 ++-
 tcpfwd.h     |  2 ++
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c
index e1f3a314..0d26cdc6 100644
--- a/svr-tcpfwd.c
+++ b/svr-tcpfwd.c
@@ -172,14 +172,14 @@ out:
 static int svr_remotetcpreq() {
 
 	int ret = DROPBEAR_FAILURE;
-	unsigned char * bindaddr = NULL;
+	unsigned char * request_addr = NULL;
 	unsigned int addrlen;
 	struct TCPListener *tcpinfo = NULL;
 	unsigned int port;
 
 	TRACE(("enter remotetcpreq"))
 
-	bindaddr = buf_getstring(ses.payload, &addrlen);
+	request_addr = buf_getstring(ses.payload, &addrlen);
 	if (addrlen > MAX_IP_LEN) {
 		TRACE(("addr len too long: %d", addrlen))
 		goto out;
@@ -209,12 +209,15 @@ static int svr_remotetcpreq() {
 	tcpinfo->chantype = &svr_chan_tcpremote;
 	tcpinfo->tcp_type = forwarded;
 
-	if (!opts.listen_fwd_all || (strcmp(bindaddr, "localhost") == 0) ) {
+	tcpinfo->request_listenaddr = request_addr;
+	if (!opts.listen_fwd_all || (strcmp(request_addr, "localhost") == 0) ) {
         // NULL means "localhost only"
-		m_free(bindaddr);
-		bindaddr = NULL;
+		tcpinfo->listenaddr = NULL;
+	}
+	else
+	{
+		tcpinfo->listenaddr = request_addr;
 	}
-	tcpinfo->listenaddr = bindaddr;
 
 	ret = listen_tcpfwd(tcpinfo);
 
@@ -222,7 +225,7 @@ out:
 	if (ret == DROPBEAR_FAILURE) {
 		/* we only free it if a listener wasn't created, since the listener
 		 * has to remember it if it's to be cancelled */
-		m_free(bindaddr);
+		m_free(request_addr);
 		m_free(tcpinfo);
 	}
 	TRACE(("leave remotetcpreq"))
diff --git a/tcp-accept.c b/tcp-accept.c
index c133535e..bb7c5e36 100644
--- a/tcp-accept.c
+++ b/tcp-accept.c
@@ -40,6 +40,7 @@ static void cleanup_tcp(struct Listener *listener) {
 
 	m_free(tcpinfo->sendaddr);
 	m_free(tcpinfo->listenaddr);
+	m_free(tcpinfo->request_listenaddr);
 	m_free(tcpinfo);
 }
 
@@ -78,7 +79,7 @@ static void tcp_acceptor(struct Listener *listener, int sock) {
 			dropbear_assert(tcpinfo->tcp_type == forwarded);
 			/* "forwarded-tcpip" */
 			/* address that was connected, port that was connected */
-			addr = tcpinfo->listenaddr;
+			addr = tcpinfo->request_listenaddr;
 			port = tcpinfo->listenport;
 		}
 
diff --git a/tcpfwd.h b/tcpfwd.h
index c33e8531..749e1cbe 100644
--- a/tcpfwd.h
+++ b/tcpfwd.h
@@ -39,6 +39,8 @@ struct TCPListener {
 	 * localhost, or a normal interface name. */
 	unsigned char *listenaddr;
 	unsigned int listenport;
+	/* The address that the remote host asked to listen on */
+	unsigned char *request_listenaddr;;
 
 	const struct ChanType *chantype;
 	enum {direct, forwarded} tcp_type;
-- 
GitLab