comparison cli-runopts.c @ 544:9e51707cd6f2

- Make -i and -W pass through multihop arguments
author Matt Johnston <matt@ucc.asn.au>
date Fri, 12 Jun 2009 14:58:43 +0000
parents b151e6df683e
children 568638be7203
comparison
equal deleted inserted replaced
543:e12c9225acbd 544:9e51707cd6f2
89 DEFAULT_RECV_WINDOW, DEFAULT_KEEPALIVE, DEFAULT_IDLE_TIMEOUT); 89 DEFAULT_RECV_WINDOW, DEFAULT_KEEPALIVE, DEFAULT_IDLE_TIMEOUT);
90 90
91 } 91 }
92 92
93 void cli_getopts(int argc, char ** argv) { 93 void cli_getopts(int argc, char ** argv) {
94
95 unsigned int i, j; 94 unsigned int i, j;
96 char ** next = 0; 95 char ** next = 0;
97 unsigned int cmdlen; 96 unsigned int cmdlen;
98 #ifdef ENABLE_CLI_PUBKEY_AUTH 97 #ifdef ENABLE_CLI_PUBKEY_AUTH
99 int nextiskey = 0; /* A flag if the next argument is a keyfile */ 98 int nextiskey = 0; /* A flag if the next argument is a keyfile */
110 char* dummy = NULL; /* Not used for anything real */ 109 char* dummy = NULL; /* Not used for anything real */
111 110
112 char* recv_window_arg = NULL; 111 char* recv_window_arg = NULL;
113 char* keepalive_arg = NULL; 112 char* keepalive_arg = NULL;
114 char* idle_timeout_arg = NULL; 113 char* idle_timeout_arg = NULL;
114 char *host_arg = NULL;
115 115
116 /* see printhelp() for options */ 116 /* see printhelp() for options */
117 cli_opts.progname = argv[0]; 117 cli_opts.progname = argv[0];
118 cli_opts.remotehost = NULL; 118 cli_opts.remotehost = NULL;
119 cli_opts.remoteport = NULL; 119 cli_opts.remoteport = NULL;
302 } else { 302 } else {
303 TRACE(("non-flag arg: '%s'", argv[i])) 303 TRACE(("non-flag arg: '%s'", argv[i]))
304 304
305 /* Either the hostname or commands */ 305 /* Either the hostname or commands */
306 306
307 if (cli_opts.remotehost == NULL) { 307 if (host_arg == NULL) {
308 #ifdef ENABLE_CLI_MULTIHOP 308 host_arg = argv[i];
309 parse_multihop_hostname(argv[i], argv[0]);
310 #else
311 parse_hostname(argv[i]);
312 #endif
313 } else { 309 } else {
314 310
315 /* this is part of the commands to send - after this we 311 /* this is part of the commands to send - after this we
316 * don't parse any more options, and flags are sent as the 312 * don't parse any more options, and flags are sent as the
317 * command */ 313 * command */
336 } 332 }
337 } 333 }
338 334
339 /* And now a few sanity checks and setup */ 335 /* And now a few sanity checks and setup */
340 336
341 if (cli_opts.remotehost == NULL) { 337 if (host_arg == NULL) {
342 printhelp(); 338 printhelp();
343 exit(EXIT_FAILURE); 339 exit(EXIT_FAILURE);
344 } 340 }
345 341
346 if (cli_opts.remoteport == NULL) { 342 if (cli_opts.remoteport == NULL) {
383 #ifdef ENABLE_CLI_NETCAT 379 #ifdef ENABLE_CLI_NETCAT
384 if (cli_opts.cmd && cli_opts.netcat_host) { 380 if (cli_opts.cmd && cli_opts.netcat_host) {
385 dropbear_log(LOG_INFO, "Ignoring command '%s' in netcat mode", cli_opts.cmd); 381 dropbear_log(LOG_INFO, "Ignoring command '%s' in netcat mode", cli_opts.cmd);
386 } 382 }
387 #endif 383 #endif
388 384
385 /* The hostname gets set up last, since
386 * in multi-hop mode it will require knowledge
387 * of other flags such as -i */
388 #ifdef ENABLE_CLI_MULTIHOP
389 parse_multihop_hostname(host_arg, argv[0]);
390 #else
391 parse_hostname(host_arg);
392 #endif
389 } 393 }
390 394
391 #ifdef ENABLE_CLI_PUBKEY_AUTH 395 #ifdef ENABLE_CLI_PUBKEY_AUTH
392 static void loadidentityfile(const char* filename) { 396 static void loadidentityfile(const char* filename) {
393 397
396 int keytype; 400 int keytype;
397 401
398 key = new_sign_key(); 402 key = new_sign_key();
399 keytype = DROPBEAR_SIGNKEY_ANY; 403 keytype = DROPBEAR_SIGNKEY_ANY;
400 if ( readhostkey(filename, key, &keytype) != DROPBEAR_SUCCESS ) { 404 if ( readhostkey(filename, key, &keytype) != DROPBEAR_SUCCESS ) {
401
402 fprintf(stderr, "Failed loading keyfile '%s'\n", filename); 405 fprintf(stderr, "Failed loading keyfile '%s'\n", filename);
403 sign_key_free(key); 406 sign_key_free(key);
404
405 } else { 407 } else {
406
407 nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList)); 408 nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList));
408 nextkey->key = key; 409 nextkey->key = key;
410 nextkey->filename = m_strdup(filename);
409 nextkey->next = cli_opts.privkeys; 411 nextkey->next = cli_opts.privkeys;
410 nextkey->type = keytype; 412 nextkey->type = keytype;
411 cli_opts.privkeys = nextkey; 413 cli_opts.privkeys = nextkey;
412 } 414 }
413 } 415 }
414 #endif 416 #endif
415 417
416 #ifdef ENABLE_CLI_MULTIHOP 418 #ifdef ENABLE_CLI_MULTIHOP
419
420 static char*
421 multihop_passthrough_args() {
422 char *ret;
423 int total;
424 unsigned int len = 0;
425 struct SignKeyList *nextkey;
426 /* Fill out -i and -W options that make sense for all
427 * the intermediate processes */
428 for (nextkey = cli_opts.privkeys; nextkey; nextkey = nextkey->next)
429 {
430 len += 3 + strlen(nextkey->filename);
431 }
432 len += 20; // space for -W <size>, terminator.
433 ret = m_malloc(len);
434 total = 0;
435
436 if (opts.recv_window != DEFAULT_RECV_WINDOW)
437 {
438 int written = snprintf(ret+total, len-total, "-W %d", opts.recv_window);
439 total += written;
440 }
441
442 for (nextkey = cli_opts.privkeys; nextkey; nextkey = nextkey->next)
443 {
444 const size_t size = len - total;
445 int written = snprintf(ret+total, size, "-i %s", nextkey->filename);
446 dropbear_assert(written < size);
447 total += written;
448 }
449
450 return ret;
451 }
417 452
418 /* Sets up 'onion-forwarding' connections. This will spawn 453 /* Sets up 'onion-forwarding' connections. This will spawn
419 * a separate dbclient process for each hop. 454 * a separate dbclient process for each hop.
420 * As an example, if the cmdline is 455 * As an example, if the cmdline is
421 * dbclient wrt,madako,canyons 456 * dbclient wrt,madako,canyons
427 * 462 *
428 * Ports for hosts can be specified as host/port. 463 * Ports for hosts can be specified as host/port.
429 */ 464 */
430 static void parse_multihop_hostname(const char* orighostarg, const char* argv0) { 465 static void parse_multihop_hostname(const char* orighostarg, const char* argv0) {
431 char *userhostarg = NULL; 466 char *userhostarg = NULL;
467 char *hostbuf = NULL;
432 char *last_hop = NULL;; 468 char *last_hop = NULL;;
433 char *remainder = NULL; 469 char *remainder = NULL;
434 470
435 /* both scp and rsync parse a user@host argument 471 /* both scp and rsync parse a user@host argument
436 * and turn it into "-l user host". This breaks 472 * and turn it into "-l user host". This breaks
439 * though that should be fairly uncommon. */ 475 * though that should be fairly uncommon. */
440 if (cli_opts.username 476 if (cli_opts.username
441 && strchr(cli_opts.username, ',') 477 && strchr(cli_opts.username, ',')
442 && strchr(cli_opts.username, '@')) { 478 && strchr(cli_opts.username, '@')) {
443 unsigned int len = strlen(orighostarg) + strlen(cli_opts.username) + 2; 479 unsigned int len = strlen(orighostarg) + strlen(cli_opts.username) + 2;
444 userhostarg = m_malloc(len); 480 hostbuf = m_malloc(len);
445 snprintf(userhostarg, len, "%s@%s", cli_opts.username, orighostarg); 481 snprintf(hostbuf, len, "%s@%s", cli_opts.username, orighostarg);
446 } else { 482 } else {
447 userhostarg = m_strdup(orighostarg); 483 hostbuf = m_strdup(orighostarg);
448 } 484 }
485 userhostarg = hostbuf;
449 486
450 last_hop = strrchr(userhostarg, ','); 487 last_hop = strrchr(userhostarg, ',');
451 if (last_hop) { 488 if (last_hop) {
452 if (last_hop == userhostarg) { 489 if (last_hop == userhostarg) {
453 dropbear_exit("Bad multi-hop hostnames"); 490 dropbear_exit("Bad multi-hop hostnames");
461 parse_hostname(userhostarg); 498 parse_hostname(userhostarg);
462 499
463 if (last_hop) { 500 if (last_hop) {
464 /* Set up the proxycmd */ 501 /* Set up the proxycmd */
465 unsigned int cmd_len = 0; 502 unsigned int cmd_len = 0;
503 char *passthrough_args = multihop_passthrough_args();
466 if (cli_opts.proxycmd) { 504 if (cli_opts.proxycmd) {
467 dropbear_exit("-J can't be used with multihop mode"); 505 dropbear_exit("-J can't be used with multihop mode");
468 } 506 }
469 if (cli_opts.remoteport == NULL) { 507 if (cli_opts.remoteport == NULL) {
470 cli_opts.remoteport = "22"; 508 cli_opts.remoteport = "22";
471 } 509 }
472 cmd_len = strlen(remainder) 510 cmd_len = strlen(argv0) + strlen(remainder)
473 + strlen(cli_opts.remotehost) + strlen(cli_opts.remoteport) 511 + strlen(cli_opts.remotehost) + strlen(cli_opts.remoteport)
474 + strlen(argv0) + 30; 512 + strlen(passthrough_args)
513 + 30;
475 cli_opts.proxycmd = m_malloc(cmd_len); 514 cli_opts.proxycmd = m_malloc(cmd_len);
476 snprintf(cli_opts.proxycmd, cmd_len, "%s -B %s:%s %s", 515 snprintf(cli_opts.proxycmd, cmd_len, "%s -B %s:%s %s %s",
477 argv0, cli_opts.remotehost, cli_opts.remoteport, remainder); 516 argv0, cli_opts.remotehost, cli_opts.remoteport,
478 } 517 passthrough_args, remainder);
518 m_free(passthrough_args);
519 }
520 m_free(hostbuf);
479 } 521 }
480 #endif /* !ENABLE_CLI_MULTIHOP */ 522 #endif /* !ENABLE_CLI_MULTIHOP */
481 523
482 /* Parses a [user@]hostname[/port] argument. */ 524 /* Parses a [user@]hostname[/port] argument. */
483 static void parse_hostname(const char* orighostarg) { 525 static void parse_hostname(const char* orighostarg) {