comparison cli-runopts.c @ 1935:a7ad060707b6

Allow dbclient -J to be used with multihop Based on a patch from Hans Harder. This also tidies formatting and un-needed parts
author Matt Johnston <matt@ucc.asn.au>
date Fri, 01 Apr 2022 12:17:02 +0800
parents e093ddc5b585
children 4528afefe45d
comparison
equal deleted inserted replaced
1934:83b6a47759a8 1935:a7ad060707b6
529 #if DROPBEAR_CLI_MULTIHOP 529 #if DROPBEAR_CLI_MULTIHOP
530 530
531 static char* 531 static char*
532 multihop_passthrough_args() { 532 multihop_passthrough_args() {
533 char *ret; 533 char *ret;
534 int total; 534 unsigned int len, total;
535 unsigned int len = 0;
536 m_list_elem *iter; 535 m_list_elem *iter;
537 /* Fill out -i, -y, -W options that make sense for all 536 /* Fill out -i, -y, -W options that make sense for all
538 * the intermediate processes */ 537 * the intermediate processes */
538 len = 30; /* space for "-q -y -y -W <size>\0" */
539 #if DROPBEAR_CLI_PUBKEY_AUTH 539 #if DROPBEAR_CLI_PUBKEY_AUTH
540 for (iter = cli_opts.privkeys->first; iter; iter = iter->next) 540 for (iter = cli_opts.privkeys->first; iter; iter = iter->next)
541 { 541 {
542 sign_key * key = (sign_key*)iter->item; 542 sign_key * key = (sign_key*)iter->item;
543 len += 3 + strlen(key->filename); 543 len += 3 + strlen(key->filename);
544 } 544 }
545 #endif /* DROPBEAR_CLI_PUBKEY_AUTH */ 545 #endif /* DROPBEAR_CLI_PUBKEY_AUTH */
546 546 if (cli_opts.proxycmd) {
547 len += 30; /* space for -W <size>, terminator. */ 547 /* "-J 'cmd'" */
548 len += 6 + strlen(cli_opts.proxycmd);
549 }
550
548 ret = m_malloc(len); 551 ret = m_malloc(len);
549 total = 0; 552 total = 0;
550 553
551 if (cli_opts.quiet) 554 if (cli_opts.quiet) {
552 { 555 total += m_snprintf(ret+total, len-total, "-q ");
553 int written = snprintf(ret+total, len-total, "-q "); 556 }
554 total += written; 557
555 } 558 if (cli_opts.no_hostkey_check) {
556 559 total += m_snprintf(ret+total, len-total, "-y -y ");
557 if (cli_opts.no_hostkey_check) 560 } else if (cli_opts.always_accept_key) {
558 { 561 total += m_snprintf(ret+total, len-total, "-y ");
559 int written = snprintf(ret+total, len-total, "-y -y "); 562 }
560 total += written; 563
561 } 564 if (cli_opts.proxycmd) {
562 else if (cli_opts.always_accept_key) 565 total += m_snprintf(ret+total, len-total, "-J '%s' ", cli_opts.proxycmd);
563 { 566 }
564 int written = snprintf(ret+total, len-total, "-y "); 567
565 total += written; 568 if (opts.recv_window != DEFAULT_RECV_WINDOW) {
566 } 569 total += m_snprintf(ret+total, len-total, "-W %u ", opts.recv_window);
567
568 if (opts.recv_window != DEFAULT_RECV_WINDOW)
569 {
570 int written = snprintf(ret+total, len-total, "-W %u ", opts.recv_window);
571 total += written;
572 } 570 }
573 571
574 #if DROPBEAR_CLI_PUBKEY_AUTH 572 #if DROPBEAR_CLI_PUBKEY_AUTH
575 for (iter = cli_opts.privkeys->first; iter; iter = iter->next) 573 for (iter = cli_opts.privkeys->first; iter; iter = iter->next)
576 { 574 {
577 sign_key * key = (sign_key*)iter->item; 575 sign_key * key = (sign_key*)iter->item;
578 const size_t size = len - total; 576 total += m_snprintf(ret+total, len-total, "-i %s ", key->filename);
579 int written = snprintf(ret+total, size, "-i %s ", key->filename);
580 dropbear_assert((unsigned int)written < size);
581 total += written;
582 } 577 }
583 #endif /* DROPBEAR_CLI_PUBKEY_AUTH */ 578 #endif /* DROPBEAR_CLI_PUBKEY_AUTH */
584
585 /* if args were passed, total will be not zero, and it will have a space at the end, so remove that */
586 if (total > 0)
587 {
588 total--;
589 }
590 579
591 return ret; 580 return ret;
592 } 581 }
593 582
594 /* Sets up 'onion-forwarding' connections. This will spawn 583 /* Sets up 'onion-forwarding' connections. This will spawn
599 * dbclient -J "dbclient -B canyons:22 wrt,madako" canyons 588 * dbclient -J "dbclient -B canyons:22 wrt,madako" canyons
600 * and then the inner dbclient will recursively run: 589 * and then the inner dbclient will recursively run:
601 * dbclient -J "dbclient -B madako:22 wrt" madako 590 * dbclient -J "dbclient -B madako:22 wrt" madako
602 * etc for as many hosts as we want. 591 * etc for as many hosts as we want.
603 * 592 *
593 * Note that "-J" arguments aren't actually used, instead
594 * below sets cli_opts.proxycmd directly.
595 *
604 * Ports for hosts can be specified as host/port. 596 * Ports for hosts can be specified as host/port.
605 */ 597 */
606 static void parse_multihop_hostname(const char* orighostarg, const char* argv0) { 598 static void parse_multihop_hostname(const char* orighostarg, const char* argv0) {
607 char *userhostarg = NULL; 599 char *userhostarg = NULL;
608 char *hostbuf = NULL; 600 char *hostbuf = NULL;
617 if (cli_opts.username 609 if (cli_opts.username
618 && strchr(cli_opts.username, ',') 610 && strchr(cli_opts.username, ',')
619 && strchr(cli_opts.username, '@')) { 611 && strchr(cli_opts.username, '@')) {
620 unsigned int len = strlen(orighostarg) + strlen(cli_opts.username) + 2; 612 unsigned int len = strlen(orighostarg) + strlen(cli_opts.username) + 2;
621 hostbuf = m_malloc(len); 613 hostbuf = m_malloc(len);
622 snprintf(hostbuf, len, "%s@%s", cli_opts.username, orighostarg); 614 m_snprintf(hostbuf, len, "%s@%s", cli_opts.username, orighostarg);
623 } else { 615 } else {
624 hostbuf = m_strdup(orighostarg); 616 hostbuf = m_strdup(orighostarg);
625 } 617 }
626 userhostarg = hostbuf; 618 userhostarg = hostbuf;
627 619
640 632
641 if (last_hop) { 633 if (last_hop) {
642 /* Set up the proxycmd */ 634 /* Set up the proxycmd */
643 unsigned int cmd_len = 0; 635 unsigned int cmd_len = 0;
644 char *passthrough_args = multihop_passthrough_args(); 636 char *passthrough_args = multihop_passthrough_args();
645 if (cli_opts.proxycmd) {
646 dropbear_exit("-J can't be used with multihop mode");
647 }
648 if (cli_opts.remoteport == NULL) { 637 if (cli_opts.remoteport == NULL) {
649 cli_opts.remoteport = "22"; 638 cli_opts.remoteport = "22";
650 } 639 }
651 cmd_len = strlen(argv0) + strlen(remainder) 640 cmd_len = strlen(argv0) + strlen(remainder)
652 + strlen(cli_opts.remotehost) + strlen(cli_opts.remoteport) 641 + strlen(cli_opts.remotehost) + strlen(cli_opts.remoteport)
653 + strlen(passthrough_args) 642 + strlen(passthrough_args)
654 + 30; 643 + 30;
655 cli_opts.proxycmd = m_malloc(cmd_len); 644 /* replace proxycmd. old -J arguments have been copied
656 snprintf(cli_opts.proxycmd, cmd_len, "%s -B %s:%s %s %s", 645 to passthrough_args */
657 argv0, cli_opts.remotehost, cli_opts.remoteport, 646 cli_opts.proxycmd = m_realloc(cli_opts.proxycmd, cmd_len);
647 m_snprintf(cli_opts.proxycmd, cmd_len, "%s -B %s:%s %s %s",
648 argv0, cli_opts.remotehost, cli_opts.remoteport,
658 passthrough_args, remainder); 649 passthrough_args, remainder);
659 #ifndef DISABLE_ZLIB 650 #ifndef DISABLE_ZLIB
660 /* The stream will be incompressible since it's encrypted. */ 651 /* The stream will be incompressible since it's encrypted. */
661 opts.compress_mode = DROPBEAR_COMPRESS_OFF; 652 opts.compress_mode = DROPBEAR_COMPRESS_OFF;
662 #endif 653 #endif