summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2010-03-21 06:07:22 +0000
committerMatt Johnston <matt@ucc.asn.au>2010-03-21 06:07:22 +0000
commiteabfd803c92dfe202f282634c011c6bfff3da047 (patch)
tree911288198c15a55f27251488f3e77dcd0fe1bdde
parent07b764ead6d89337a677e8f14b6a90205bfd3199 (diff)
parent8bad5d61fde47eb380872b20aa3cfd1c49b14e83 (diff)
merge of '0adbc6745a5ada0b6780b0683209f5b26b1a335d'
and 'a014a978f213e6ff424e7d10794ae426375f3191' --HG-- extra : convert_revision : eecc64377b2b55ba1d9e77855f4323cdc9f8e1c6
-rw-r--r--cli-runopts.c51
-rw-r--r--cli-tcpfwd.c66
-rw-r--r--svr-chansession.c1
-rw-r--r--svr-tcpfwd.c11
-rw-r--r--tcp-accept.c10
-rw-r--r--tcpfwd.h1
6 files changed, 91 insertions, 49 deletions
diff --git a/cli-runopts.c b/cli-runopts.c
index aedd4b7..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 <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 @@ 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,41 @@ 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 +696,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/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"
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 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 */