Mercurial > dropbear
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) { |