summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-10-07 13:33:15 +0100
committerColin Watson <cjwatson@debian.org>2014-10-07 14:27:30 +0100
commitf0b009aea83e9ff3a50be30f51012099a5143c16 (patch)
tree3825e6f7e3b7ea4481d06ed89aba9a7a95150df5 /mux.c
parent47f0bad4330b16ec3bad870fcf9839c196e42c12 (diff)
parent762c062828f5a8f6ed189ed6e44ad38fd92f8b36 (diff)
Merge 6.7p1.
* New upstream release (http://www.openssh.com/txt/release-6.7): - sshd(8): The default set of ciphers and MACs has been altered to remove unsafe algorithms. In particular, CBC ciphers and arcfour* are disabled by default. The full set of algorithms remains available if configured explicitly via the Ciphers and MACs sshd_config options. - ssh(1), sshd(8): Add support for Unix domain socket forwarding. A remote TCP port may be forwarded to a local Unix domain socket and vice versa or both ends may be a Unix domain socket (closes: #236718). - ssh(1), ssh-keygen(1): Add support for SSHFP DNS records for ED25519 key types. - sftp(1): Allow resumption of interrupted uploads. - ssh(1): When rekeying, skip file/DNS lookups of the hostkey if it is the same as the one sent during initial key exchange. - sshd(8): Allow explicit ::1 and 127.0.0.1 forwarding bind addresses when GatewayPorts=no; allows client to choose address family. - sshd(8): Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is executed, mirroring the no-user-rc authorized_keys option. - ssh(1): Add a %C escape sequence for LocalCommand and ControlPath that expands to a unique identifer based on a hash of the tuple of (local host, remote user, hostname, port). Helps avoid exceeding miserly pathname limits for Unix domain sockets in multiplexing control paths. - sshd(8): Make the "Too many authentication failures" message include the user, source address, port and protocol in a format similar to the authentication success / failure messages. - Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC when it is available. It considers time spent suspended, thereby ensuring timeouts (e.g. for expiring agent keys) fire correctly (closes: #734553). - Use prctl() to prevent sftp-server from accessing /proc/self/{mem,maps}. * Restore TCP wrappers support, removed upstream in 6.7. It is true that dropping this reduces preauth attack surface in sshd. On the other hand, this support seems to be quite widely used, and abruptly dropping it (from the perspective of users who don't read openssh-unix-dev) could easily cause more serious problems in practice. It's not entirely clear what the right long-term answer for Debian is, but it at least probably doesn't involve dropping this feature shortly before a freeze. * Replace patch to disable OpenSSL version check with an updated version of Kurt Roeckx's patch from #732940 to just avoid checking the status field.
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c275
1 files changed, 180 insertions, 95 deletions
diff --git a/mux.c b/mux.c
index 882fa61b5..48f7a050f 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.44 2013/07/12 00:19:58 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.48 2014/07/17 07:22:19 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 *
@@ -105,6 +105,11 @@ struct mux_session_confirm_ctx {
105 u_int rid; 105 u_int rid;
106}; 106};
107 107
108/* Context for stdio fwd open confirmation callback */
109struct mux_stdio_confirm_ctx {
110 u_int rid;
111};
112
108/* Context for global channel callback */ 113/* Context for global channel callback */
109struct mux_channel_confirm_ctx { 114struct mux_channel_confirm_ctx {
110 u_int cid; /* channel id */ 115 u_int cid; /* channel id */
@@ -157,6 +162,7 @@ struct mux_master_state {
157#define MUX_FWD_DYNAMIC 3 162#define MUX_FWD_DYNAMIC 3
158 163
159static void mux_session_confirm(int, int, void *); 164static void mux_session_confirm(int, int, void *);
165static void mux_stdio_confirm(int, int, void *);
160 166
161static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); 167static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *);
162static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); 168static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *);
@@ -509,29 +515,33 @@ process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r)
509} 515}
510 516
511static char * 517static char *
512format_forward(u_int ftype, Forward *fwd) 518format_forward(u_int ftype, struct Forward *fwd)
513{ 519{
514 char *ret; 520 char *ret;
515 521
516 switch (ftype) { 522 switch (ftype) {
517 case MUX_FWD_LOCAL: 523 case MUX_FWD_LOCAL:
518 xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d", 524 xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",
525 (fwd->listen_path != NULL) ? fwd->listen_path :
519 (fwd->listen_host == NULL) ? 526 (fwd->listen_host == NULL) ?
520 (options.gateway_ports ? "*" : "LOCALHOST") : 527 (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
521 fwd->listen_host, fwd->listen_port, 528 fwd->listen_host, fwd->listen_port,
529 (fwd->connect_path != NULL) ? fwd->connect_path :
522 fwd->connect_host, fwd->connect_port); 530 fwd->connect_host, fwd->connect_port);
523 break; 531 break;
524 case MUX_FWD_DYNAMIC: 532 case MUX_FWD_DYNAMIC:
525 xasprintf(&ret, "dynamic forward %.200s:%d -> *", 533 xasprintf(&ret, "dynamic forward %.200s:%d -> *",
526 (fwd->listen_host == NULL) ? 534 (fwd->listen_host == NULL) ?
527 (options.gateway_ports ? "*" : "LOCALHOST") : 535 (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
528 fwd->listen_host, fwd->listen_port); 536 fwd->listen_host, fwd->listen_port);
529 break; 537 break;
530 case MUX_FWD_REMOTE: 538 case MUX_FWD_REMOTE:
531 xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d", 539 xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",
540 (fwd->listen_path != NULL) ? fwd->listen_path :
532 (fwd->listen_host == NULL) ? 541 (fwd->listen_host == NULL) ?
533 "LOCALHOST" : fwd->listen_host, 542 "LOCALHOST" : fwd->listen_host,
534 fwd->listen_port, 543 fwd->listen_port,
544 (fwd->connect_path != NULL) ? fwd->connect_path :
535 fwd->connect_host, fwd->connect_port); 545 fwd->connect_host, fwd->connect_port);
536 break; 546 break;
537 default: 547 default:
@@ -551,14 +561,18 @@ compare_host(const char *a, const char *b)
551} 561}
552 562
553static int 563static int
554compare_forward(Forward *a, Forward *b) 564compare_forward(struct Forward *a, struct Forward *b)
555{ 565{
556 if (!compare_host(a->listen_host, b->listen_host)) 566 if (!compare_host(a->listen_host, b->listen_host))
557 return 0; 567 return 0;
568 if (!compare_host(a->listen_path, b->listen_path))
569 return 0;
558 if (a->listen_port != b->listen_port) 570 if (a->listen_port != b->listen_port)
559 return 0; 571 return 0;
560 if (!compare_host(a->connect_host, b->connect_host)) 572 if (!compare_host(a->connect_host, b->connect_host))
561 return 0; 573 return 0;
574 if (!compare_host(a->connect_path, b->connect_path))
575 return 0;
562 if (a->connect_port != b->connect_port) 576 if (a->connect_port != b->connect_port)
563 return 0; 577 return 0;
564 578
@@ -570,7 +584,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
570{ 584{
571 struct mux_channel_confirm_ctx *fctx = ctxt; 585 struct mux_channel_confirm_ctx *fctx = ctxt;
572 char *failmsg = NULL; 586 char *failmsg = NULL;
573 Forward *rfwd; 587 struct Forward *rfwd;
574 Channel *c; 588 Channel *c;
575 Buffer out; 589 Buffer out;
576 590
@@ -587,7 +601,8 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
587 rfwd = &options.remote_forwards[fctx->fid]; 601 rfwd = &options.remote_forwards[fctx->fid];
588 debug("%s: %s for: listen %d, connect %s:%d", __func__, 602 debug("%s: %s for: listen %d, connect %s:%d", __func__,
589 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 603 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
590 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); 604 rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :
605 rfwd->connect_host, rfwd->connect_port);
591 if (type == SSH2_MSG_REQUEST_SUCCESS) { 606 if (type == SSH2_MSG_REQUEST_SUCCESS) {
592 if (rfwd->listen_port == 0) { 607 if (rfwd->listen_port == 0) {
593 rfwd->allocated_port = packet_get_int(); 608 rfwd->allocated_port = packet_get_int();
@@ -607,8 +622,12 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
607 } else { 622 } else {
608 if (rfwd->listen_port == 0) 623 if (rfwd->listen_port == 0)
609 channel_update_permitted_opens(rfwd->handle, -1); 624 channel_update_permitted_opens(rfwd->handle, -1);
610 xasprintf(&failmsg, "remote port forwarding failed for " 625 if (rfwd->listen_path != NULL)
611 "listen port %d", rfwd->listen_port); 626 xasprintf(&failmsg, "remote port forwarding failed for "
627 "listen path %s", rfwd->listen_path);
628 else
629 xasprintf(&failmsg, "remote port forwarding failed for "
630 "listen port %d", rfwd->listen_port);
612 } 631 }
613 fail: 632 fail:
614 error("%s: %s", __func__, failmsg); 633 error("%s: %s", __func__, failmsg);
@@ -627,34 +646,46 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
627static int 646static int
628process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 647process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
629{ 648{
630 Forward fwd; 649 struct Forward fwd;
631 char *fwd_desc = NULL; 650 char *fwd_desc = NULL;
651 char *listen_addr, *connect_addr;
632 u_int ftype; 652 u_int ftype;
633 u_int lport, cport; 653 u_int lport, cport;
634 int i, ret = 0, freefwd = 1; 654 int i, ret = 0, freefwd = 1;
635 655
636 fwd.listen_host = fwd.connect_host = NULL; 656 /* XXX - lport/cport check redundant */
637 if (buffer_get_int_ret(&ftype, m) != 0 || 657 if (buffer_get_int_ret(&ftype, m) != 0 ||
638 (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || 658 (listen_addr = buffer_get_string_ret(m, NULL)) == NULL ||
639 buffer_get_int_ret(&lport, m) != 0 || 659 buffer_get_int_ret(&lport, m) != 0 ||
640 (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || 660 (connect_addr = buffer_get_string_ret(m, NULL)) == NULL ||
641 buffer_get_int_ret(&cport, m) != 0 || 661 buffer_get_int_ret(&cport, m) != 0 ||
642 lport > 65535 || cport > 65535) { 662 (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
663 (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
643 error("%s: malformed message", __func__); 664 error("%s: malformed message", __func__);
644 ret = -1; 665 ret = -1;
645 goto out; 666 goto out;
646 } 667 }
647 fwd.listen_port = lport; 668 if (*listen_addr == '\0') {
648 fwd.connect_port = cport; 669 free(listen_addr);
649 if (*fwd.listen_host == '\0') { 670 listen_addr = NULL;
650 free(fwd.listen_host);
651 fwd.listen_host = NULL;
652 } 671 }
653 if (*fwd.connect_host == '\0') { 672 if (*connect_addr == '\0') {
654 free(fwd.connect_host); 673 free(connect_addr);
655 fwd.connect_host = NULL; 674 connect_addr = NULL;
656 } 675 }
657 676
677 memset(&fwd, 0, sizeof(fwd));
678 fwd.listen_port = lport;
679 if (fwd.listen_port == PORT_STREAMLOCAL)
680 fwd.listen_path = listen_addr;
681 else
682 fwd.listen_host = listen_addr;
683 fwd.connect_port = cport;
684 if (fwd.connect_port == PORT_STREAMLOCAL)
685 fwd.connect_path = connect_addr;
686 else
687 fwd.connect_host = connect_addr;
688
658 debug2("%s: channel %d: request %s", __func__, c->self, 689 debug2("%s: channel %d: request %s", __func__, c->self,
659 (fwd_desc = format_forward(ftype, &fwd))); 690 (fwd_desc = format_forward(ftype, &fwd)));
660 691
@@ -662,25 +693,30 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
662 ftype != MUX_FWD_DYNAMIC) { 693 ftype != MUX_FWD_DYNAMIC) {
663 logit("%s: invalid forwarding type %u", __func__, ftype); 694 logit("%s: invalid forwarding type %u", __func__, ftype);
664 invalid: 695 invalid:
665 free(fwd.listen_host); 696 free(listen_addr);
666 free(fwd.connect_host); 697 free(connect_addr);
667 buffer_put_int(r, MUX_S_FAILURE); 698 buffer_put_int(r, MUX_S_FAILURE);
668 buffer_put_int(r, rid); 699 buffer_put_int(r, rid);
669 buffer_put_cstring(r, "Invalid forwarding request"); 700 buffer_put_cstring(r, "Invalid forwarding request");
670 return 0; 701 return 0;
671 } 702 }
672 if (fwd.listen_port >= 65536) { 703 if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {
704 logit("%s: streamlocal and dynamic forwards "
705 "are mutually exclusive", __func__);
706 goto invalid;
707 }
708 if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) {
673 logit("%s: invalid listen port %u", __func__, 709 logit("%s: invalid listen port %u", __func__,
674 fwd.listen_port); 710 fwd.listen_port);
675 goto invalid; 711 goto invalid;
676 } 712 }
677 if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC && 713 if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536)
678 ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { 714 || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
679 logit("%s: invalid connect port %u", __func__, 715 logit("%s: invalid connect port %u", __func__,
680 fwd.connect_port); 716 fwd.connect_port);
681 goto invalid; 717 goto invalid;
682 } 718 }
683 if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) { 719 if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) {
684 logit("%s: missing connect host", __func__); 720 logit("%s: missing connect host", __func__);
685 goto invalid; 721 goto invalid;
686 } 722 }
@@ -731,9 +767,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
731 } 767 }
732 768
733 if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { 769 if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
734 if (!channel_setup_local_fwd_listener(fwd.listen_host, 770 if (!channel_setup_local_fwd_listener(&fwd,
735 fwd.listen_port, fwd.connect_host, fwd.connect_port, 771 &options.fwd_opts)) {
736 options.gateway_ports)) {
737 fail: 772 fail:
738 logit("slave-requested %s failed", fwd_desc); 773 logit("slave-requested %s failed", fwd_desc);
739 buffer_put_int(r, MUX_S_FAILURE); 774 buffer_put_int(r, MUX_S_FAILURE);
@@ -746,8 +781,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
746 } else { 781 } else {
747 struct mux_channel_confirm_ctx *fctx; 782 struct mux_channel_confirm_ctx *fctx;
748 783
749 fwd.handle = channel_request_remote_forwarding(fwd.listen_host, 784 fwd.handle = channel_request_remote_forwarding(&fwd);
750 fwd.listen_port, fwd.connect_host, fwd.connect_port);
751 if (fwd.handle < 0) 785 if (fwd.handle < 0)
752 goto fail; 786 goto fail;
753 add_remote_forward(&options, &fwd); 787 add_remote_forward(&options, &fwd);
@@ -768,7 +802,9 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
768 free(fwd_desc); 802 free(fwd_desc);
769 if (freefwd) { 803 if (freefwd) {
770 free(fwd.listen_host); 804 free(fwd.listen_host);
805 free(fwd.listen_path);
771 free(fwd.connect_host); 806 free(fwd.connect_host);
807 free(fwd.connect_path);
772 } 808 }
773 return ret; 809 return ret;
774} 810}
@@ -776,36 +812,47 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
776static int 812static int
777process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 813process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
778{ 814{
779 Forward fwd, *found_fwd; 815 struct Forward fwd, *found_fwd;
780 char *fwd_desc = NULL; 816 char *fwd_desc = NULL;
781 const char *error_reason = NULL; 817 const char *error_reason = NULL;
818 char *listen_addr = NULL, *connect_addr = NULL;
782 u_int ftype; 819 u_int ftype;
783 int i, listen_port, ret = 0; 820 int i, ret = 0;
784 u_int lport, cport; 821 u_int lport, cport;
785 822
786 fwd.listen_host = fwd.connect_host = NULL;
787 if (buffer_get_int_ret(&ftype, m) != 0 || 823 if (buffer_get_int_ret(&ftype, m) != 0 ||
788 (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || 824 (listen_addr = buffer_get_string_ret(m, NULL)) == NULL ||
789 buffer_get_int_ret(&lport, m) != 0 || 825 buffer_get_int_ret(&lport, m) != 0 ||
790 (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || 826 (connect_addr = buffer_get_string_ret(m, NULL)) == NULL ||
791 buffer_get_int_ret(&cport, m) != 0 || 827 buffer_get_int_ret(&cport, m) != 0 ||
792 lport > 65535 || cport > 65535) { 828 (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
829 (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
793 error("%s: malformed message", __func__); 830 error("%s: malformed message", __func__);
794 ret = -1; 831 ret = -1;
795 goto out; 832 goto out;
796 } 833 }
797 fwd.listen_port = lport;
798 fwd.connect_port = cport;
799 834
800 if (*fwd.listen_host == '\0') { 835 if (*listen_addr == '\0') {
801 free(fwd.listen_host); 836 free(listen_addr);
802 fwd.listen_host = NULL; 837 listen_addr = NULL;
803 } 838 }
804 if (*fwd.connect_host == '\0') { 839 if (*connect_addr == '\0') {
805 free(fwd.connect_host); 840 free(connect_addr);
806 fwd.connect_host = NULL; 841 connect_addr = NULL;
807 } 842 }
808 843
844 memset(&fwd, 0, sizeof(fwd));
845 fwd.listen_port = lport;
846 if (fwd.listen_port == PORT_STREAMLOCAL)
847 fwd.listen_path = listen_addr;
848 else
849 fwd.listen_host = listen_addr;
850 fwd.connect_port = cport;
851 if (fwd.connect_port == PORT_STREAMLOCAL)
852 fwd.connect_path = connect_addr;
853 else
854 fwd.connect_host = connect_addr;
855
809 debug2("%s: channel %d: request cancel %s", __func__, c->self, 856 debug2("%s: channel %d: request cancel %s", __func__, c->self,
810 (fwd_desc = format_forward(ftype, &fwd))); 857 (fwd_desc = format_forward(ftype, &fwd)));
811 858
@@ -840,18 +887,14 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
840 * This shouldn't fail unless we confused the host/port 887 * This shouldn't fail unless we confused the host/port
841 * between options.remote_forwards and permitted_opens. 888 * between options.remote_forwards and permitted_opens.
842 * However, for dynamic allocated listen ports we need 889 * However, for dynamic allocated listen ports we need
843 * to lookup the actual listen port. 890 * to use the actual listen port.
844 */ 891 */
845 listen_port = (fwd.listen_port == 0) ? 892 if (channel_request_rforward_cancel(found_fwd) == -1)
846 found_fwd->allocated_port : fwd.listen_port;
847 if (channel_request_rforward_cancel(fwd.listen_host,
848 listen_port) == -1)
849 error_reason = "port not in permitted opens"; 893 error_reason = "port not in permitted opens";
850 } else { /* local and dynamic forwards */ 894 } else { /* local and dynamic forwards */
851 /* Ditto */ 895 /* Ditto */
852 if (channel_cancel_lport_listener(fwd.listen_host, 896 if (channel_cancel_lport_listener(&fwd, fwd.connect_port,
853 fwd.listen_port, fwd.connect_port, 897 &options.fwd_opts) == -1)
854 options.gateway_ports) == -1)
855 error_reason = "port not found"; 898 error_reason = "port not found";
856 } 899 }
857 900
@@ -860,8 +903,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
860 buffer_put_int(r, rid); 903 buffer_put_int(r, rid);
861 904
862 free(found_fwd->listen_host); 905 free(found_fwd->listen_host);
906 free(found_fwd->listen_path);
863 free(found_fwd->connect_host); 907 free(found_fwd->connect_host);
908 free(found_fwd->connect_path);
864 found_fwd->listen_host = found_fwd->connect_host = NULL; 909 found_fwd->listen_host = found_fwd->connect_host = NULL;
910 found_fwd->listen_path = found_fwd->connect_path = NULL;
865 found_fwd->listen_port = found_fwd->connect_port = 0; 911 found_fwd->listen_port = found_fwd->connect_port = 0;
866 } else { 912 } else {
867 buffer_put_int(r, MUX_S_FAILURE); 913 buffer_put_int(r, MUX_S_FAILURE);
@@ -870,8 +916,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
870 } 916 }
871 out: 917 out:
872 free(fwd_desc); 918 free(fwd_desc);
873 free(fwd.listen_host); 919 free(listen_addr);
874 free(fwd.connect_host); 920 free(connect_addr);
875 921
876 return ret; 922 return ret;
877} 923}
@@ -883,6 +929,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
883 char *reserved, *chost; 929 char *reserved, *chost;
884 u_int cport, i, j; 930 u_int cport, i, j;
885 int new_fd[2]; 931 int new_fd[2];
932 struct mux_stdio_confirm_ctx *cctx;
886 933
887 chost = reserved = NULL; 934 chost = reserved = NULL;
888 if ((reserved = buffer_get_string_ret(m, NULL)) == NULL || 935 if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
@@ -962,15 +1009,60 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
962 1009
963 channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); 1010 channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);
964 1011
965 /* prepare reply */ 1012 cctx = xcalloc(1, sizeof(*cctx));
966 /* XXX defer until channel confirmed */ 1013 cctx->rid = rid;
967 buffer_put_int(r, MUX_S_SESSION_OPENED); 1014 channel_register_open_confirm(nc->self, mux_stdio_confirm, cctx);
968 buffer_put_int(r, rid); 1015 c->mux_pause = 1; /* stop handling messages until open_confirm done */
969 buffer_put_int(r, nc->self);
970 1016
1017 /* reply is deferred, sent by mux_session_confirm */
971 return 0; 1018 return 0;
972} 1019}
973 1020
1021/* Callback on open confirmation in mux master for a mux stdio fwd session. */
1022static void
1023mux_stdio_confirm(int id, int success, void *arg)
1024{
1025 struct mux_stdio_confirm_ctx *cctx = arg;
1026 Channel *c, *cc;
1027 Buffer reply;
1028
1029 if (cctx == NULL)
1030 fatal("%s: cctx == NULL", __func__);
1031 if ((c = channel_by_id(id)) == NULL)
1032 fatal("%s: no channel for id %d", __func__, id);
1033 if ((cc = channel_by_id(c->ctl_chan)) == NULL)
1034 fatal("%s: channel %d lacks control channel %d", __func__,
1035 id, c->ctl_chan);
1036
1037 if (!success) {
1038 debug3("%s: sending failure reply", __func__);
1039 /* prepare reply */
1040 buffer_init(&reply);
1041 buffer_put_int(&reply, MUX_S_FAILURE);
1042 buffer_put_int(&reply, cctx->rid);
1043 buffer_put_cstring(&reply, "Session open refused by peer");
1044 goto done;
1045 }
1046
1047 debug3("%s: sending success reply", __func__);
1048 /* prepare reply */
1049 buffer_init(&reply);
1050 buffer_put_int(&reply, MUX_S_SESSION_OPENED);
1051 buffer_put_int(&reply, cctx->rid);
1052 buffer_put_int(&reply, c->self);
1053
1054 done:
1055 /* Send reply */
1056 buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply));
1057 buffer_free(&reply);
1058
1059 if (cc->mux_pause <= 0)
1060 fatal("%s: mux_pause %d", __func__, cc->mux_pause);
1061 cc->mux_pause = 0; /* start processing messages again */
1062 c->open_confirm_ctx = NULL;
1063 free(cctx);
1064}
1065
974static int 1066static int
975process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) 1067process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
976{ 1068{
@@ -1010,7 +1102,7 @@ mux_master_read_cb(Channel *c)
1010{ 1102{
1011 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; 1103 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
1012 Buffer in, out; 1104 Buffer in, out;
1013 void *ptr; 1105 const u_char *ptr;
1014 u_int type, rid, have, i; 1106 u_int type, rid, have, i;
1015 int ret = -1; 1107 int ret = -1;
1016 1108
@@ -1133,12 +1225,11 @@ mux_tty_alloc_failed(Channel *c)
1133void 1225void
1134muxserver_listen(void) 1226muxserver_listen(void)
1135{ 1227{
1136 struct sockaddr_un addr;
1137 socklen_t sun_len;
1138 mode_t old_umask; 1228 mode_t old_umask;
1139 char *orig_control_path = options.control_path; 1229 char *orig_control_path = options.control_path;
1140 char rbuf[16+1]; 1230 char rbuf[16+1];
1141 u_int i, r; 1231 u_int i, r;
1232 int oerrno;
1142 1233
1143 if (options.control_path == NULL || 1234 if (options.control_path == NULL ||
1144 options.control_master == SSHCTL_MASTER_NO) 1235 options.control_master == SSHCTL_MASTER_NO)
@@ -1163,24 +1254,12 @@ muxserver_listen(void)
1163 xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf); 1254 xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
1164 debug3("%s: temporary control path %s", __func__, options.control_path); 1255 debug3("%s: temporary control path %s", __func__, options.control_path);
1165 1256
1166 memset(&addr, '\0', sizeof(addr));
1167 addr.sun_family = AF_UNIX;
1168 sun_len = offsetof(struct sockaddr_un, sun_path) +
1169 strlen(options.control_path) + 1;
1170
1171 if (strlcpy(addr.sun_path, options.control_path,
1172 sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {
1173 error("ControlPath \"%s\" too long for Unix domain socket",
1174 options.control_path);
1175 goto disable_mux_master;
1176 }
1177
1178 if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1179 fatal("%s socket(): %s", __func__, strerror(errno));
1180
1181 old_umask = umask(0177); 1257 old_umask = umask(0177);
1182 if (bind(muxserver_sock, (struct sockaddr *)&addr, sun_len) == -1) { 1258 muxserver_sock = unix_listener(options.control_path, 64, 0);
1183 if (errno == EINVAL || errno == EADDRINUSE) { 1259 oerrno = errno;
1260 umask(old_umask);
1261 if (muxserver_sock < 0) {
1262 if (oerrno == EINVAL || oerrno == EADDRINUSE) {
1184 error("ControlSocket %s already exists, " 1263 error("ControlSocket %s already exists, "
1185 "disabling multiplexing", options.control_path); 1264 "disabling multiplexing", options.control_path);
1186 disable_mux_master: 1265 disable_mux_master:
@@ -1193,13 +1272,11 @@ muxserver_listen(void)
1193 options.control_path = NULL; 1272 options.control_path = NULL;
1194 options.control_master = SSHCTL_MASTER_NO; 1273 options.control_master = SSHCTL_MASTER_NO;
1195 return; 1274 return;
1196 } else 1275 } else {
1197 fatal("%s bind(): %s", __func__, strerror(errno)); 1276 /* unix_listener() logs the error */
1277 cleanup_exit(255);
1278 }
1198 } 1279 }
1199 umask(old_umask);
1200
1201 if (listen(muxserver_sock, 64) == -1)
1202 fatal("%s listen(): %s", __func__, strerror(errno));
1203 1280
1204 /* Now atomically "move" the mux socket into position */ 1281 /* Now atomically "move" the mux socket into position */
1205 if (link(options.control_path, orig_control_path) != 0) { 1282 if (link(options.control_path, orig_control_path) != 0) {
@@ -1429,7 +1506,7 @@ mux_client_read_packet(int fd, Buffer *m)
1429{ 1506{
1430 Buffer queue; 1507 Buffer queue;
1431 u_int need, have; 1508 u_int need, have;
1432 void *ptr; 1509 const u_char *ptr;
1433 int oerrno; 1510 int oerrno;
1434 1511
1435 buffer_init(&queue); 1512 buffer_init(&queue);
@@ -1593,7 +1670,7 @@ mux_client_request_terminate(int fd)
1593} 1670}
1594 1671
1595static int 1672static int
1596mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd) 1673mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
1597{ 1674{
1598 Buffer m; 1675 Buffer m;
1599 char *e, *fwd_desc; 1676 char *e, *fwd_desc;
@@ -1608,11 +1685,19 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)
1608 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD); 1685 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);
1609 buffer_put_int(&m, muxclient_request_id); 1686 buffer_put_int(&m, muxclient_request_id);
1610 buffer_put_int(&m, ftype); 1687 buffer_put_int(&m, ftype);
1611 buffer_put_cstring(&m, 1688 if (fwd->listen_path != NULL) {
1612 fwd->listen_host == NULL ? "" : fwd->listen_host); 1689 buffer_put_cstring(&m, fwd->listen_path);
1690 } else {
1691 buffer_put_cstring(&m,
1692 fwd->listen_host == NULL ? "" : fwd->listen_host);
1693 }
1613 buffer_put_int(&m, fwd->listen_port); 1694 buffer_put_int(&m, fwd->listen_port);
1614 buffer_put_cstring(&m, 1695 if (fwd->connect_path != NULL) {
1615 fwd->connect_host == NULL ? "" : fwd->connect_host); 1696 buffer_put_cstring(&m, fwd->connect_path);
1697 } else {
1698 buffer_put_cstring(&m,
1699 fwd->connect_host == NULL ? "" : fwd->connect_host);
1700 }
1616 buffer_put_int(&m, fwd->connect_port); 1701 buffer_put_int(&m, fwd->connect_port);
1617 1702
1618 if (mux_client_write_packet(fd, &m) != 0) 1703 if (mux_client_write_packet(fd, &m) != 0)
@@ -1922,7 +2007,7 @@ mux_client_request_stdio_fwd(int fd)
1922 case MUX_S_FAILURE: 2007 case MUX_S_FAILURE:
1923 e = buffer_get_string(&m, NULL); 2008 e = buffer_get_string(&m, NULL);
1924 buffer_free(&m); 2009 buffer_free(&m);
1925 fatal("%s: stdio forwarding request failed: %s", __func__, e); 2010 fatal("Stdio forwarding request failed: %s", e);
1926 default: 2011 default:
1927 buffer_free(&m); 2012 buffer_free(&m);
1928 error("%s: unexpected response from master 0x%08x", 2013 error("%s: unexpected response from master 0x%08x",