summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--options.h5
-rw-r--r--runopts.h1
-rw-r--r--svr-main.c4
-rw-r--r--svr-runopts.c69
4 files changed, 60 insertions, 19 deletions
diff --git a/options.h b/options.h
index a8f45d4..4ba51c3 100644
--- a/options.h
+++ b/options.h
@@ -14,6 +14,11 @@
#define DROPBEAR_DEFPORT "22"
#endif
+#ifndef DROPBEAR_DEFADDRESS
+/* Listen on all interfaces */
+#define DROPBEAR_DEFADDRESS ""
+#endif
+
/* Default hostkey paths - these can be specified on the command line */
#ifndef DSS_PRIV_FILENAME
#define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key"
diff --git a/runopts.h b/runopts.h
index 459edfe..ed34658 100644
--- a/runopts.h
+++ b/runopts.h
@@ -55,6 +55,7 @@ typedef struct svr_runopts {
/* ports is an array of the portcount listening ports */
char *ports[DROPBEAR_MAX_PORTS];
unsigned int portcount;
+ char *addresses[DROPBEAR_MAX_PORTS];
int inetdmode;
diff --git a/svr-main.c b/svr-main.c
index 616ddaf..0b65a45 100644
--- a/svr-main.c
+++ b/svr-main.c
@@ -403,9 +403,9 @@ static size_t listensockets(int *sock, size_t sockcount, int *maxfd) {
for (i = 0; i < svr_opts.portcount; i++) {
- TRACE(("listening on '%s'", svr_opts.ports[i]))
+ TRACE(("listening on '%s:%s'", svr_opts.addresses[i], svr_opts.ports[i]))
- nsock = dropbear_listen("", svr_opts.ports[i], &sock[sockpos],
+ nsock = dropbear_listen(svr_opts.addresses[i], svr_opts.ports[i], &sock[sockpos],
sockcount - sockpos,
&errstring, maxfd);
diff --git a/svr-runopts.c b/svr-runopts.c
index 784e0ca..2f51096 100644
--- a/svr-runopts.c
+++ b/svr-runopts.c
@@ -32,6 +32,7 @@
svr_runopts svr_opts; /* GLOBAL */
static void printhelp(const char * progname);
+static void addportandaddress(char* spec);
static void printhelp(const char * progname) {
@@ -70,8 +71,10 @@ static void printhelp(const char * progname) {
"-k Disable remote port forwarding\n"
"-a Allow connections to forwarded ports from any host\n"
#endif
- "-p port Listen on specified tcp port, up to %d can be specified\n"
- " (default %s if none specified)\n"
+ "-p [address:]port\n"
+ " Listen on specified tcp port (and optionally address),\n"
+ " up to %d can be specified\n"
+ " (default port is %s if none specified)\n"
"-P PidFile Create pid file PidFile\n"
" (default %s)\n"
#ifdef INETD_MODE
@@ -94,6 +97,7 @@ void svr_getopts(int argc, char ** argv) {
unsigned int i;
char ** next = 0;
+ int nextisport = 0;
/* see printhelp() for options */
svr_opts.rsakeyfile = NULL;
@@ -129,6 +133,12 @@ void svr_getopts(int argc, char ** argv) {
#endif
for (i = 1; i < (unsigned int)argc; i++) {
+ if (nextisport) {
+ addportandaddress(argv[i]);
+ nextisport = 0;
+ continue;
+ }
+
if (next) {
*next = argv[i];
if (*next == NULL) {
@@ -180,14 +190,8 @@ void svr_getopts(int argc, char ** argv) {
break;
#endif
case 'p':
- if (svr_opts.portcount < DROPBEAR_MAX_PORTS) {
- svr_opts.ports[svr_opts.portcount] = NULL;
- next = &svr_opts.ports[svr_opts.portcount];
- /* Note: if it doesn't actually get set, we'll
- * decrement it after the loop */
- svr_opts.portcount++;
- }
- break;
+ nextisport = 1;
+ break;
case 'P':
next = &svr_opts.pidfile;
break;
@@ -229,15 +233,10 @@ void svr_getopts(int argc, char ** argv) {
/* Set up listening ports */
if (svr_opts.portcount == 0) {
svr_opts.ports[0] = m_strdup(DROPBEAR_DEFPORT);
+ svr_opts.addresses[0] = m_strdup(DROPBEAR_DEFADDRESS);
svr_opts.portcount = 1;
- } else {
- /* we may have been given a -p option but no argument to go with
- * it */
- if (svr_opts.ports[svr_opts.portcount-1] == NULL) {
- svr_opts.portcount--;
- }
}
-
+
if (svr_opts.dsskeyfile == NULL) {
svr_opts.dsskeyfile = DSS_PRIV_FILENAME;
}
@@ -267,6 +266,42 @@ void svr_getopts(int argc, char ** argv) {
}
+static void addportandaddress(char* spec) {
+
+ char *myspec = NULL;
+
+ if (svr_opts.portcount < DROPBEAR_MAX_PORTS) {
+
+ /* We don't free it, it becomes part of the runopt state */
+ myspec = m_strdup(spec);
+
+ /* search for ':', that separates address and port */
+ svr_opts.ports[svr_opts.portcount] = strchr(myspec, ':');
+
+ if (svr_opts.ports[svr_opts.portcount] == NULL) {
+ /* no ':' -> the whole string specifies just a port */
+ svr_opts.ports[svr_opts.portcount] = myspec;
+ } else {
+ /* Split the address/port */
+ svr_opts.ports[svr_opts.portcount][0] = '\0';
+ svr_opts.ports[svr_opts.portcount]++;
+ svr_opts.addresses[svr_opts.portcount] = myspec;
+ }
+
+ if (svr_opts.addresses[svr_opts.portcount] == NULL) {
+ /* no address given -> fill in the default address */
+ svr_opts.addresses[svr_opts.portcount] = m_strdup(DROPBEAR_DEFADDRESS);
+ }
+
+ if (svr_opts.ports[svr_opts.portcount][0] == '\0') {
+ /* empty port -> exit */
+ dropbear_exit("Bad port");
+ }
+
+ svr_opts.portcount++;
+ }
+}
+
static void disablekey(int type, const char* filename) {
int i;