Mercurial > dropbear
diff cli-runopts.c @ 579:8c737cd7c1af
merge of '48fdaa8706d1acda35e9d564adc9a1fbc96c18c8'
and '658fd03abd21e0da7c4c89b9fff9dc693c72daae'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 27 Feb 2010 11:53:18 +0000 |
parents | 69e98c45db7c 44f486b72427 |
children | dd9947170fc8 |
line wrap: on
line diff
--- a/cli-runopts.c Wed Feb 24 16:13:15 2010 +0000 +++ b/cli-runopts.c Sat Feb 27 11:53:18 2010 +0000 @@ -29,6 +29,7 @@ #include "dbutil.h" #include "algo.h" #include "tcpfwd.h" +#include "list.h" cli_runopts cli_opts; /* GLOBAL */ @@ -40,7 +41,7 @@ static void loadidentityfile(const char* filename); #endif #ifdef ENABLE_CLI_ANYTCPFWD -static void addforward(const char* str, struct TCPFwdList** fwdlist); +static void addforward(const char* str, m_list *fwdlist); #endif #ifdef ENABLE_CLI_NETCAT static void add_netcat(const char *str); @@ -66,6 +67,9 @@ #ifdef ENABLE_CLI_PUBKEY_AUTH "-i <identityfile> (multiple allowed)\n" #endif +#ifdef ENABLE_CLI_AGENTFWD + "-A Enable agent auth forwarding\n" +#endif #ifdef ENABLE_CLI_LOCALTCPFWD "-L <listenport:remotehost:remoteport> Local port forwarding\n" "-g Allow remote hosts to connect to forwarded ports\n" @@ -91,7 +95,6 @@ } void cli_getopts(int argc, char ** argv) { - unsigned int i, j; char ** next = 0; unsigned int cmdlen; @@ -112,6 +115,7 @@ char* recv_window_arg = NULL; char* keepalive_arg = NULL; char* idle_timeout_arg = NULL; + char *host_arg = NULL; /* see printhelp() for options */ cli_opts.progname = argv[0]; @@ -125,18 +129,25 @@ cli_opts.always_accept_key = 0; cli_opts.is_subsystem = 0; #ifdef ENABLE_CLI_PUBKEY_AUTH - cli_opts.privkeys = NULL; + cli_opts.privkeys = list_new(); #endif #ifdef ENABLE_CLI_LOCALTCPFWD - cli_opts.localfwds = NULL; + cli_opts.localfwds = list_new(); opts.listen_fwd_all = 0; #endif #ifdef ENABLE_CLI_REMOTETCPFWD - cli_opts.remotefwds = NULL; + cli_opts.remotefwds = list_new(); +#endif +#ifdef ENABLE_CLI_AGENTFWD + cli_opts.agent_fwd = 0; + cli_opts.agent_keys_loaded = 0; #endif #ifdef ENABLE_CLI_PROXYCMD cli_opts.proxycmd = NULL; #endif +#ifndef DISABLE_ZLIB + opts.enable_compress = 1; +#endif /* not yet opts.ipv4 = 1; opts.ipv6 = 1; @@ -158,7 +169,7 @@ #ifdef ENABLE_CLI_REMOTETCPFWD if (nextisremote) { TRACE(("nextisremote true")) - addforward(argv[i], &cli_opts.remotefwds); + addforward(argv[i], cli_opts.remotefwds); nextisremote = 0; continue; } @@ -166,7 +177,7 @@ #ifdef ENABLE_CLI_LOCALTCPFWD if (nextislocal) { TRACE(("nextislocal true")) - addforward(argv[i], &cli_opts.localfwds); + addforward(argv[i], cli_opts.localfwds); nextislocal = 0; continue; } @@ -266,6 +277,11 @@ case 'I': next = &idle_timeout_arg; break; +#ifdef ENABLE_CLI_AGENTFWD + case 'A': + cli_opts.agent_fwd = 1; + break; +#endif #ifdef DEBUG_TRACE case 'v': debug_trace = 1; @@ -304,12 +320,8 @@ /* Either the hostname or commands */ - if (cli_opts.remotehost == NULL) { -#ifdef ENABLE_CLI_MULTIHOP - parse_multihop_hostname(argv[i], argv[0]); -#else - parse_hostname(argv[i]); -#endif + if (host_arg == NULL) { + host_arg = argv[i]; } else { /* this is part of the commands to send - after this we @@ -338,7 +350,7 @@ /* And now a few sanity checks and setup */ - if (cli_opts.remotehost == NULL) { + if (host_arg == NULL) { printhelp(); exit(EXIT_FAILURE); } @@ -369,15 +381,19 @@ } } if (keepalive_arg) { - if (m_str_to_uint(keepalive_arg, &opts.keepalive_secs) == DROPBEAR_FAILURE) { + unsigned int val; + if (m_str_to_uint(keepalive_arg, &val) == DROPBEAR_FAILURE) { dropbear_exit("Bad keepalive '%s'", keepalive_arg); } + opts.keepalive_secs = val; } if (idle_timeout_arg) { - if (m_str_to_uint(idle_timeout_arg, &opts.idle_timeout_secs) == DROPBEAR_FAILURE) { + unsigned int val; + if (m_str_to_uint(idle_timeout_arg, &val) == DROPBEAR_FAILURE) { dropbear_exit("Bad idle_timeout '%s'", idle_timeout_arg); } + opts.idle_timeout_secs = val; } #ifdef ENABLE_CLI_NETCAT @@ -385,36 +401,73 @@ dropbear_log(LOG_INFO, "Ignoring command '%s' in netcat mode", cli_opts.cmd); } #endif - + + /* The hostname gets set up last, since + * in multi-hop mode it will require knowledge + * of other flags such as -i */ +#ifdef ENABLE_CLI_MULTIHOP + parse_multihop_hostname(host_arg, argv[0]); +#else + parse_hostname(host_arg); +#endif } #ifdef ENABLE_CLI_PUBKEY_AUTH static void loadidentityfile(const char* filename) { - - struct SignKeyList * nextkey; sign_key *key; int keytype; key = new_sign_key(); keytype = DROPBEAR_SIGNKEY_ANY; if ( readhostkey(filename, key, &keytype) != DROPBEAR_SUCCESS ) { - fprintf(stderr, "Failed loading keyfile '%s'\n", filename); sign_key_free(key); - } else { - - nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList)); - nextkey->key = key; - nextkey->next = cli_opts.privkeys; - nextkey->type = keytype; - cli_opts.privkeys = nextkey; + key->type = keytype; + key->source = SIGNKEY_SOURCE_RAW_FILE; + key->filename = m_strdup(filename); + list_append(cli_opts.privkeys, key); } } #endif #ifdef ENABLE_CLI_MULTIHOP +static char* +multihop_passthrough_args() { + char *ret; + int total; + unsigned int len = 0; + m_list_elem *iter; + /* Fill out -i and -W options that make sense for all + * the intermediate processes */ + for (iter = cli_opts.privkeys->first; iter; iter = iter->next) + { + sign_key * key = (sign_key*)iter->item; + len += 3 + strlen(key->filename); + } + len += 20; // space for -W <size>, terminator. + ret = m_malloc(len); + total = 0; + + if (opts.recv_window != DEFAULT_RECV_WINDOW) + { + int written = snprintf(ret+total, len-total, "-W %d", opts.recv_window); + total += written; + } + + for (iter = cli_opts.privkeys->first; iter; iter = iter->next) + { + sign_key * key = (sign_key*)iter->item; + const size_t size = len - total; + int written = snprintf(ret+total, size, "-i %s", key->filename); + dropbear_assert((unsigned int)written < size); + total += written; + } + + return ret; +} + /* Sets up 'onion-forwarding' connections. This will spawn * a separate dbclient process for each hop. * As an example, if the cmdline is @@ -429,7 +482,8 @@ */ static void parse_multihop_hostname(const char* orighostarg, const char* argv0) { char *userhostarg = NULL; - char *last_hop = NULL;; + char *hostbuf = NULL; + char *last_hop = NULL; char *remainder = NULL; /* both scp and rsync parse a user@host argument @@ -441,11 +495,12 @@ && strchr(cli_opts.username, ',') && strchr(cli_opts.username, '@')) { unsigned int len = strlen(orighostarg) + strlen(cli_opts.username) + 2; - userhostarg = m_malloc(len); - snprintf(userhostarg, len, "%s@%s", cli_opts.username, orighostarg); + hostbuf = m_malloc(len); + snprintf(hostbuf, len, "%s@%s", cli_opts.username, orighostarg); } else { - userhostarg = m_strdup(orighostarg); + hostbuf = m_strdup(orighostarg); } + userhostarg = hostbuf; last_hop = strrchr(userhostarg, ','); if (last_hop) { @@ -463,19 +518,28 @@ if (last_hop) { /* Set up the proxycmd */ unsigned int cmd_len = 0; + char *passthrough_args = multihop_passthrough_args(); 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) + cmd_len = strlen(argv0) + strlen(remainder) + strlen(cli_opts.remotehost) + strlen(cli_opts.remoteport) - + strlen(argv0) + 30; + + strlen(passthrough_args) + + 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); + snprintf(cli_opts.proxycmd, cmd_len, "%s -B %s:%s %s %s", + argv0, cli_opts.remotehost, cli_opts.remoteport, + passthrough_args, remainder); +#ifndef DISABLE_ZLIB + /* The stream will be incompressible since it's encrypted. */ + opts.enable_compress = 0; +#endif + m_free(passthrough_args); } + m_free(hostbuf); } #endif /* !ENABLE_CLI_MULTIHOP */ @@ -566,14 +630,14 @@ #ifdef ENABLE_CLI_ANYTCPFWD /* Turn a "[listenaddr:]listenport:remoteaddr:remoteport" string into into a forwarding * set, and add it to the forwarding list */ -static void addforward(const char* origstr, struct TCPFwdList** fwdlist) { +static void addforward(const char* origstr, m_list *fwdlist) { char *part1 = NULL, *part2 = NULL, *part3 = NULL, *part4 = NULL; char * listenaddr = NULL; char * listenport = NULL; char * connectaddr = NULL; char * connectport = NULL; - struct TCPFwdList* newfwd = NULL; + struct TCPFwdEntry* newfwd = NULL; char * str = NULL; TRACE(("enter addforward")) @@ -618,7 +682,9 @@ connectport = part3; } - newfwd = (struct TCPFwdList*)m_malloc(sizeof(struct TCPFwdList)); + } + + newfwd = m_malloc(sizeof(struct TCPFwdEntry)); /* Now we check the ports - note that the port ints are unsigned, * the check later only checks for >= MAX_PORT */ @@ -646,8 +712,7 @@ } newfwd->have_reply = 0; - newfwd->next = *fwdlist; - *fwdlist = newfwd; + list_append(fwdlist, newfwd); TRACE(("leave addforward: done")) return;