diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 86 |
1 files changed, 71 insertions, 15 deletions
diff --git a/clientloop.c b/clientloop.c index d77337b82..033a98a5b 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -59,7 +59,7 @@ | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "includes.h" | 61 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.133 2004/10/29 22:53:56 djm Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.134 2004/11/07 00:01:46 djm Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -561,7 +561,7 @@ client_process_control(fd_set * readset) | |||
561 | struct sockaddr_storage addr; | 561 | struct sockaddr_storage addr; |
562 | struct confirm_ctx *cctx; | 562 | struct confirm_ctx *cctx; |
563 | char *cmd; | 563 | char *cmd; |
564 | u_int len, env_len; | 564 | u_int len, env_len, command, flags; |
565 | uid_t euid; | 565 | uid_t euid; |
566 | gid_t egid; | 566 | gid_t egid; |
567 | 567 | ||
@@ -591,24 +591,74 @@ client_process_control(fd_set * readset) | |||
591 | return; | 591 | return; |
592 | } | 592 | } |
593 | 593 | ||
594 | allowed = 1; | ||
595 | if (options.control_master == 2) | ||
596 | allowed = ask_permission("Allow shared connection to %s? ", | ||
597 | host); | ||
598 | |||
599 | unset_nonblock(client_fd); | 594 | unset_nonblock(client_fd); |
600 | 595 | ||
596 | /* Read command */ | ||
601 | buffer_init(&m); | 597 | buffer_init(&m); |
598 | if (ssh_msg_recv(client_fd, &m) == -1) { | ||
599 | error("%s: client msg_recv failed", __func__); | ||
600 | close(client_fd); | ||
601 | buffer_free(&m); | ||
602 | return; | ||
603 | } | ||
604 | if ((ver = buffer_get_char(&m)) != 1) { | ||
605 | error("%s: wrong client version %d", __func__, ver); | ||
606 | buffer_free(&m); | ||
607 | close(client_fd); | ||
608 | return; | ||
609 | } | ||
610 | |||
611 | allowed = 1; | ||
612 | command = buffer_get_int(&m); | ||
613 | flags = buffer_get_int(&m); | ||
614 | |||
615 | buffer_clear(&m); | ||
602 | 616 | ||
617 | switch (command) { | ||
618 | case SSHMUX_COMMAND_OPEN: | ||
619 | if (options.control_master == 2) | ||
620 | allowed = ask_permission("Allow shared connection " | ||
621 | "to %s? ", host); | ||
622 | /* continue below */ | ||
623 | break; | ||
624 | case SSHMUX_COMMAND_TERMINATE: | ||
625 | if (options.control_master == 2) | ||
626 | allowed = ask_permission("Terminate shared connection " | ||
627 | "to %s? ", host); | ||
628 | if (allowed) | ||
629 | quit_pending = 1; | ||
630 | /* FALLTHROUGH */ | ||
631 | case SSHMUX_COMMAND_ALIVE_CHECK: | ||
632 | /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */ | ||
633 | buffer_clear(&m); | ||
634 | buffer_put_int(&m, allowed); | ||
635 | buffer_put_int(&m, getpid()); | ||
636 | if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { | ||
637 | error("%s: client msg_send failed", __func__); | ||
638 | close(client_fd); | ||
639 | buffer_free(&m); | ||
640 | return; | ||
641 | } | ||
642 | buffer_free(&m); | ||
643 | close(client_fd); | ||
644 | return; | ||
645 | default: | ||
646 | error("Unsupported command %d", command); | ||
647 | buffer_free(&m); | ||
648 | close(client_fd); | ||
649 | return; | ||
650 | } | ||
651 | |||
652 | /* Reply for SSHMUX_COMMAND_OPEN */ | ||
653 | buffer_clear(&m); | ||
603 | buffer_put_int(&m, allowed); | 654 | buffer_put_int(&m, allowed); |
604 | buffer_put_int(&m, getpid()); | 655 | buffer_put_int(&m, getpid()); |
605 | if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { | 656 | if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { |
606 | error("%s: client msg_send failed", __func__); | 657 | error("%s: client msg_send failed", __func__); |
607 | close(client_fd); | 658 | close(client_fd); |
608 | buffer_free(&m); | 659 | buffer_free(&m); |
609 | return; | 660 | return; |
610 | } | 661 | } |
611 | buffer_clear(&m); | ||
612 | 662 | ||
613 | if (!allowed) { | 663 | if (!allowed) { |
614 | error("Refused control connection"); | 664 | error("Refused control connection"); |
@@ -617,14 +667,14 @@ client_process_control(fd_set * readset) | |||
617 | return; | 667 | return; |
618 | } | 668 | } |
619 | 669 | ||
670 | buffer_clear(&m); | ||
620 | if (ssh_msg_recv(client_fd, &m) == -1) { | 671 | if (ssh_msg_recv(client_fd, &m) == -1) { |
621 | error("%s: client msg_recv failed", __func__); | 672 | error("%s: client msg_recv failed", __func__); |
622 | close(client_fd); | 673 | close(client_fd); |
623 | buffer_free(&m); | 674 | buffer_free(&m); |
624 | return; | 675 | return; |
625 | } | 676 | } |
626 | 677 | if ((ver = buffer_get_char(&m)) != 1) { | |
627 | if ((ver = buffer_get_char(&m)) != 0) { | ||
628 | error("%s: wrong client version %d", __func__, ver); | 678 | error("%s: wrong client version %d", __func__, ver); |
629 | buffer_free(&m); | 679 | buffer_free(&m); |
630 | close(client_fd); | 680 | close(client_fd); |
@@ -633,9 +683,8 @@ client_process_control(fd_set * readset) | |||
633 | 683 | ||
634 | cctx = xmalloc(sizeof(*cctx)); | 684 | cctx = xmalloc(sizeof(*cctx)); |
635 | memset(cctx, 0, sizeof(*cctx)); | 685 | memset(cctx, 0, sizeof(*cctx)); |
636 | 686 | cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; | |
637 | cctx->want_tty = buffer_get_int(&m); | 687 | cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; |
638 | cctx->want_subsys = buffer_get_int(&m); | ||
639 | cctx->term = buffer_get_string(&m, &len); | 688 | cctx->term = buffer_get_string(&m, &len); |
640 | 689 | ||
641 | cmd = buffer_get_string(&m, &len); | 690 | cmd = buffer_get_string(&m, &len); |
@@ -667,14 +716,21 @@ client_process_control(fd_set * readset) | |||
667 | if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) | 716 | if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) |
668 | error("%s: tcgetattr: %s", __func__, strerror(errno)); | 717 | error("%s: tcgetattr: %s", __func__, strerror(errno)); |
669 | 718 | ||
719 | /* This roundtrip is just for synchronisation of ttymodes */ | ||
670 | buffer_clear(&m); | 720 | buffer_clear(&m); |
671 | if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { | 721 | if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { |
672 | error("%s: client msg_send failed", __func__); | 722 | error("%s: client msg_send failed", __func__); |
673 | close(client_fd); | 723 | close(client_fd); |
674 | close(new_fd[0]); | 724 | close(new_fd[0]); |
675 | close(new_fd[1]); | 725 | close(new_fd[1]); |
676 | close(new_fd[2]); | 726 | close(new_fd[2]); |
677 | buffer_free(&m); | 727 | buffer_free(&m); |
728 | xfree(cctx->term); | ||
729 | if (env_len != 0) { | ||
730 | for (i = 0; i < env_len; i++) | ||
731 | xfree(cctx->env[i]); | ||
732 | xfree(cctx->env); | ||
733 | } | ||
678 | return; | 734 | return; |
679 | } | 735 | } |
680 | buffer_free(&m); | 736 | buffer_free(&m); |