From 85288d7b6174b78af903fb55593bccd0014e5f30 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 24 Feb 2010 16:13:15 +0000 Subject: - Progress for allowing specifying a listenaddr for tcp forwards --HG-- extra : convert_revision : 48fdaa8706d1acda35e9d564adc9a1fbc96c18c8 --- cli-runopts.c | 47 +++++++++++++++++++++++++++++++------------ cli-tcpfwd.c | 64 +++++++++++++++++++++++++++++++++++++++-------------------- svr-tcpfwd.c | 11 +++++++++- tcp-accept.c | 10 +--------- tcpfwd.h | 1 + 5 files changed, 88 insertions(+), 45 deletions(-) diff --git a/cli-runopts.c b/cli-runopts.c index 9c10fc3..da9dd1a 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -564,13 +564,15 @@ static void fill_own_user() { } #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, struct TCPFwdList** fwdlist) { + char *part1 = NULL, *part2 = NULL, *part3 = NULL, *part4 = NULL; + char * listenaddr = NULL; char * listenport = NULL; - char * connectport = NULL; char * connectaddr = NULL; + char * connectport = NULL; struct TCPFwdList* newfwd = NULL; char * str = NULL; @@ -580,23 +582,41 @@ static void addforward(const char* origstr, struct TCPFwdList** fwdlist) { 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; } - *connectaddr = '\0'; - connectaddr++; + *part2 = '\0'; + part2++; - connectport = strchr(connectaddr, ':'); - if (connectport == NULL) { - TRACE(("connectport == NULL")) + part3 = strchr(part2, ':'); + if (part3 == NULL) { + TRACE(("part3 == NULL")) goto fail; } - *connectport = '\0'; - connectport++; + *part3 = '\0'; + part3++; + + part4 = strchr(part3, ':'); + if (part4) { + *part4 = '\0'; + part4++; + } + + if (part4) { + listenaddr = part1; + listenport = part2; + connectaddr = part3; + connectport = part4; + } else { + listenaddr = NULL; + listenport = part1; + connectaddr = part2; + connectport = part3; + } newfwd = (struct TCPFwdList*)m_malloc(sizeof(struct TCPFwdList)); @@ -612,6 +632,7 @@ static void addforward(const char* origstr, struct TCPFwdList** fwdlist) { goto fail; } + newfwd->listenaddr = listenaddr; newfwd->connectaddr = connectaddr; if (newfwd->listenport > 65535) { diff --git a/cli-tcpfwd.c b/cli-tcpfwd.c index 0e60090..0751fb2 100644 --- a/cli-tcpfwd.c +++ b/cli-tcpfwd.c @@ -45,7 +45,9 @@ const struct ChanType cli_chan_tcpremote = { #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 */ @@ -69,11 +71,14 @@ void setup_localtcp() { } while (cli_opts.localfwds != NULL) { - ret = cli_localtcp(cli_opts.localfwds->listenport, + ret = cli_localtcp( + cli_opts.localfwds->listenaddr, + cli_opts.localfwds->listenport, cli_opts.localfwds->connectaddr, cli_opts.localfwds->connectport); if (ret == DROPBEAR_FAILURE) { dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d", + cli_opts.localfwds->listenaddr, cli_opts.localfwds->listenport, cli_opts.localfwds->connectaddr, cli_opts.localfwds->connectport); @@ -85,7 +90,9 @@ void setup_localtcp() { } -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; @@ -99,10 +106,17 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr, 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; @@ -120,7 +134,7 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr, #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")) @@ -129,13 +143,7 @@ static void send_msg_global_request_remotetcp(int port) { 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(); @@ -192,7 +200,17 @@ void setup_remotetcp() { iter = cli_opts.remotefwds; while (iter != NULL) { - send_msg_global_request_remotetcp(iter->listenport); + if (!iter->listenaddr) + { + // we store the addresses so that we can compare them + // when the server sends them back + if (opts.listen_fwd_all) { + iter->listenaddr = m_strdup(""); + } else { + iter->listenaddr = m_strdup("localhost"); + } + } + send_msg_global_request_remotetcp(iter->listenaddr, iter->listenport); iter = iter->next; } TRACE(("leave setup_remotetcp")) @@ -200,22 +218,22 @@ void setup_remotetcp() { static int newtcpforwarded(struct Channel * channel) { + char *origaddr = NULL; unsigned int origport; struct TCPFwdList * iter = NULL; char portstring[NI_MAXSERV]; 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 */ iter = cli_opts.remotefwds; while (iter != NULL) { - if (origport == iter->listenport) { + if (origport == iter->listenport + && (strcmp(origaddr, iter->listenaddr) == 0)) { break; } iter = iter->next; @@ -223,8 +241,9 @@ static int newtcpforwarded(struct Channel * channel) { 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; } @@ -246,6 +265,7 @@ static int newtcpforwarded(struct Channel * channel) { err = SSH_OPEN_IN_PROGRESS; out: + m_free(origaddr); TRACE(("leave newtcpdirect: err %d", err)) return err; } diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c index a55361b..7b37449 100644 --- a/svr-tcpfwd.c +++ b/svr-tcpfwd.c @@ -206,11 +206,20 @@ static int svr_remotetcpreq() { 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: diff --git a/tcp-accept.c b/tcp-accept.c index 7457c9b..cf0aa7a 100644 --- a/tcp-accept.c +++ b/tcp-accept.c @@ -104,21 +104,13 @@ int listen_tcpfwd(struct TCPListener* tcpinfo) { 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); diff --git a/tcpfwd.h b/tcpfwd.h index 251612e..25aa366 100644 --- a/tcpfwd.h +++ b/tcpfwd.h @@ -48,6 +48,7 @@ struct TCPFwdList { 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 */ -- cgit v1.2.3 From 3b078445482f42dabfe4922e67a958dc607b166f Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Sat, 27 Feb 2010 11:51:19 +0000 Subject: - tcpfwd bindaddr support against trunk. needs merging. --HG-- extra : convert_revision : 658fd03abd21e0da7c4c89b9fff9dc693c72daae --- cli-runopts.c | 49 ++++++++++++++++++++++++++++++++------------ cli-tcpfwd.c | 66 ++++++++++++++++++++++++++++++++++++++--------------------- tcpfwd.h | 1 + 3 files changed, 80 insertions(+), 36 deletions(-) diff --git a/cli-runopts.c b/cli-runopts.c index aedd4b7..ddd52b5 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -628,13 +628,15 @@ static void fill_own_user() { } #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 * connectport = NULL; char * connectaddr = NULL; + char * connectport = NULL; struct TCPFwdEntry* newfwd = NULL; char * str = NULL; @@ -644,23 +646,43 @@ static void addforward(const char* origstr, m_list *fwdlist) { 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; } - *connectaddr = '\0'; - connectaddr++; + *part2 = '\0'; + part2++; - connectport = strchr(connectaddr, ':'); - if (connectport == NULL) { - TRACE(("connectport == NULL")) + part3 = strchr(part2, ':'); + if (part3 == NULL) { + TRACE(("part3 == NULL")) goto fail; } - *connectport = '\0'; - connectport++; + *part3 = '\0'; + part3++; + + part4 = strchr(part3, ':'); + if (part4) { + *part4 = '\0'; + part4++; + } + + if (part4) { + listenaddr = part1; + listenport = part2; + connectaddr = part3; + connectport = part4; + } else { + listenaddr = NULL; + listenport = part1; + connectaddr = part2; + connectport = part3; + } + + } newfwd = m_malloc(sizeof(struct TCPFwdEntry)); @@ -676,6 +698,7 @@ static void addforward(const char* origstr, m_list *fwdlist) { goto fail; } + newfwd->listenaddr = listenaddr; newfwd->connectaddr = connectaddr; if (newfwd->listenport > 65535) { diff --git a/cli-tcpfwd.c b/cli-tcpfwd.c index 0242654..63eb70e 100644 --- a/cli-tcpfwd.c +++ b/cli-tcpfwd.c @@ -45,7 +45,9 @@ const struct ChanType cli_chan_tcpremote = { #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 @@ void setup_localtcp() { 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 @@ void setup_localtcp() { } -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 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr, 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 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr, #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 @@ static void send_msg_global_request_remotetcp(int port) { 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 @@ void setup_remotetcp() { 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 @@ void setup_remotetcp() { static int newtcpforwarded(struct Channel * channel) { + char *origaddr = NULL; unsigned int origport; m_list_elem * iter = NULL; struct TCPFwdEntry *fwd; @@ -188,23 +207,23 @@ static int newtcpforwarded(struct Channel * channel) { 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 @@ static int newtcpforwarded(struct Channel * channel) { err = SSH_OPEN_IN_PROGRESS; out: + m_free(origaddr); TRACE(("leave newtcpdirect: err %d", err)) return err; } diff --git a/tcpfwd.h b/tcpfwd.h index 34da314..c33e853 100644 --- a/tcpfwd.h +++ b/tcpfwd.h @@ -48,6 +48,7 @@ struct TCPListener { 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 */ -- cgit v1.2.3 From 9f42a75ef6b5f90844be647c57625c4a56a996bb Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Sat, 27 Feb 2010 12:15:27 +0000 Subject: - fixes for listenaddr --HG-- extra : convert_revision : 9eebe96bb7c26c4c09c77a2e89a67a7332abcd49 --- cli-runopts.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cli-runopts.c b/cli-runopts.c index ddd52b5..e874dc2 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -71,11 +71,11 @@ static void printhelp() { "-A Enable agent auth forwarding\n" #endif #ifdef ENABLE_CLI_LOCALTCPFWD - "-L 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 Remote port forwarding\n" + "-R <[listenaddress:]listenport:remotehost:remoteport> Remote port forwarding\n" #endif "-W (default %d, larger may be faster, max 1MB)\n" "-K (0 is never, default %d)\n" @@ -682,8 +682,6 @@ static void addforward(const char* origstr, m_list *fwdlist) { connectport = part3; } - } - newfwd = m_malloc(sizeof(struct TCPFwdEntry)); /* Now we check the ports - note that the port ints are unsigned, -- cgit v1.2.3 From 8bad5d61fde47eb380872b20aa3cfd1c49b14e83 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Thu, 4 Mar 2010 14:50:19 +0000 Subject: don't #include "utmp.h" --HG-- extra : convert_revision : a014a978f213e6ff424e7d10794ae426375f3191 --- svr-chansession.c | 1 - 1 file changed, 1 deletion(-) diff --git a/svr-chansession.c b/svr-chansession.c index 5ecc57f..24cdc68 100644 --- a/svr-chansession.c +++ b/svr-chansession.c @@ -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" -- cgit v1.2.3