summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c121
1 files changed, 95 insertions, 26 deletions
diff --git a/mux.c b/mux.c
index add0e26b1..d90605eb4 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.29 2011/06/22 22:08:42 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.34 2012/01/07 21:11:36 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 *
@@ -341,10 +341,8 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
341 env_len = 0; 341 env_len = 0;
342 while (buffer_len(m) > 0) { 342 while (buffer_len(m) > 0) {
343#define MUX_MAX_ENV_VARS 4096 343#define MUX_MAX_ENV_VARS 4096
344 if ((cp = buffer_get_string_ret(m, &len)) == NULL) { 344 if ((cp = buffer_get_string_ret(m, &len)) == NULL)
345 xfree(cmd);
346 goto malf; 345 goto malf;
347 }
348 if (!env_permitted(cp)) { 346 if (!env_permitted(cp)) {
349 xfree(cp); 347 xfree(cp);
350 continue; 348 continue;
@@ -601,12 +599,16 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
601 buffer_put_int(&out, MUX_S_REMOTE_PORT); 599 buffer_put_int(&out, MUX_S_REMOTE_PORT);
602 buffer_put_int(&out, fctx->rid); 600 buffer_put_int(&out, fctx->rid);
603 buffer_put_int(&out, rfwd->allocated_port); 601 buffer_put_int(&out, rfwd->allocated_port);
602 channel_update_permitted_opens(rfwd->handle,
603 rfwd->allocated_port);
604 } else { 604 } else {
605 buffer_put_int(&out, MUX_S_OK); 605 buffer_put_int(&out, MUX_S_OK);
606 buffer_put_int(&out, fctx->rid); 606 buffer_put_int(&out, fctx->rid);
607 } 607 }
608 goto out; 608 goto out;
609 } else { 609 } else {
610 if (rfwd->listen_port == 0)
611 channel_update_permitted_opens(rfwd->handle, -1);
610 xasprintf(&failmsg, "remote port forwarding failed for " 612 xasprintf(&failmsg, "remote port forwarding failed for "
611 "listen port %d", rfwd->listen_port); 613 "listen port %d", rfwd->listen_port);
612 } 614 }
@@ -745,8 +747,9 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
745 } else { 747 } else {
746 struct mux_channel_confirm_ctx *fctx; 748 struct mux_channel_confirm_ctx *fctx;
747 749
748 if (channel_request_remote_forwarding(fwd.listen_host, 750 fwd.handle = channel_request_remote_forwarding(fwd.listen_host,
749 fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0) 751 fwd.listen_port, fwd.connect_host, fwd.connect_port);
752 if (fwd.handle < 0)
750 goto fail; 753 goto fail;
751 add_remote_forward(&options, &fwd); 754 add_remote_forward(&options, &fwd);
752 fctx = xcalloc(1, sizeof(*fctx)); 755 fctx = xcalloc(1, sizeof(*fctx));
@@ -777,10 +780,11 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
777static int 780static int
778process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 781process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
779{ 782{
780 Forward fwd; 783 Forward fwd, *found_fwd;
781 char *fwd_desc = NULL; 784 char *fwd_desc = NULL;
785 const char *error_reason = NULL;
782 u_int ftype; 786 u_int ftype;
783 int ret = 0; 787 int i, listen_port, ret = 0;
784 788
785 fwd.listen_host = fwd.connect_host = NULL; 789 fwd.listen_host = fwd.connect_host = NULL;
786 if (buffer_get_int_ret(&ftype, m) != 0 || 790 if (buffer_get_int_ret(&ftype, m) != 0 ||
@@ -802,14 +806,70 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
802 fwd.connect_host = NULL; 806 fwd.connect_host = NULL;
803 } 807 }
804 808
805 debug2("%s: channel %d: request %s", __func__, c->self, 809 debug2("%s: channel %d: request cancel %s", __func__, c->self,
806 (fwd_desc = format_forward(ftype, &fwd))); 810 (fwd_desc = format_forward(ftype, &fwd)));
807 811
808 /* XXX implement this */ 812 /* make sure this has been requested */
809 buffer_put_int(r, MUX_S_FAILURE); 813 found_fwd = NULL;
810 buffer_put_int(r, rid); 814 switch (ftype) {
811 buffer_put_cstring(r, "unimplemented"); 815 case MUX_FWD_LOCAL:
816 case MUX_FWD_DYNAMIC:
817 for (i = 0; i < options.num_local_forwards; i++) {
818 if (compare_forward(&fwd,
819 options.local_forwards + i)) {
820 found_fwd = options.local_forwards + i;
821 break;
822 }
823 }
824 break;
825 case MUX_FWD_REMOTE:
826 for (i = 0; i < options.num_remote_forwards; i++) {
827 if (compare_forward(&fwd,
828 options.remote_forwards + i)) {
829 found_fwd = options.remote_forwards + i;
830 break;
831 }
832 }
833 break;
834 }
812 835
836 if (found_fwd == NULL)
837 error_reason = "port not forwarded";
838 else if (ftype == MUX_FWD_REMOTE) {
839 /*
840 * This shouldn't fail unless we confused the host/port
841 * between options.remote_forwards and permitted_opens.
842 * However, for dynamic allocated listen ports we need
843 * to lookup the actual listen port.
844 */
845 listen_port = (fwd.listen_port == 0) ?
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";
850 } else { /* local and dynamic forwards */
851 /* Ditto */
852 if (channel_cancel_lport_listener(fwd.listen_host,
853 fwd.listen_port, fwd.connect_port,
854 options.gateway_ports) == -1)
855 error_reason = "port not found";
856 }
857
858 if (error_reason == NULL) {
859 buffer_put_int(r, MUX_S_OK);
860 buffer_put_int(r, rid);
861
862 if (found_fwd->listen_host != NULL)
863 xfree(found_fwd->listen_host);
864 if (found_fwd->connect_host != NULL)
865 xfree(found_fwd->connect_host);
866 found_fwd->listen_host = found_fwd->connect_host = NULL;
867 found_fwd->listen_port = found_fwd->connect_port = 0;
868 } else {
869 buffer_put_int(r, MUX_S_FAILURE);
870 buffer_put_int(r, rid);
871 buffer_put_cstring(r, error_reason);
872 }
813 out: 873 out:
814 if (fwd_desc != NULL) 874 if (fwd_desc != NULL)
815 xfree(fwd_desc); 875 xfree(fwd_desc);
@@ -1537,18 +1597,19 @@ mux_client_request_terminate(int fd)
1537} 1597}
1538 1598
1539static int 1599static int
1540mux_client_request_forward(int fd, u_int ftype, Forward *fwd) 1600mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)
1541{ 1601{
1542 Buffer m; 1602 Buffer m;
1543 char *e, *fwd_desc; 1603 char *e, *fwd_desc;
1544 u_int type, rid; 1604 u_int type, rid;
1545 1605
1546 fwd_desc = format_forward(ftype, fwd); 1606 fwd_desc = format_forward(ftype, fwd);
1547 debug("Requesting %s", fwd_desc); 1607 debug("Requesting %s %s",
1608 cancel_flag ? "cancellation of" : "forwarding of", fwd_desc);
1548 xfree(fwd_desc); 1609 xfree(fwd_desc);
1549 1610
1550 buffer_init(&m); 1611 buffer_init(&m);
1551 buffer_put_int(&m, MUX_C_OPEN_FWD); 1612 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);
1552 buffer_put_int(&m, muxclient_request_id); 1613 buffer_put_int(&m, muxclient_request_id);
1553 buffer_put_int(&m, ftype); 1614 buffer_put_int(&m, ftype);
1554 buffer_put_cstring(&m, 1615 buffer_put_cstring(&m,
@@ -1577,6 +1638,8 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
1577 case MUX_S_OK: 1638 case MUX_S_OK:
1578 break; 1639 break;
1579 case MUX_S_REMOTE_PORT: 1640 case MUX_S_REMOTE_PORT:
1641 if (cancel_flag)
1642 fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__);
1580 fwd->allocated_port = buffer_get_int(&m); 1643 fwd->allocated_port = buffer_get_int(&m);
1581 logit("Allocated port %u for remote forward to %s:%d", 1644 logit("Allocated port %u for remote forward to %s:%d",
1582 fwd->allocated_port, 1645 fwd->allocated_port,
@@ -1606,27 +1669,28 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
1606} 1669}
1607 1670
1608static int 1671static int
1609mux_client_request_forwards(int fd) 1672mux_client_forwards(int fd, int cancel_flag)
1610{ 1673{
1611 int i; 1674 int i, ret = 0;
1612 1675
1613 debug3("%s: requesting forwardings: %d local, %d remote", __func__, 1676 debug3("%s: %s forwardings: %d local, %d remote", __func__,
1677 cancel_flag ? "cancel" : "request",
1614 options.num_local_forwards, options.num_remote_forwards); 1678 options.num_local_forwards, options.num_remote_forwards);
1615 1679
1616 /* XXX ExitOnForwardingFailure */ 1680 /* XXX ExitOnForwardingFailure */
1617 for (i = 0; i < options.num_local_forwards; i++) { 1681 for (i = 0; i < options.num_local_forwards; i++) {
1618 if (mux_client_request_forward(fd, 1682 if (mux_client_forward(fd, cancel_flag,
1619 options.local_forwards[i].connect_port == 0 ? 1683 options.local_forwards[i].connect_port == 0 ?
1620 MUX_FWD_DYNAMIC : MUX_FWD_LOCAL, 1684 MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
1621 options.local_forwards + i) != 0) 1685 options.local_forwards + i) != 0)
1622 return -1; 1686 ret = -1;
1623 } 1687 }
1624 for (i = 0; i < options.num_remote_forwards; i++) { 1688 for (i = 0; i < options.num_remote_forwards; i++) {
1625 if (mux_client_request_forward(fd, MUX_FWD_REMOTE, 1689 if (mux_client_forward(fd, cancel_flag, MUX_FWD_REMOTE,
1626 options.remote_forwards + i) != 0) 1690 options.remote_forwards + i) != 0)
1627 return -1; 1691 ret = -1;
1628 } 1692 }
1629 return 0; 1693 return ret;
1630} 1694}
1631 1695
1632static int 1696static int
@@ -2014,11 +2078,11 @@ muxclient(const char *path)
2014 fprintf(stderr, "Exit request sent.\r\n"); 2078 fprintf(stderr, "Exit request sent.\r\n");
2015 exit(0); 2079 exit(0);
2016 case SSHMUX_COMMAND_FORWARD: 2080 case SSHMUX_COMMAND_FORWARD:
2017 if (mux_client_request_forwards(sock) != 0) 2081 if (mux_client_forwards(sock, 0) != 0)
2018 fatal("%s: master forward request failed", __func__); 2082 fatal("%s: master forward request failed", __func__);
2019 exit(0); 2083 exit(0);
2020 case SSHMUX_COMMAND_OPEN: 2084 case SSHMUX_COMMAND_OPEN:
2021 if (mux_client_request_forwards(sock) != 0) { 2085 if (mux_client_forwards(sock, 0) != 0) {
2022 error("%s: master forward request failed", __func__); 2086 error("%s: master forward request failed", __func__);
2023 return; 2087 return;
2024 } 2088 }
@@ -2031,6 +2095,11 @@ muxclient(const char *path)
2031 mux_client_request_stop_listening(sock); 2095 mux_client_request_stop_listening(sock);
2032 fprintf(stderr, "Stop listening request sent.\r\n"); 2096 fprintf(stderr, "Stop listening request sent.\r\n");
2033 exit(0); 2097 exit(0);
2098 case SSHMUX_COMMAND_CANCEL_FWD:
2099 if (mux_client_forwards(sock, 1) != 0)
2100 error("%s: master cancel forward request failed",
2101 __func__);
2102 exit(0);
2034 default: 2103 default:
2035 fatal("unrecognised muxclient_command %d", muxclient_command); 2104 fatal("unrecognised muxclient_command %d", muxclient_command);
2036 } 2105 }