summaryrefslogtreecommitdiffhomepage
path: root/cli-tcpfwd.c
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2010-02-27 11:51:19 +0000
committerMatt Johnston <matt@ucc.asn.au>2010-02-27 11:51:19 +0000
commit3b078445482f42dabfe4922e67a958dc607b166f (patch)
tree68fff0d4c9c34c7ace28285f82e711a8fad3a8fb /cli-tcpfwd.c
parent8174a2f27b9539511eb1f432df76856222cdfc1a (diff)
- tcpfwd bindaddr support against trunk. needs merging.
--HG-- extra : convert_revision : 658fd03abd21e0da7c4c89b9fff9dc693c72daae
Diffstat (limited to 'cli-tcpfwd.c')
-rw-r--r--cli-tcpfwd.c66
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;
}