diff options
author | Matt Johnston <matt@ucc.asn.au> | 2010-02-27 11:51:19 +0000 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2010-02-27 11:51:19 +0000 |
commit | 3b078445482f42dabfe4922e67a958dc607b166f (patch) | |
tree | 68fff0d4c9c34c7ace28285f82e711a8fad3a8fb /cli-tcpfwd.c | |
parent | 8174a2f27b9539511eb1f432df76856222cdfc1a (diff) |
- tcpfwd bindaddr support against trunk. needs merging.
--HG--
extra : convert_revision : 658fd03abd21e0da7c4c89b9fff9dc693c72daae
Diffstat (limited to 'cli-tcpfwd.c')
-rw-r--r-- | cli-tcpfwd.c | 66 |
1 files changed, 43 insertions, 23 deletions
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; } |