mirror of
https://github.com/clearml/dropbear
synced 2025-05-16 17:43:23 +00:00
bind to port as well with -b
This commit is contained in:
parent
9c7ecf6d14
commit
e4ac7ea1ca
@ -66,8 +66,8 @@ int main(int argc, char ** argv) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACE(("user='%s' host='%s' port='%s' bind_address='%s'", cli_opts.username,
|
TRACE(("user='%s' host='%s' port='%s' bind_address='%s' bind_port='%s'", cli_opts.username,
|
||||||
cli_opts.remotehost, cli_opts.remoteport, cli_opts.bind_address))
|
cli_opts.remotehost, cli_opts.remoteport, cli_opts.bind_address, cli_opts.bind_port))
|
||||||
|
|
||||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
||||||
dropbear_exit("signal() error");
|
dropbear_exit("signal() error");
|
||||||
@ -86,7 +86,8 @@ int main(int argc, char ** argv) {
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
progress = connect_remote(cli_opts.remotehost, cli_opts.remoteport, cli_connected, &ses, cli_opts.bind_address);
|
progress = connect_remote(cli_opts.remotehost, cli_opts.remoteport,
|
||||||
|
cli_connected, &ses, cli_opts.bind_address, cli_opts.bind_port);
|
||||||
sock_in = sock_out = -1;
|
sock_in = sock_out = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ static void printhelp() {
|
|||||||
"-c <cipher list> Specify preferred ciphers ('-c help' to list options)\n"
|
"-c <cipher list> Specify preferred ciphers ('-c help' to list options)\n"
|
||||||
"-m <MAC list> Specify preferred MACs for packet verification (or '-m help')\n"
|
"-m <MAC list> Specify preferred MACs for packet verification (or '-m help')\n"
|
||||||
#endif
|
#endif
|
||||||
"-b bind_address\n"
|
"-b [bind_address][:bind_port]\n"
|
||||||
"-V Version\n"
|
"-V Version\n"
|
||||||
#if DEBUG_TRACE
|
#if DEBUG_TRACE
|
||||||
"-v verbose (compiled with DEBUG_TRACE)\n"
|
"-v verbose (compiled with DEBUG_TRACE)\n"
|
||||||
@ -131,6 +131,7 @@ void cli_getopts(int argc, char ** argv) {
|
|||||||
char* keepalive_arg = NULL;
|
char* keepalive_arg = NULL;
|
||||||
char* idle_timeout_arg = NULL;
|
char* idle_timeout_arg = NULL;
|
||||||
char *host_arg = NULL;
|
char *host_arg = NULL;
|
||||||
|
char *bind_arg = NULL;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
/* see printhelp() for options */
|
/* see printhelp() for options */
|
||||||
@ -167,6 +168,7 @@ void cli_getopts(int argc, char ** argv) {
|
|||||||
cli_opts.proxycmd = NULL;
|
cli_opts.proxycmd = NULL;
|
||||||
#endif
|
#endif
|
||||||
cli_opts.bind_address = NULL;
|
cli_opts.bind_address = NULL;
|
||||||
|
cli_opts.bind_port = NULL;
|
||||||
#ifndef DISABLE_ZLIB
|
#ifndef DISABLE_ZLIB
|
||||||
opts.compress_mode = DROPBEAR_COMPRESS_ON;
|
opts.compress_mode = DROPBEAR_COMPRESS_ON;
|
||||||
#endif
|
#endif
|
||||||
@ -315,7 +317,7 @@ void cli_getopts(int argc, char ** argv) {
|
|||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
next = &cli_opts.bind_address;
|
next = &bind_arg;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -421,6 +423,18 @@ void cli_getopts(int argc, char ** argv) {
|
|||||||
cli_opts.remoteport = "22";
|
cli_opts.remoteport = "22";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bind_arg) {
|
||||||
|
/* split [host][:port] */
|
||||||
|
char *port = strrchr(bind_arg, ':');
|
||||||
|
if (port) {
|
||||||
|
cli_opts.bind_port = m_strdup(port+1);
|
||||||
|
*port = '\0';
|
||||||
|
}
|
||||||
|
if (strlen(bind_arg) > 0) {
|
||||||
|
cli_opts.bind_address = m_strdup(bind_arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If not explicitly specified with -t or -T, we don't want a pty if
|
/* If not explicitly specified with -t or -T, we don't want a pty if
|
||||||
* there's a command, but we do otherwise */
|
* there's a command, but we do otherwise */
|
||||||
if (cli_opts.wantpty == 9) {
|
if (cli_opts.wantpty == 9) {
|
||||||
|
@ -274,7 +274,7 @@ static int newtcpforwarded(struct Channel * channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
snprintf(portstring, sizeof(portstring), "%u", fwd->connectport);
|
snprintf(portstring, sizeof(portstring), "%u", fwd->connectport);
|
||||||
channel->conn_pending = connect_remote(fwd->connectaddr, portstring, channel_connect_done, channel, NULL);
|
channel->conn_pending = connect_remote(fwd->connectaddr, portstring, channel_connect_done, channel, NULL, NULL);
|
||||||
|
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
|
channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
|
||||||
|
|
||||||
|
@ -133,8 +133,8 @@ Can be used to give options in the format used by OpenSSH config file. This is
|
|||||||
useful for specifying options for which there is no separate command-line flag.
|
useful for specifying options for which there is no separate command-line flag.
|
||||||
For full details of the options listed below, and their possible values, see
|
For full details of the options listed below, and their possible values, see
|
||||||
ssh_config(5).
|
ssh_config(5).
|
||||||
|
The following options have currently been implemented:
|
||||||
|
|
||||||
For now following options have been implemented:
|
|
||||||
.RS
|
.RS
|
||||||
.TP
|
.TP
|
||||||
.B ExitOnForwardFailure
|
.B ExitOnForwardFailure
|
||||||
@ -147,6 +147,10 @@ Send dbclient log messages to syslog in addition to stderr.
|
|||||||
.B \-s
|
.B \-s
|
||||||
The specified command will be requested as a subsystem, used for sftp. Dropbear doesn't implement sftp itself but the OpenSSH sftp client can be used eg \fIsftp -S dbclient user@host\fR
|
The specified command will be requested as a subsystem, used for sftp. Dropbear doesn't implement sftp itself but the OpenSSH sftp client can be used eg \fIsftp -S dbclient user@host\fR
|
||||||
.TP
|
.TP
|
||||||
|
.B \-b \fI[address][:port]
|
||||||
|
Bind to a specific local address when connecting to the remote host. This can be used to choose from
|
||||||
|
multiple outgoing interfaces. Either address or port (or both) can be given.
|
||||||
|
.TP
|
||||||
.B \-V
|
.B \-V
|
||||||
Print the version
|
Print the version
|
||||||
|
|
||||||
|
64
netio.c
64
netio.c
@ -19,7 +19,7 @@ struct dropbear_progress_connection {
|
|||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
char* errstring;
|
char* errstring;
|
||||||
struct addrinfo *bind_addrinfo;
|
char *bind_address, *bind_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Deallocate a progress connection. Removes from the pending list if iter!=NULL.
|
/* Deallocate a progress connection. Removes from the pending list if iter!=NULL.
|
||||||
@ -31,7 +31,8 @@ static void remove_connect(struct dropbear_progress_connection *c, m_list_elem *
|
|||||||
m_free(c->remotehost);
|
m_free(c->remotehost);
|
||||||
m_free(c->remoteport);
|
m_free(c->remoteport);
|
||||||
m_free(c->errstring);
|
m_free(c->errstring);
|
||||||
if (c->bind_addrinfo) freeaddrinfo(c->bind_addrinfo);
|
m_free(c->bind_address);
|
||||||
|
m_free(c->bind_port);
|
||||||
m_free(c);
|
m_free(c);
|
||||||
|
|
||||||
if (iter) {
|
if (iter) {
|
||||||
@ -53,6 +54,7 @@ void cancel_connect(struct dropbear_progress_connection *c) {
|
|||||||
|
|
||||||
static void connect_try_next(struct dropbear_progress_connection *c) {
|
static void connect_try_next(struct dropbear_progress_connection *c) {
|
||||||
struct addrinfo *r;
|
struct addrinfo *r;
|
||||||
|
int err;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int fastopen = 0;
|
int fastopen = 0;
|
||||||
#if DROPBEAR_CLIENT_TCP_FAST_OPEN
|
#if DROPBEAR_CLIENT_TCP_FAST_OPEN
|
||||||
@ -68,11 +70,38 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->bind_addrinfo) {
|
if (c->bind_address || c->bind_port) {
|
||||||
if (bind(c->sock, c->bind_addrinfo->ai_addr, c->bind_addrinfo->ai_addrlen) < 0) {
|
/* bind to a source port/address */
|
||||||
/* failure */
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *bindaddr = NULL;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_family = r->ai_family;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
|
err = getaddrinfo(c->bind_address, c->bind_port, &hints, &bindaddr);
|
||||||
|
if (err) {
|
||||||
|
int len = 100 + strlen(gai_strerror(err));
|
||||||
m_free(c->errstring);
|
m_free(c->errstring);
|
||||||
c->errstring = m_strdup(strerror(errno));
|
c->errstring = (char*)m_malloc(len);
|
||||||
|
snprintf(c->errstring, len, "Error resolving bind address '%s' (port %s). %s",
|
||||||
|
c->bind_address, c->bind_port, gai_strerror(err));
|
||||||
|
TRACE(("Error resolving bind: %s", gai_strerror(err)))
|
||||||
|
close(c->sock);
|
||||||
|
c->sock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
res = bind(c->sock, bindaddr->ai_addr, bindaddr->ai_addrlen);
|
||||||
|
freeaddrinfo(bindaddr);
|
||||||
|
bindaddr = NULL;
|
||||||
|
if (res < 0) {
|
||||||
|
/* failure */
|
||||||
|
int keep_errno = errno;
|
||||||
|
int len = 300;
|
||||||
|
m_free(c->errstring);
|
||||||
|
c->errstring = m_malloc(len);
|
||||||
|
snprintf(c->errstring, len, "Error binding local address '%s' (port %s). %s",
|
||||||
|
c->bind_address, c->bind_port, strerror(keep_errno));
|
||||||
close(c->sock);
|
close(c->sock);
|
||||||
c->sock = -1;
|
c->sock = -1;
|
||||||
continue;
|
continue;
|
||||||
@ -143,7 +172,8 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
|
|||||||
|
|
||||||
/* Connect via TCP to a host. */
|
/* Connect via TCP to a host. */
|
||||||
struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport,
|
struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport,
|
||||||
connect_callback cb, void* cb_data, char* bind_address)
|
connect_callback cb, void* cb_data,
|
||||||
|
const char* bind_address, const char* bind_port)
|
||||||
{
|
{
|
||||||
struct dropbear_progress_connection *c = NULL;
|
struct dropbear_progress_connection *c = NULL;
|
||||||
int err;
|
int err;
|
||||||
@ -155,7 +185,6 @@ struct dropbear_progress_connection *connect_remote(const char* remotehost, cons
|
|||||||
c->sock = -1;
|
c->sock = -1;
|
||||||
c->cb = cb;
|
c->cb = cb;
|
||||||
c->cb_data = cb_data;
|
c->cb_data = cb_data;
|
||||||
c->bind_addrinfo = NULL;
|
|
||||||
|
|
||||||
list_append(&ses.conn_pending, c);
|
list_append(&ses.conn_pending, c);
|
||||||
|
|
||||||
@ -175,20 +204,11 @@ struct dropbear_progress_connection *connect_remote(const char* remotehost, cons
|
|||||||
c->res_iter = c->res;
|
c->res_iter = c->res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != bind_address) {
|
if (bind_address) {
|
||||||
memset(&hints, 0, sizeof(hints));
|
c->bind_address = m_strdup(bind_address);
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
}
|
||||||
hints.ai_family = AF_UNSPEC;
|
if (bind_port) {
|
||||||
err = getaddrinfo(bind_address, NULL, &hints, &c->bind_addrinfo);
|
c->bind_port = m_strdup(bind_port);
|
||||||
if (err) {
|
|
||||||
int len;
|
|
||||||
len = 100 + strlen(gai_strerror(err));
|
|
||||||
c->errstring = (char*)m_malloc(len);
|
|
||||||
snprintf(c->errstring, len, "Error resolving '%s'. %s",
|
|
||||||
bind_address, gai_strerror(err));
|
|
||||||
TRACE(("Error resolving: %s", gai_strerror(err)))
|
|
||||||
c->res_iter = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
2
netio.h
2
netio.h
@ -30,7 +30,7 @@ typedef void(*connect_callback)(int result, int sock, void* data, const char* er
|
|||||||
|
|
||||||
/* Always returns a progress connection, if it fails it will call the callback at a later point */
|
/* Always returns a progress connection, if it fails it will call the callback at a later point */
|
||||||
struct dropbear_progress_connection * connect_remote (const char* remotehost, const char* remoteport,
|
struct dropbear_progress_connection * connect_remote (const char* remotehost, const char* remoteport,
|
||||||
connect_callback cb, void *cb_data, char* bind_address);
|
connect_callback cb, void *cb_data, const char* bind_address, const char* bind_port);
|
||||||
|
|
||||||
/* Sets up for select() */
|
/* Sets up for select() */
|
||||||
void set_connect_fds(fd_set *writefd);
|
void set_connect_fds(fd_set *writefd);
|
||||||
|
@ -168,6 +168,7 @@ typedef struct cli_runopts {
|
|||||||
char *proxycmd;
|
char *proxycmd;
|
||||||
#endif
|
#endif
|
||||||
char *bind_address;
|
char *bind_address;
|
||||||
|
char *bind_port;
|
||||||
} cli_runopts;
|
} cli_runopts;
|
||||||
|
|
||||||
extern cli_runopts cli_opts;
|
extern cli_runopts cli_opts;
|
||||||
|
@ -285,7 +285,7 @@ static int newtcpdirect(struct Channel * channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
snprintf(portstring, sizeof(portstring), "%u", destport);
|
snprintf(portstring, sizeof(portstring), "%u", destport);
|
||||||
channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done, channel, NULL);
|
channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done, channel, NULL, NULL);
|
||||||
|
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
|
channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user