summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2004-11-07 20:06:19 +1100
committerDarren Tucker <dtucker@zip.com.au>2004-11-07 20:06:19 +1100
commit7ebfc10884da0e430966cb323f57de17397f64bc (patch)
treecb4ab9a4f8cc8378a2c63ca3d46d2f94a2d5c724 /clientloop.c
parent2d963d87210c6a0c5eadfa5f02c808f6d983b47e (diff)
- djm@cvs.openbsd.org 2004/11/07 00:01:46
[clientloop.c clientloop.h ssh.1 ssh.c] add basic control of a running multiplex master connection; including the ability to check its status and request it to exit; ok markus@
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c86
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"
62RCSID("$OpenBSD: clientloop.c,v 1.133 2004/10/29 22:53:56 djm Exp $"); 62RCSID("$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);