# HG changeset patch # User Matt Johnston # Date 1172155966 0 # Node ID 0aaaf68e97dc178cd8a3a7076cb698552f920632 # Parent 55a99934db873be2e63b5968fb6532e5d9bd02e4 Add -p [address:]port option for binding to addresses, patch from Max-Gerd Retzlaff diff -r 55a99934db87 -r 0aaaf68e97dc options.h --- a/options.h Thu Mar 09 15:03:22 2006 +0000 +++ b/options.h Thu Feb 22 14:52:46 2007 +0000 @@ -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 -r 55a99934db87 -r 0aaaf68e97dc runopts.h --- a/runopts.h Thu Mar 09 15:03:22 2006 +0000 +++ b/runopts.h Thu Feb 22 14:52:46 2007 +0000 @@ -55,6 +55,7 @@ /* 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 -r 55a99934db87 -r 0aaaf68e97dc svr-main.c --- a/svr-main.c Thu Mar 09 15:03:22 2006 +0000 +++ b/svr-main.c Thu Feb 22 14:52:46 2007 +0000 @@ -397,9 +397,9 @@ 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 -r 55a99934db87 -r 0aaaf68e97dc svr-runopts.c --- a/svr-runopts.c Thu Mar 09 15:03:22 2006 +0000 +++ b/svr-runopts.c Thu Feb 22 14:52:46 2007 +0000 @@ -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 @@ "-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" #ifdef INETD_MODE "-i Start for inetd\n" #endif @@ -92,6 +95,7 @@ unsigned int i; char ** next = 0; + int nextisport = 0; /* see printhelp() for options */ svr_opts.rsakeyfile = NULL; @@ -126,6 +130,12 @@ #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) { @@ -177,14 +187,8 @@ 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; #ifdef DO_MOTD /* motd is displayed by default, -m turns it off */ case 'm': @@ -223,15 +227,10 @@ /* 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; } @@ -261,6 +260,42 @@ } +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;