mirror of
https://github.com/clearml/dropbear
synced 2025-04-23 07:34:52 +00:00
* add -g (dbclient) and -a (dropbear) options for allowing non-local
hosts to connect to forwarded ports. Rearranged various some of the tcp listening code. * changed to /* */ style brackets in svr-authpam.c --HG-- extra : convert_revision : c1e04e648867db464fe9818c4910e4320cd50c32
This commit is contained in:
parent
736f370dce
commit
a673d60963
@ -47,6 +47,7 @@ static void printhelp() {
|
|||||||
"Usage: %s [options] [user@]host\n"
|
"Usage: %s [options] [user@]host\n"
|
||||||
"Options are:\n"
|
"Options are:\n"
|
||||||
"-p <remoteport>\n"
|
"-p <remoteport>\n"
|
||||||
|
"-l <username>\n"
|
||||||
"-t Allocate a pty\n"
|
"-t Allocate a pty\n"
|
||||||
"-T Don't allocate a pty\n"
|
"-T Don't allocate a pty\n"
|
||||||
#ifdef ENABLE_CLI_PUBKEY_AUTH
|
#ifdef ENABLE_CLI_PUBKEY_AUTH
|
||||||
@ -54,11 +55,11 @@ static void printhelp() {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||||
"-L <listenport:remotehost:remoteport> Local port forwarding\n"
|
"-L <listenport:remotehost:remoteport> Local port forwarding\n"
|
||||||
|
"-g Allow remote hosts to connect to forwarded ports\n"
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||||
"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
|
"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
|
||||||
#endif
|
#endif
|
||||||
"-l <username>\n"
|
|
||||||
#ifdef DEBUG_TRACE
|
#ifdef DEBUG_TRACE
|
||||||
"-v verbose\n"
|
"-v verbose\n"
|
||||||
#endif
|
#endif
|
||||||
@ -93,12 +94,11 @@ void cli_getopts(int argc, char ** argv) {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||||
cli_opts.localfwds = NULL;
|
cli_opts.localfwds = NULL;
|
||||||
|
opts.listen_fwd_all = 0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||||
cli_opts.remotefwds = NULL;
|
cli_opts.remotefwds = NULL;
|
||||||
#endif
|
#endif
|
||||||
opts.nolocaltcp = 0;
|
|
||||||
opts.noremotetcp = 0;
|
|
||||||
/* not yet
|
/* not yet
|
||||||
opts.ipv4 = 1;
|
opts.ipv4 = 1;
|
||||||
opts.ipv6 = 1;
|
opts.ipv6 = 1;
|
||||||
@ -167,6 +167,9 @@ void cli_getopts(int argc, char ** argv) {
|
|||||||
case 'L':
|
case 'L':
|
||||||
nextislocal = 1;
|
nextislocal = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'g':
|
||||||
|
opts.listen_fwd_all = 1;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||||
case 'R':
|
case 'R':
|
||||||
|
17
cli-tcpfwd.c
17
cli-tcpfwd.c
@ -95,9 +95,17 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
|
|||||||
remoteport));
|
remoteport));
|
||||||
|
|
||||||
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
|
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
|
||||||
|
|
||||||
tcpinfo->sendaddr = m_strdup(remoteaddr);
|
tcpinfo->sendaddr = m_strdup(remoteaddr);
|
||||||
tcpinfo->sendport = remoteport;
|
tcpinfo->sendport = remoteport;
|
||||||
|
|
||||||
|
if (opts.listen_fwd_all) {
|
||||||
|
tcpinfo->listenaddr = m_strdup("");
|
||||||
|
} else {
|
||||||
|
tcpinfo->listenaddr = m_strdup("localhost");
|
||||||
|
}
|
||||||
tcpinfo->listenport = listenport;
|
tcpinfo->listenport = listenport;
|
||||||
|
|
||||||
tcpinfo->chantype = &cli_chan_tcplocal;
|
tcpinfo->chantype = &cli_chan_tcplocal;
|
||||||
|
|
||||||
ret = listen_tcpfwd(tcpinfo);
|
ret = listen_tcpfwd(tcpinfo);
|
||||||
@ -113,13 +121,20 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
|
|||||||
#ifdef ENABLE_CLI_REMOTETCPFWD
|
#ifdef ENABLE_CLI_REMOTETCPFWD
|
||||||
static void send_msg_global_request_remotetcp(int port) {
|
static void send_msg_global_request_remotetcp(int port) {
|
||||||
|
|
||||||
|
char* listenspec = NULL;
|
||||||
TRACE(("enter send_msg_global_request_remotetcp"))
|
TRACE(("enter send_msg_global_request_remotetcp"))
|
||||||
|
|
||||||
CHECKCLEARTOWRITE();
|
CHECKCLEARTOWRITE();
|
||||||
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, 0);
|
buf_putbyte(ses.writepayload, 0);
|
||||||
buf_putstring(ses.writepayload, "0.0.0.0", 7); /* TODO: IPv6? */
|
if (opts.listen_fwd_all) {
|
||||||
|
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();
|
||||||
|
@ -59,6 +59,11 @@ Allocate a pty.
|
|||||||
.TP
|
.TP
|
||||||
.B \-T
|
.B \-T
|
||||||
Don't allocate a pty.
|
Don't allocate a pty.
|
||||||
|
.TP
|
||||||
|
.B \-g
|
||||||
|
Allow non-local hosts to connect to forwarded ports. Applies to -L and -R
|
||||||
|
forwarded ports, though remote connections to -R forwarded ports may be limited
|
||||||
|
by the ssh server.
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Matt Johnston (matt@ucc.asn.au).
|
Matt Johnston (matt@ucc.asn.au).
|
||||||
.br
|
.br
|
||||||
|
17
dbutil.c
17
dbutil.c
@ -177,8 +177,9 @@ static void set_sock_priority(int sock) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Listen on address:port. Unless address is NULL, in which case listen on
|
/* Listen on address:port.
|
||||||
* everything. If called with address == "", we'll listen on localhost/loopback.
|
* Special cases are address of "" listening on everything,
|
||||||
|
* and address of NULL listening on localhost only.
|
||||||
* Returns the number of sockets bound on success, or -1 on failure. On
|
* Returns the number of sockets bound on success, or -1 on failure. On
|
||||||
* failure, if errstring wasn't NULL, it'll be a newly malloced error
|
* failure, if errstring wasn't NULL, it'll be a newly malloced error
|
||||||
* string.*/
|
* string.*/
|
||||||
@ -198,11 +199,17 @@ int dropbear_listen(const char* address, const char* port,
|
|||||||
hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */
|
hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
if (address && address[0] == '\0') {
|
// for calling getaddrinfo:
|
||||||
|
// address == NULL and !AI_PASSIVE: local loopback
|
||||||
|
// address == NULL and AI_PASSIVE: all interfaces
|
||||||
|
// address != NULL: whatever the address says
|
||||||
|
if (!address) {
|
||||||
TRACE(("dropbear_listen: local loopback"))
|
TRACE(("dropbear_listen: local loopback"))
|
||||||
address = NULL;
|
|
||||||
} else {
|
} else {
|
||||||
TRACE(("dropbear_listen: not local loopback"))
|
if (address[0] == '\0') {
|
||||||
|
TRACE(("dropbear_listen: all interfaces"))
|
||||||
|
address = NULL;
|
||||||
|
}
|
||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
}
|
}
|
||||||
err = getaddrinfo(address, port, &hints, &res0);
|
err = getaddrinfo(address, port, &hints, &res0);
|
||||||
|
@ -71,6 +71,9 @@ Use this option to run
|
|||||||
.B dropbear
|
.B dropbear
|
||||||
under TCP/IP servers like inetd, tcpsvd, or tcpserver.
|
under TCP/IP servers like inetd, tcpsvd, or tcpserver.
|
||||||
In program mode the \-F option is implied, and \-p options are ignored.
|
In program mode the \-F option is implied, and \-p options are ignored.
|
||||||
|
.TP
|
||||||
|
.B \-a
|
||||||
|
Allow remote hosts to connect to forwarded ports.
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Matt Johnston (matt@ucc.asn.au).
|
Matt Johnston (matt@ucc.asn.au).
|
||||||
.br
|
.br
|
||||||
|
14
runopts.h
14
runopts.h
@ -33,8 +33,9 @@
|
|||||||
|
|
||||||
typedef struct runopts {
|
typedef struct runopts {
|
||||||
|
|
||||||
int nolocaltcp;
|
#if defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD)
|
||||||
int noremotetcp;
|
int listen_fwd_all;
|
||||||
|
#endif
|
||||||
|
|
||||||
} runopts;
|
} runopts;
|
||||||
|
|
||||||
@ -73,6 +74,13 @@ typedef struct svr_runopts {
|
|||||||
int noauthpass;
|
int noauthpass;
|
||||||
int norootpass;
|
int norootpass;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SVR_REMOTETCPFWD
|
||||||
|
int noremotetcp;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_SVR_LOCALTCPFWD
|
||||||
|
int nolocaltcp;
|
||||||
|
#endif
|
||||||
|
|
||||||
sign_key *hostkey;
|
sign_key *hostkey;
|
||||||
buffer * banner;
|
buffer * banner;
|
||||||
|
|
||||||
@ -83,7 +91,6 @@ extern svr_runopts svr_opts;
|
|||||||
void svr_getopts(int argc, char ** argv);
|
void svr_getopts(int argc, char ** argv);
|
||||||
void loadhostkeys();
|
void loadhostkeys();
|
||||||
|
|
||||||
/* Uncompleted XXX matt */
|
|
||||||
typedef struct cli_runopts {
|
typedef struct cli_runopts {
|
||||||
|
|
||||||
char *progname;
|
char *progname;
|
||||||
@ -103,7 +110,6 @@ typedef struct cli_runopts {
|
|||||||
#ifdef ENABLE_CLI_LOCALTCPFWD
|
#ifdef ENABLE_CLI_LOCALTCPFWD
|
||||||
struct TCPFwdList * localfwds;
|
struct TCPFwdList * localfwds;
|
||||||
#endif
|
#endif
|
||||||
/* XXX TODO */
|
|
||||||
|
|
||||||
} cli_runopts;
|
} cli_runopts;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ pamConvFunc(int num_msg,
|
|||||||
|
|
||||||
const char* message = (*msg)->msg;
|
const char* message = (*msg)->msg;
|
||||||
|
|
||||||
// make a copy we can strip
|
/* make a copy we can strip */
|
||||||
char * compare_message = m_strdup(message);
|
char * compare_message = m_strdup(message);
|
||||||
|
|
||||||
TRACE(("enter pamConvFunc"))
|
TRACE(("enter pamConvFunc"))
|
||||||
@ -80,14 +80,14 @@ pamConvFunc(int num_msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Make the string lowercase.
|
/* Make the string lowercase. */
|
||||||
msg_len = strlen(compare_message);
|
msg_len = strlen(compare_message);
|
||||||
for (i = 0; i < msg_len; i++) {
|
for (i = 0; i < msg_len; i++) {
|
||||||
compare_message[i] = tolower(compare_message[i]);
|
compare_message[i] = tolower(compare_message[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the string ends with ": ", remove the space.
|
/* If the string ends with ": ", remove the space.
|
||||||
// ie "login: " vs "login:"
|
ie "login: " vs "login:" */
|
||||||
if (msg_len > 2
|
if (msg_len > 2
|
||||||
&& compare_message[msg_len-2] == ':'
|
&& compare_message[msg_len-2] == ':'
|
||||||
&& compare_message[msg_len-1] == ' ') {
|
&& compare_message[msg_len-1] == ' ') {
|
||||||
@ -99,9 +99,9 @@ pamConvFunc(int num_msg,
|
|||||||
case PAM_PROMPT_ECHO_OFF:
|
case PAM_PROMPT_ECHO_OFF:
|
||||||
|
|
||||||
if (!(strcmp(compare_message, "password:") == 0)) {
|
if (!(strcmp(compare_message, "password:") == 0)) {
|
||||||
// We don't recognise the prompt as asking for a password,
|
/* We don't recognise the prompt as asking for a password,
|
||||||
// so can't handle it. Add more above as required for
|
so can't handle it. Add more above as required for
|
||||||
// different pam modules/implementations
|
different pam modules/implementations */
|
||||||
dropbear_log(LOG_NOTICE, "PAM unknown prompt %s (no echo)",
|
dropbear_log(LOG_NOTICE, "PAM unknown prompt %s (no echo)",
|
||||||
compare_message);
|
compare_message);
|
||||||
rc = PAM_CONV_ERR;
|
rc = PAM_CONV_ERR;
|
||||||
@ -125,9 +125,9 @@ pamConvFunc(int num_msg,
|
|||||||
|
|
||||||
if (!((strcmp(compare_message, "login:" ) == 0)
|
if (!((strcmp(compare_message, "login:" ) == 0)
|
||||||
|| (strcmp(compare_message, "please enter username:") == 0))) {
|
|| (strcmp(compare_message, "please enter username:") == 0))) {
|
||||||
// We don't recognise the prompt as asking for a username,
|
/* We don't recognise the prompt as asking for a username,
|
||||||
// so can't handle it. Add more above as required for
|
so can't handle it. Add more above as required for
|
||||||
// different pam modules/implementations
|
different pam modules/implementations */
|
||||||
dropbear_log(LOG_NOTICE, "PAM unknown prompt %s (with echo)",
|
dropbear_log(LOG_NOTICE, "PAM unknown prompt %s (with echo)",
|
||||||
compare_message);
|
compare_message);
|
||||||
rc = PAM_CONV_ERR;
|
rc = PAM_CONV_ERR;
|
||||||
|
@ -375,7 +375,7 @@ static int listensockets(int *sock, int sockcount, int *maxfd) {
|
|||||||
|
|
||||||
TRACE(("listening on '%s'", svr_opts.ports[i]))
|
TRACE(("listening on '%s'", svr_opts.ports[i]))
|
||||||
|
|
||||||
nsock = dropbear_listen(NULL, svr_opts.ports[i], &sock[sockpos],
|
nsock = dropbear_listen("", svr_opts.ports[i], &sock[sockpos],
|
||||||
sockcount - sockpos,
|
sockcount - sockpos,
|
||||||
&errstring, maxfd);
|
&errstring, maxfd);
|
||||||
|
|
||||||
|
@ -63,11 +63,12 @@ static void printhelp(const char * progname) {
|
|||||||
"-s Disable password logins\n"
|
"-s Disable password logins\n"
|
||||||
"-g Disable password logins for root\n"
|
"-g Disable password logins for root\n"
|
||||||
#endif
|
#endif
|
||||||
#ifndef DISABLE_LOCALTCPFWD
|
#ifdef ENABLE_SVR_LOCALTCPFWD
|
||||||
"-j Disable local port forwarding\n"
|
"-j Disable local port forwarding\n"
|
||||||
#endif
|
#endif
|
||||||
#ifndef DISABLE_REMOTETCPFWD
|
#ifdef ENABLE_SVR_REMOTETCPFWD
|
||||||
"-k Disable remote port forwarding\n"
|
"-k Disable remote port forwarding\n"
|
||||||
|
"-a Allow connections to forwarded ports from any host\n"
|
||||||
#endif
|
#endif
|
||||||
"-p port Listen on specified tcp port, up to %d can be specified\n"
|
"-p port Listen on specified tcp port, up to %d can be specified\n"
|
||||||
" (default %s if none specified)\n"
|
" (default %s if none specified)\n"
|
||||||
@ -104,8 +105,8 @@ void svr_getopts(int argc, char ** argv) {
|
|||||||
svr_opts.inetdmode = 0;
|
svr_opts.inetdmode = 0;
|
||||||
svr_opts.portcount = 0;
|
svr_opts.portcount = 0;
|
||||||
svr_opts.hostkey = NULL;
|
svr_opts.hostkey = NULL;
|
||||||
opts.nolocaltcp = 0;
|
svr_opts.nolocaltcp = 0;
|
||||||
opts.noremotetcp = 0;
|
svr_opts.noremotetcp = 0;
|
||||||
/* not yet
|
/* not yet
|
||||||
opts.ipv4 = 1;
|
opts.ipv4 = 1;
|
||||||
opts.ipv6 = 1;
|
opts.ipv6 = 1;
|
||||||
@ -116,6 +117,9 @@ void svr_getopts(int argc, char ** argv) {
|
|||||||
#ifndef DISABLE_SYSLOG
|
#ifndef DISABLE_SYSLOG
|
||||||
svr_opts.usingsyslog = 1;
|
svr_opts.usingsyslog = 1;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_SVR_REMOTETCPFWD
|
||||||
|
opts.listen_fwd_all = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 1; i < (unsigned int)argc; i++) {
|
for (i = 1; i < (unsigned int)argc; i++) {
|
||||||
if (next) {
|
if (next) {
|
||||||
@ -152,12 +156,15 @@ void svr_getopts(int argc, char ** argv) {
|
|||||||
#endif
|
#endif
|
||||||
#ifndef DISABLE_LOCALTCPFWD
|
#ifndef DISABLE_LOCALTCPFWD
|
||||||
case 'j':
|
case 'j':
|
||||||
opts.nolocaltcp = 1;
|
svr_opts.nolocaltcp = 1;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef DISABLE_REMOTETCPFWD
|
#ifndef DISABLE_REMOTETCPFWD
|
||||||
case 'k':
|
case 'k':
|
||||||
opts.noremotetcp = 1;
|
svr_opts.noremotetcp = 1;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
opts.listen_fwd_all = 1;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INETD_MODE
|
#ifdef INETD_MODE
|
||||||
|
24
svr-tcpfwd.c
24
svr-tcpfwd.c
@ -72,7 +72,7 @@ void recv_msg_global_request_remotetcp() {
|
|||||||
|
|
||||||
TRACE(("enter recv_msg_global_request_remotetcp"))
|
TRACE(("enter recv_msg_global_request_remotetcp"))
|
||||||
|
|
||||||
if (opts.noremotetcp) {
|
if (svr_opts.noremotetcp) {
|
||||||
TRACE(("leave recv_msg_global_request_remotetcp: remote tcp forwarding disabled"))
|
TRACE(("leave recv_msg_global_request_remotetcp: remote tcp forwarding disabled"))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -129,9 +129,9 @@ static int matchtcp(void* typedata1, void* typedata2) {
|
|||||||
const struct TCPListener *info1 = (struct TCPListener*)typedata1;
|
const struct TCPListener *info1 = (struct TCPListener*)typedata1;
|
||||||
const struct TCPListener *info2 = (struct TCPListener*)typedata2;
|
const struct TCPListener *info2 = (struct TCPListener*)typedata2;
|
||||||
|
|
||||||
return (info1->sendport == info2->sendport)
|
return (info1->listenport == info2->listenport)
|
||||||
&& (info1->chantype == info2->chantype)
|
&& (info1->chantype == info2->chantype)
|
||||||
&& (strcmp(info1->sendaddr, info2->sendaddr) == 0);
|
&& (strcmp(info1->listenaddr, info2->listenaddr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int svr_cancelremotetcp() {
|
static int svr_cancelremotetcp() {
|
||||||
@ -153,8 +153,10 @@ static int svr_cancelremotetcp() {
|
|||||||
|
|
||||||
port = buf_getint(ses.payload);
|
port = buf_getint(ses.payload);
|
||||||
|
|
||||||
tcpinfo.sendaddr = bindaddr;
|
tcpinfo.sendaddr = NULL;
|
||||||
tcpinfo.sendport = port;
|
tcpinfo.sendport = 0;
|
||||||
|
tcpinfo.listenaddr = bindaddr;
|
||||||
|
tcpinfo.listenport = port;
|
||||||
listener = get_listener(CHANNEL_ID_TCPFORWARDED, &tcpinfo, matchtcp);
|
listener = get_listener(CHANNEL_ID_TCPFORWARDED, &tcpinfo, matchtcp);
|
||||||
if (listener) {
|
if (listener) {
|
||||||
remove_listener( listener );
|
remove_listener( listener );
|
||||||
@ -177,7 +179,6 @@ static int svr_remotetcpreq() {
|
|||||||
|
|
||||||
TRACE(("enter remotetcpreq"))
|
TRACE(("enter remotetcpreq"))
|
||||||
|
|
||||||
/* NOTE: at this stage, we ignore bindaddr. see below and listen_tcpfwd */
|
|
||||||
bindaddr = buf_getstring(ses.payload, &addrlen);
|
bindaddr = buf_getstring(ses.payload, &addrlen);
|
||||||
if (addrlen > MAX_IP_LEN) {
|
if (addrlen > MAX_IP_LEN) {
|
||||||
TRACE(("addr len too long: %d", addrlen))
|
TRACE(("addr len too long: %d", addrlen))
|
||||||
@ -202,20 +203,19 @@ static int svr_remotetcpreq() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
|
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
|
||||||
tcpinfo->sendaddr = bindaddr;
|
tcpinfo->sendaddr = NULL;
|
||||||
tcpinfo->sendport = port;
|
tcpinfo->sendport = 0;
|
||||||
|
tcpinfo->listenaddr = bindaddr;
|
||||||
tcpinfo->listenport = port;
|
tcpinfo->listenport = port;
|
||||||
tcpinfo->chantype = &svr_chan_tcpremote;
|
tcpinfo->chantype = &svr_chan_tcpremote;
|
||||||
|
|
||||||
/* Note: bindaddr is actually ignored by listen_tcpfwd, since
|
|
||||||
* we only want to bind to localhost */
|
|
||||||
ret = listen_tcpfwd(tcpinfo);
|
ret = listen_tcpfwd(tcpinfo);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (ret == DROPBEAR_FAILURE) {
|
if (ret == DROPBEAR_FAILURE) {
|
||||||
/* we only free it if a listener wasn't created, since the listener
|
/* we only free it if a listener wasn't created, since the listener
|
||||||
* has to remember it if it's to be cancelled */
|
* has to remember it if it's to be cancelled */
|
||||||
m_free(tcpinfo->sendaddr);
|
m_free(tcpinfo->listenaddr);
|
||||||
m_free(tcpinfo);
|
m_free(tcpinfo);
|
||||||
}
|
}
|
||||||
TRACE(("leave remotetcpreq"))
|
TRACE(("leave remotetcpreq"))
|
||||||
@ -235,7 +235,7 @@ static int newtcpdirect(struct Channel * channel) {
|
|||||||
int len;
|
int len;
|
||||||
int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
|
int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
|
||||||
|
|
||||||
if (opts.nolocaltcp) {
|
if (svr_opts.nolocaltcp) {
|
||||||
TRACE(("leave newtcpdirect: local tcp forwarding disabled"))
|
TRACE(("leave newtcpdirect: local tcp forwarding disabled"))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
24
tcp-accept.c
24
tcp-accept.c
@ -39,6 +39,7 @@ static void cleanup_tcp(struct Listener *listener) {
|
|||||||
struct TCPListener *tcpinfo = (struct TCPListener*)(listener->typedata);
|
struct TCPListener *tcpinfo = (struct TCPListener*)(listener->typedata);
|
||||||
|
|
||||||
m_free(tcpinfo->sendaddr);
|
m_free(tcpinfo->sendaddr);
|
||||||
|
m_free(tcpinfo->listenaddr);
|
||||||
m_free(tcpinfo);
|
m_free(tcpinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,10 +66,14 @@ static void tcp_acceptor(struct Listener *listener, int sock) {
|
|||||||
|
|
||||||
if (send_msg_channel_open_init(fd, tcpinfo->chantype) == DROPBEAR_SUCCESS) {
|
if (send_msg_channel_open_init(fd, tcpinfo->chantype) == DROPBEAR_SUCCESS) {
|
||||||
|
|
||||||
buf_putstring(ses.writepayload, tcpinfo->sendaddr,
|
// address that was connected
|
||||||
strlen(tcpinfo->sendaddr));
|
buf_putstring(ses.writepayload, tcpinfo->listenaddr,
|
||||||
buf_putint(ses.writepayload, tcpinfo->sendport);
|
strlen(tcpinfo->listenaddr));
|
||||||
|
// port that was connected
|
||||||
|
buf_putint(ses.writepayload, tcpinfo->listenport);
|
||||||
|
// originator ip
|
||||||
buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
|
buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
|
||||||
|
// originator port
|
||||||
buf_putint(ses.writepayload, atol(portstring));
|
buf_putint(ses.writepayload, atol(portstring));
|
||||||
|
|
||||||
encrypt_packet();
|
encrypt_packet();
|
||||||
@ -86,16 +91,21 @@ 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);
|
||||||
|
|
||||||
/* XXX Note: we're just listening on localhost, no matter what they tell
|
/* a listenaddr of "" will indicate all interfaces */
|
||||||
* us. If someone wants to make it listen otherways, then change
|
if (opts.listen_fwd_all
|
||||||
* the "" argument. but that requires UI changes too */
|
&& (strcmp(tcpinfo->listenaddr, "localhost") != 0) ) {
|
||||||
nsocks = dropbear_listen("", portstring, socks,
|
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);
|
||||||
|
11
tcpfwd.h
11
tcpfwd.h
@ -28,16 +28,15 @@
|
|||||||
|
|
||||||
struct TCPListener {
|
struct TCPListener {
|
||||||
|
|
||||||
/* sendaddr/sendport are what we send in the channel init request. For a
|
/* For a direct-tcpip request, it's the addr/port we want the other
|
||||||
* forwarded-tcpip request, it's the addr/port we were binding to.
|
|
||||||
* For a direct-tcpip request, it's the addr/port we want the other
|
|
||||||
* end to connect to */
|
* end to connect to */
|
||||||
|
|
||||||
unsigned char *sendaddr;
|
unsigned char *sendaddr;
|
||||||
unsigned int sendport;
|
unsigned int sendport;
|
||||||
|
|
||||||
/* This is for direct-tcpip (ie the client listening), and specifies the
|
/* This is the address/port that we listen on. The address has special
|
||||||
* port to listen on. Is unspecified for the server */
|
* meanings as per the rfc, "" for all interfaces, "localhost" for
|
||||||
|
* localhost, or a normal interface name. */
|
||||||
|
unsigned char *listenaddr;
|
||||||
unsigned int listenport;
|
unsigned int listenport;
|
||||||
|
|
||||||
const struct ChanType *chantype;
|
const struct ChanType *chantype;
|
||||||
|
Loading…
Reference in New Issue
Block a user