diff options
author | Matt Johnston <matt@ucc.asn.au> | 2008-09-18 14:47:02 +0000 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2008-09-18 14:47:02 +0000 |
commit | f4aacaa74c948d4cae554c293f801bce2a35e452 (patch) | |
tree | faf6d290dc6e9bd70671826d9855d2477bca4b99 | |
parent | 66e2f59c7b81c28d2f0c0cbf26f4de7ed73f3038 (diff) |
Add multihop 'onion-forwarding' mode. Needs refinement, works.
--HG--
extra : convert_revision : 877947ce24297781438a75e7e9c64ba86f0dce93
-rw-r--r-- | cli-runopts.c | 87 | ||||
-rw-r--r-- | options.h | 8 |
2 files changed, 87 insertions, 8 deletions
diff --git a/cli-runopts.c b/cli-runopts.c index b97f12e..8a6dc07 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -33,7 +33,7 @@ cli_runopts cli_opts; /* GLOBAL */ static void printhelp(); -static void parsehostname(const char* orighostarg); +static void parsehostname(const char* orighostarg, const char* argv0); static void fill_own_user(); #ifdef ENABLE_CLI_PUBKEY_AUTH static void loadidentityfile(const char* filename); @@ -291,7 +291,7 @@ void cli_getopts(int argc, char ** argv) { if (cli_opts.remotehost == NULL) { - parsehostname(argv[i]); + parsehostname(argv[i], argv[0]); } else { @@ -319,6 +319,8 @@ void cli_getopts(int argc, char ** argv) { } } + /* And now a few sanity checks and setup */ + if (cli_opts.remotehost == NULL) { printhelp(); exit(EXIT_FAILURE); @@ -355,6 +357,12 @@ void cli_getopts(int argc, char ** argv) { dropbear_exit("Bad keepalive '%s'", keepalive_arg); } } + +#ifdef ENABLE_CLI_NETCAT + if (cli_opts.cmd && cli_opts.netcat_host) { + dropbear_log(LOG_INFO, "Ignoring command '%s' in netcat mode", cli_opts.cmd); + } +#endif } @@ -383,12 +391,77 @@ static void loadidentityfile(const char* filename) { } #endif +#ifdef ENABLE_CLI_MULTIHOP + +/* Sets up 'onion-forwarding' connections. + * As an example, if the cmdline is + * dbclient wrt,madako,canyons + * then we want to run: + * dbclient -J "dbclient -B canyons:22 wrt,madako" canyons + * and then the inner dbclient will recursively run: + * dbclient -J "dbclient -B madako:22 wrt" madako + * etc for as many hosts as we want. + */ +static void parsehostname(const char* orighostarg, const char* argv0) { + char *userhostarg = NULL; + char *last_hop = NULL;; + char *remainder = NULL; -/* Parses a [user@]hostname argument. orighostarg is the argv[i] corresponding */ -static void parsehostname(const char* orighostarg) { + userhostarg = m_strdup(orighostarg); - uid_t uid; - struct passwd *pw = NULL; + last_hop = strrchr(userhostarg, ','); + if (last_hop) { + if (last_hop == userhostarg) { + dropbear_exit("Bad multi-hop hostnames"); + } + *last_hop = '\0'; + last_hop++; + remainder = userhostarg; + userhostarg = last_hop; + } + + cli_opts.remotehost = strchr(userhostarg, '@'); + if (cli_opts.remotehost == NULL) { + /* no username portion, the cli-auth.c code can figure the + * local user's name */ + cli_opts.remotehost = userhostarg; + } else { + cli_opts.remotehost[0] = '\0'; /* Split the user/host */ + cli_opts.remotehost++; + cli_opts.username = userhostarg; + } + + if (cli_opts.username == NULL) { + cli_opts.username = m_strdup(cli_opts.own_user); + } + + if (cli_opts.remotehost[0] == '\0') { + dropbear_exit("Bad hostname"); + } + + if (last_hop) { + /* Set up the proxycmd */ + unsigned int cmd_len = 0; + if (cli_opts.proxycmd) { + dropbear_exit("-J can't be used with multihop mode"); + } + if (cli_opts.remoteport == NULL) { + cli_opts.remoteport = "22"; + } + cmd_len = strlen(remainder) + + strlen(cli_opts.remotehost) + strlen(cli_opts.remoteport) + + strlen(argv0) + 30; + cli_opts.proxycmd = m_malloc(cmd_len); + snprintf(cli_opts.proxycmd, cmd_len, "%s -B %s:%s %s", + argv0, cli_opts.remotehost, cli_opts.remoteport, remainder); + dropbear_log(LOG_INFO, "proxycmd: '%s'", cli_opts.proxycmd); + } +} + +#else /* !ENABLE_CLI_MULTIHOP */ + +/* Parses a [user@]hostname argument. orighostarg is the argv[i] corresponding */ +static void parsehostname(const char* orighostarg, const char* argv0) { char *userhostarg = NULL; userhostarg = m_strdup(orighostarg); @@ -413,6 +486,8 @@ static void parsehostname(const char* orighostarg) { } } +#endif /* !ENABLE_CLI_MULTIHOP */ + #ifdef ENABLE_CLI_NETCAT static void add_netcat(const char* origstr) { char *portstr = NULL; @@ -140,8 +140,8 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ * but there's an interface via a PAM module - don't bother using it otherwise. * You can't enable both PASSWORD and PAM. */ -#define ENABLE_SVR_PASSWORD_AUTH -/*#define ENABLE_SVR_PAM_AUTH */ /* requires ./configure --enable-pam */ +//#define ENABLE_SVR_PASSWORD_AUTH +#define ENABLE_SVR_PAM_AUTH /* requires ./configure --enable-pam */ #define ENABLE_SVR_PUBKEY_AUTH #define ENABLE_CLI_PASSWORD_AUTH @@ -407,6 +407,10 @@ be overridden at runtime with -K. 0 disables keepalives */ #define USING_LISTENERS #endif +#if defined(ENABLE_CLI_NETCAT) && defined(ENABLE_CLI_PROXYCMD) +#define ENABLE_CLI_MULTIHOP +#endif + #if defined(DROPBEAR_CLIENT) || defined(ENABLE_SVR_PUBKEY_AUTH) #define DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */ #endif |