summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2008-06-13 10:24:03 +1000
committerDarren Tucker <dtucker@zip.com.au>2008-06-13 10:24:03 +1000
commitca19bfe2546f280f10795bae5e0ec296623de880 (patch)
treeaaee26713bb8de916dd020657554c076d99dbc8f /mux.c
parentf8b7eb7c3c77625845f4e2a844cc57c0496d414e (diff)
- djm@cvs.openbsd.org 2008/06/13 00:16:49
[mux.c] fall back to creating a new TCP connection on most multiplexing errors (socket connect fail, invalid version, refused permittion, corrupted messages, etc.); bz #1329 ok dtucker@
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c72
1 files changed, 54 insertions, 18 deletions
diff --git a/mux.c b/mux.c
index 8f7bfb793..aaa3a4ee2 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.4 2008/06/12 15:19:17 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.5 2008/06/13 00:16:49 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -144,10 +144,16 @@ muxserver_listen(void)
144 old_umask = umask(0177); 144 old_umask = umask(0177);
145 if (bind(muxserver_sock, (struct sockaddr *)&addr, addr_len) == -1) { 145 if (bind(muxserver_sock, (struct sockaddr *)&addr, addr_len) == -1) {
146 muxserver_sock = -1; 146 muxserver_sock = -1;
147 if (errno == EINVAL || errno == EADDRINUSE) 147 if (errno == EINVAL || errno == EADDRINUSE) {
148 fatal("ControlSocket %s already exists", 148 error("ControlSocket %s already exists, "
149 options.control_path); 149 "disabling multiplexing", options.control_path);
150 else 150 close(muxserver_sock);
151 muxserver_sock = -1;
152 xfree(options.control_path);
153 options.control_path = NULL;
154 options.control_master = SSHCTL_MASTER_NO;
155 return;
156 } else
151 fatal("%s bind(): %s", __func__, strerror(errno)); 157 fatal("%s bind(): %s", __func__, strerror(errno));
152 } 158 }
153 umask(old_umask); 159 umask(old_umask);
@@ -500,7 +506,7 @@ muxclient(const char *path)
500 Buffer m; 506 Buffer m;
501 char *term; 507 char *term;
502 extern char **environ; 508 extern char **environ;
503 u_int flags; 509 u_int allowed, flags;
504 510
505 if (muxclient_command == 0) 511 if (muxclient_command == 0)
506 muxclient_command = SSHMUX_COMMAND_OPEN; 512 muxclient_command = SSHMUX_COMMAND_OPEN;
@@ -571,17 +577,38 @@ muxclient(const char *path)
571 /* Send our command to server */ 577 /* Send our command to server */
572 buffer_put_int(&m, muxclient_command); 578 buffer_put_int(&m, muxclient_command);
573 buffer_put_int(&m, flags); 579 buffer_put_int(&m, flags);
574 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) 580 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
575 fatal("%s: msg_send", __func__); 581 error("%s: msg_send", __func__);
582 muxerr:
583 close(sock);
584 buffer_free(&m);
585 if (muxclient_command != SSHMUX_COMMAND_OPEN)
586 cleanup_exit(255);
587 logit("Falling back to non-multiplexed connection");
588 xfree(options.control_path);
589 options.control_path = NULL;
590 options.control_master = SSHCTL_MASTER_NO;
591 return;
592 }
576 buffer_clear(&m); 593 buffer_clear(&m);
577 594
578 /* Get authorisation status and PID of controlee */ 595 /* Get authorisation status and PID of controlee */
579 if (ssh_msg_recv(sock, &m) == -1) 596 if (ssh_msg_recv(sock, &m) == -1) {
580 fatal("%s: msg_recv", __func__); 597 error("%s: msg_recv", __func__);
581 if (buffer_get_char(&m) != SSHMUX_VER) 598 goto muxerr;
582 fatal("%s: wrong version", __func__); 599 }
583 if (buffer_get_int(&m) != 1) 600 if (buffer_get_char(&m) != SSHMUX_VER) {
584 fatal("Connection to master denied"); 601 error("%s: wrong version", __func__);
602 goto muxerr;
603 }
604 if (buffer_get_int_ret(&allowed, &m) != 0) {
605 error("%s: bad server reply", __func__);
606 goto muxerr;
607 }
608 if (allowed != 1) {
609 error("Connection to master denied");
610 goto muxerr;
611 }
585 muxserver_pid = buffer_get_int(&m); 612 muxserver_pid = buffer_get_int(&m);
586 613
587 buffer_clear(&m); 614 buffer_clear(&m);
@@ -625,13 +652,22 @@ muxclient(const char *path)
625 fatal("unrecognised muxclient_command %d", muxclient_command); 652 fatal("unrecognised muxclient_command %d", muxclient_command);
626 } 653 }
627 654
628 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) 655 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
629 fatal("%s: msg_send", __func__); 656 error("%s: msg_send", __func__);
657 goto muxerr;
658 }
630 659
631 if (mm_send_fd(sock, STDIN_FILENO) == -1 || 660 if (mm_send_fd(sock, STDIN_FILENO) == -1 ||
632 mm_send_fd(sock, STDOUT_FILENO) == -1 || 661 mm_send_fd(sock, STDOUT_FILENO) == -1 ||
633 mm_send_fd(sock, STDERR_FILENO) == -1) 662 mm_send_fd(sock, STDERR_FILENO) == -1) {
634 fatal("%s: send fds failed", __func__); 663 error("%s: send fds failed", __func__);
664 goto muxerr;
665 }
666
667 /*
668 * Mux errors are non-recoverable from this point as the master
669 * has ownership of the session now.
670 */
635 671
636 /* Wait for reply, so master has a chance to gather ttymodes */ 672 /* Wait for reply, so master has a chance to gather ttymodes */
637 buffer_clear(&m); 673 buffer_clear(&m);