mirror of
https://github.com/clearml/dropbear
synced 2025-04-07 22:24:21 +00:00
- Progress for allowing specifying a listenaddr for tcp forwards
--HG-- extra : convert_revision : 48fdaa8706d1acda35e9d564adc9a1fbc96c18c8
This commit is contained in:
parent
3dbc707820
commit
85288d7b61
@ -564,13 +564,15 @@ static void fill_own_user() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_CLI_ANYTCPFWD
|
#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 */
|
* set, and add it to the forwarding list */
|
||||||
static void addforward(const char* origstr, struct TCPFwdList** fwdlist) {
|
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 * listenport = NULL;
|
||||||
char * connectport = NULL;
|
|
||||||
char * connectaddr = NULL;
|
char * connectaddr = NULL;
|
||||||
|
char * connectport = NULL;
|
||||||
struct TCPFwdList* newfwd = NULL;
|
struct TCPFwdList* newfwd = NULL;
|
||||||
char * str = NULL;
|
char * str = NULL;
|
||||||
|
|
||||||
@ -580,23 +582,41 @@ static void addforward(const char* origstr, struct TCPFwdList** fwdlist) {
|
|||||||
is never free()d. */
|
is never free()d. */
|
||||||
str = m_strdup(origstr);
|
str = m_strdup(origstr);
|
||||||
|
|
||||||
listenport = str;
|
part1 = str;
|
||||||
|
|
||||||
connectaddr = strchr(str, ':');
|
part2 = strchr(str, ':');
|
||||||
if (connectaddr == NULL) {
|
if (part2 == NULL) {
|
||||||
TRACE(("connectaddr == NULL"))
|
TRACE(("part2 == NULL"))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
*connectaddr = '\0';
|
*part2 = '\0';
|
||||||
connectaddr++;
|
part2++;
|
||||||
|
|
||||||
connectport = strchr(connectaddr, ':');
|
part3 = strchr(part2, ':');
|
||||||
if (connectport == NULL) {
|
if (part3 == NULL) {
|
||||||
TRACE(("connectport == NULL"))
|
TRACE(("part3 == NULL"))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
*connectport = '\0';
|
*part3 = '\0';
|
||||||
connectport++;
|
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));
|
newfwd = (struct TCPFwdList*)m_malloc(sizeof(struct TCPFwdList));
|
||||||
|
|
||||||
@ -612,6 +632,7 @@ static void addforward(const char* origstr, struct TCPFwdList** fwdlist) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newfwd->listenaddr = listenaddr;
|
||||||
newfwd->connectaddr = connectaddr;
|
newfwd->connectaddr = connectaddr;
|
||||||
|
|
||||||
if (newfwd->listenport > 65535) {
|
if (newfwd->listenport > 65535) {
|
||||||
|
64
cli-tcpfwd.c
64
cli-tcpfwd.c
@ -45,7 +45,9 @@ const struct ChanType cli_chan_tcpremote = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
#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);
|
unsigned int remoteport);
|
||||||
static const struct ChanType cli_chan_tcplocal = {
|
static const struct ChanType cli_chan_tcplocal = {
|
||||||
1, /* sepfds */
|
1, /* sepfds */
|
||||||
@ -69,11 +71,14 @@ void setup_localtcp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (cli_opts.localfwds != NULL) {
|
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->connectaddr,
|
||||||
cli_opts.localfwds->connectport);
|
cli_opts.localfwds->connectport);
|
||||||
if (ret == DROPBEAR_FAILURE) {
|
if (ret == DROPBEAR_FAILURE) {
|
||||||
dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
|
dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
|
||||||
|
cli_opts.localfwds->listenaddr,
|
||||||
cli_opts.localfwds->listenport,
|
cli_opts.localfwds->listenport,
|
||||||
cli_opts.localfwds->connectaddr,
|
cli_opts.localfwds->connectaddr,
|
||||||
cli_opts.localfwds->connectport);
|
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) {
|
unsigned int remoteport) {
|
||||||
|
|
||||||
struct TCPListener* tcpinfo = NULL;
|
struct TCPListener* tcpinfo = NULL;
|
||||||
@ -99,10 +106,17 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
|
|||||||
tcpinfo->sendaddr = m_strdup(remoteaddr);
|
tcpinfo->sendaddr = m_strdup(remoteaddr);
|
||||||
tcpinfo->sendport = remoteport;
|
tcpinfo->sendport = remoteport;
|
||||||
|
|
||||||
if (opts.listen_fwd_all) {
|
if (listenaddr)
|
||||||
tcpinfo->listenaddr = m_strdup("");
|
{
|
||||||
} else {
|
tcpinfo->listenaddr = m_strdup(listenaddr);
|
||||||
tcpinfo->listenaddr = m_strdup("localhost");
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (opts.listen_fwd_all) {
|
||||||
|
tcpinfo->listenaddr = m_strdup("");
|
||||||
|
} else {
|
||||||
|
tcpinfo->listenaddr = m_strdup("localhost");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tcpinfo->listenport = listenport;
|
tcpinfo->listenport = listenport;
|
||||||
|
|
||||||
@ -120,7 +134,7 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
|
|||||||
#endif /* ENABLE_CLI_LOCALTCPFWD */
|
#endif /* ENABLE_CLI_LOCALTCPFWD */
|
||||||
|
|
||||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
#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;
|
char* listenspec = NULL;
|
||||||
TRACE(("enter send_msg_global_request_remotetcp"))
|
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_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
|
||||||
buf_putstring(ses.writepayload, "tcpip-forward", 13);
|
buf_putstring(ses.writepayload, "tcpip-forward", 13);
|
||||||
buf_putbyte(ses.writepayload, 1); /* want_reply */
|
buf_putbyte(ses.writepayload, 1); /* want_reply */
|
||||||
if (opts.listen_fwd_all) {
|
buf_putstring(ses.writepayload, addr, strlen(addr));
|
||||||
listenspec = "";
|
|
||||||
} else {
|
|
||||||
listenspec = "localhost";
|
|
||||||
}
|
|
||||||
/* TODO: IPv6? */;
|
|
||||||
buf_putstring(ses.writepayload, listenspec, strlen(listenspec));
|
|
||||||
buf_putint(ses.writepayload, port);
|
buf_putint(ses.writepayload, port);
|
||||||
|
|
||||||
encrypt_packet();
|
encrypt_packet();
|
||||||
@ -192,7 +200,17 @@ void setup_remotetcp() {
|
|||||||
iter = cli_opts.remotefwds;
|
iter = cli_opts.remotefwds;
|
||||||
|
|
||||||
while (iter != NULL) {
|
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;
|
iter = iter->next;
|
||||||
}
|
}
|
||||||
TRACE(("leave setup_remotetcp"))
|
TRACE(("leave setup_remotetcp"))
|
||||||
@ -200,22 +218,22 @@ void setup_remotetcp() {
|
|||||||
|
|
||||||
static int newtcpforwarded(struct Channel * channel) {
|
static int newtcpforwarded(struct Channel * channel) {
|
||||||
|
|
||||||
|
char *origaddr = NULL;
|
||||||
unsigned int origport;
|
unsigned int origport;
|
||||||
struct TCPFwdList * iter = NULL;
|
struct TCPFwdList * iter = NULL;
|
||||||
char portstring[NI_MAXSERV];
|
char portstring[NI_MAXSERV];
|
||||||
int sock;
|
int sock;
|
||||||
int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
|
int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
|
||||||
|
|
||||||
/* We don't care what address they connected to */
|
origaddr = buf_getstring(ses.payload, NULL);
|
||||||
buf_eatstring(ses.payload);
|
|
||||||
|
|
||||||
origport = buf_getint(ses.payload);
|
origport = buf_getint(ses.payload);
|
||||||
|
|
||||||
/* Find which port corresponds */
|
/* Find which port corresponds */
|
||||||
iter = cli_opts.remotefwds;
|
iter = cli_opts.remotefwds;
|
||||||
|
|
||||||
while (iter != NULL) {
|
while (iter != NULL) {
|
||||||
if (origport == iter->listenport) {
|
if (origport == iter->listenport
|
||||||
|
&& (strcmp(origaddr, iter->listenaddr) == 0)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
iter = iter->next;
|
iter = iter->next;
|
||||||
@ -223,8 +241,9 @@ static int newtcpforwarded(struct Channel * channel) {
|
|||||||
|
|
||||||
if (iter == NULL) {
|
if (iter == NULL) {
|
||||||
/* We didn't request forwarding on that port */
|
/* We didn't request forwarding on that port */
|
||||||
dropbear_log(LOG_INFO, "Server send unrequested port, from port %d",
|
cleantext(origaddr);
|
||||||
origport);
|
dropbear_log(LOG_INFO, "Server sent unrequested forward from \"%s:%d\"",
|
||||||
|
origaddr, origport);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,6 +265,7 @@ static int newtcpforwarded(struct Channel * channel) {
|
|||||||
err = SSH_OPEN_IN_PROGRESS;
|
err = SSH_OPEN_IN_PROGRESS;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
m_free(origaddr);
|
||||||
TRACE(("leave newtcpdirect: err %d", err))
|
TRACE(("leave newtcpdirect: err %d", err))
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
11
svr-tcpfwd.c
11
svr-tcpfwd.c
@ -206,11 +206,20 @@ static int svr_remotetcpreq() {
|
|||||||
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
|
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
|
||||||
tcpinfo->sendaddr = NULL;
|
tcpinfo->sendaddr = NULL;
|
||||||
tcpinfo->sendport = 0;
|
tcpinfo->sendport = 0;
|
||||||
tcpinfo->listenaddr = bindaddr;
|
|
||||||
tcpinfo->listenport = port;
|
tcpinfo->listenport = port;
|
||||||
tcpinfo->chantype = &svr_chan_tcpremote;
|
tcpinfo->chantype = &svr_chan_tcpremote;
|
||||||
tcpinfo->tcp_type = forwarded;
|
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);
|
ret = listen_tcpfwd(tcpinfo);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
10
tcp-accept.c
10
tcp-accept.c
@ -104,21 +104,13 @@ int listen_tcpfwd(struct TCPListener* tcpinfo) {
|
|||||||
struct Listener *listener = NULL;
|
struct Listener *listener = NULL;
|
||||||
int nsocks;
|
int nsocks;
|
||||||
char* errstring = NULL;
|
char* errstring = NULL;
|
||||||
/* listen_spec = NULL indicates localhost */
|
|
||||||
const char* listen_spec = NULL;
|
|
||||||
|
|
||||||
TRACE(("enter listen_tcpfwd"))
|
TRACE(("enter listen_tcpfwd"))
|
||||||
|
|
||||||
/* first we try to bind, so don't need to do so much cleanup on failure */
|
/* first we try to bind, so don't need to do so much cleanup on failure */
|
||||||
snprintf(portstring, sizeof(portstring), "%d", tcpinfo->listenport);
|
snprintf(portstring, sizeof(portstring), "%d", tcpinfo->listenport);
|
||||||
|
|
||||||
/* a listenaddr of "" will indicate all interfaces */
|
nsocks = dropbear_listen(tcpinfo->listenaddr, portstring, socks,
|
||||||
if (opts.listen_fwd_all
|
|
||||||
&& (strcmp(tcpinfo->listenaddr, "localhost") != 0) ) {
|
|
||||||
listen_spec = tcpinfo->listenaddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsocks = dropbear_listen(listen_spec, portstring, socks,
|
|
||||||
DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd);
|
DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd);
|
||||||
if (nsocks < 0) {
|
if (nsocks < 0) {
|
||||||
dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring);
|
dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring);
|
||||||
|
1
tcpfwd.h
1
tcpfwd.h
@ -48,6 +48,7 @@ struct TCPFwdList {
|
|||||||
|
|
||||||
const unsigned char* connectaddr;
|
const unsigned char* connectaddr;
|
||||||
unsigned int connectport;
|
unsigned int connectport;
|
||||||
|
const unsigned char* listenaddr;
|
||||||
unsigned int listenport;
|
unsigned int listenport;
|
||||||
unsigned int have_reply; /* is set to 1 after a reply has been received
|
unsigned int have_reply; /* is set to 1 after a reply has been received
|
||||||
when setting up the forwarding */
|
when setting up the forwarding */
|
||||||
|
Loading…
Reference in New Issue
Block a user