summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-09-22 21:38:52 +1000
committerDamien Miller <djm@mindrot.org>2011-09-22 21:38:52 +1000
commitf6dff7cd2ff5eba5cd63e3a9c7bf6ccf183cb056 (patch)
treeca2f37e390f5f26598341a09435dabed25648d46 /mux.c
parent9ee2c606c1d03ecb955aa8a2624b9db4aa9752a2 (diff)
- djm@cvs.openbsd.org 2011/09/09 22:46:44
[channels.c channels.h clientloop.h mux.c ssh.c] support for cancelling local and remote port forwards via the multiplex socket. Use ssh -O cancel -L xx:xx:xx -R yy:yy:yy user@host" to request the cancellation of the specified forwardings; ok markus@
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c104
1 files changed, 83 insertions, 21 deletions
diff --git a/mux.c b/mux.c
index add0e26b1..6b63d813b 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.30 2011/09/09 22:46:44 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 *
@@ -777,10 +777,11 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
777static int 777static int
778process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 778process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
779{ 779{
780 Forward fwd; 780 Forward fwd, *found_fwd;
781 char *fwd_desc = NULL; 781 char *fwd_desc = NULL;
782 const char *error_reason = NULL;
782 u_int ftype; 783 u_int ftype;
783 int ret = 0; 784 int i, ret = 0;
784 785
785 fwd.listen_host = fwd.connect_host = NULL; 786 fwd.listen_host = fwd.connect_host = NULL;
786 if (buffer_get_int_ret(&ftype, m) != 0 || 787 if (buffer_get_int_ret(&ftype, m) != 0 ||
@@ -802,14 +803,66 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
802 fwd.connect_host = NULL; 803 fwd.connect_host = NULL;
803 } 804 }
804 805
805 debug2("%s: channel %d: request %s", __func__, c->self, 806 debug2("%s: channel %d: request cancel %s", __func__, c->self,
806 (fwd_desc = format_forward(ftype, &fwd))); 807 (fwd_desc = format_forward(ftype, &fwd)));
807 808
808 /* XXX implement this */ 809 /* make sure this has been requested */
809 buffer_put_int(r, MUX_S_FAILURE); 810 found_fwd = NULL;
810 buffer_put_int(r, rid); 811 switch (ftype) {
811 buffer_put_cstring(r, "unimplemented"); 812 case MUX_FWD_LOCAL:
813 case MUX_FWD_DYNAMIC:
814 for (i = 0; i < options.num_local_forwards; i++) {
815 if (compare_forward(&fwd,
816 options.local_forwards + i)) {
817 found_fwd = options.local_forwards + i;
818 break;
819 }
820 }
821 break;
822 case MUX_FWD_REMOTE:
823 for (i = 0; i < options.num_remote_forwards; i++) {
824 if (compare_forward(&fwd,
825 options.remote_forwards + i)) {
826 found_fwd = options.remote_forwards + i;
827 break;
828 }
829 }
830 break;
831 }
812 832
833 if (found_fwd == NULL)
834 error_reason = "port not forwarded";
835 else if (ftype == MUX_FWD_REMOTE) {
836 /*
837 * This shouldn't fail unless we confused the host/port
838 * between options.remote_forwards and permitted_opens.
839 */
840 if (channel_request_rforward_cancel(fwd.listen_host,
841 fwd.listen_port) == -1)
842 error_reason = "port not in permitted opens";
843 } else { /* local and dynamic forwards */
844 /* Ditto */
845 if (channel_cancel_lport_listener(fwd.listen_host,
846 fwd.listen_port, fwd.connect_port,
847 options.gateway_ports) == -1)
848 error_reason = "port not found";
849 }
850
851 if (error_reason == NULL) {
852 buffer_put_int(r, MUX_S_OK);
853 buffer_put_int(r, rid);
854
855 if (found_fwd->listen_host != NULL)
856 xfree(found_fwd->listen_host);
857 if (found_fwd->connect_host != NULL)
858 xfree(found_fwd->connect_host);
859 found_fwd->listen_host = found_fwd->connect_host = NULL;
860 found_fwd->listen_port = found_fwd->connect_port = 0;
861 } else {
862 buffer_put_int(r, MUX_S_FAILURE);
863 buffer_put_int(r, rid);
864 buffer_put_cstring(r, error_reason);
865 }
813 out: 866 out:
814 if (fwd_desc != NULL) 867 if (fwd_desc != NULL)
815 xfree(fwd_desc); 868 xfree(fwd_desc);
@@ -1537,18 +1590,19 @@ mux_client_request_terminate(int fd)
1537} 1590}
1538 1591
1539static int 1592static int
1540mux_client_request_forward(int fd, u_int ftype, Forward *fwd) 1593mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)
1541{ 1594{
1542 Buffer m; 1595 Buffer m;
1543 char *e, *fwd_desc; 1596 char *e, *fwd_desc;
1544 u_int type, rid; 1597 u_int type, rid;
1545 1598
1546 fwd_desc = format_forward(ftype, fwd); 1599 fwd_desc = format_forward(ftype, fwd);
1547 debug("Requesting %s", fwd_desc); 1600 debug("Requesting %s %s",
1601 cancel_flag ? "cancellation of" : "forwarding of", fwd_desc);
1548 xfree(fwd_desc); 1602 xfree(fwd_desc);
1549 1603
1550 buffer_init(&m); 1604 buffer_init(&m);
1551 buffer_put_int(&m, MUX_C_OPEN_FWD); 1605 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);
1552 buffer_put_int(&m, muxclient_request_id); 1606 buffer_put_int(&m, muxclient_request_id);
1553 buffer_put_int(&m, ftype); 1607 buffer_put_int(&m, ftype);
1554 buffer_put_cstring(&m, 1608 buffer_put_cstring(&m,
@@ -1577,6 +1631,8 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
1577 case MUX_S_OK: 1631 case MUX_S_OK:
1578 break; 1632 break;
1579 case MUX_S_REMOTE_PORT: 1633 case MUX_S_REMOTE_PORT:
1634 if (cancel_flag)
1635 fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__);
1580 fwd->allocated_port = buffer_get_int(&m); 1636 fwd->allocated_port = buffer_get_int(&m);
1581 logit("Allocated port %u for remote forward to %s:%d", 1637 logit("Allocated port %u for remote forward to %s:%d",
1582 fwd->allocated_port, 1638 fwd->allocated_port,
@@ -1606,27 +1662,28 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
1606} 1662}
1607 1663
1608static int 1664static int
1609mux_client_request_forwards(int fd) 1665mux_client_forwards(int fd, int cancel_flag)
1610{ 1666{
1611 int i; 1667 int i, ret = 0;
1612 1668
1613 debug3("%s: requesting forwardings: %d local, %d remote", __func__, 1669 debug3("%s: %s forwardings: %d local, %d remote", __func__,
1670 cancel_flag ? "cancel" : "request",
1614 options.num_local_forwards, options.num_remote_forwards); 1671 options.num_local_forwards, options.num_remote_forwards);
1615 1672
1616 /* XXX ExitOnForwardingFailure */ 1673 /* XXX ExitOnForwardingFailure */
1617 for (i = 0; i < options.num_local_forwards; i++) { 1674 for (i = 0; i < options.num_local_forwards; i++) {
1618 if (mux_client_request_forward(fd, 1675 if (mux_client_forward(fd, cancel_flag,
1619 options.local_forwards[i].connect_port == 0 ? 1676 options.local_forwards[i].connect_port == 0 ?
1620 MUX_FWD_DYNAMIC : MUX_FWD_LOCAL, 1677 MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
1621 options.local_forwards + i) != 0) 1678 options.local_forwards + i) != 0)
1622 return -1; 1679 ret = -1;
1623 } 1680 }
1624 for (i = 0; i < options.num_remote_forwards; i++) { 1681 for (i = 0; i < options.num_remote_forwards; i++) {
1625 if (mux_client_request_forward(fd, MUX_FWD_REMOTE, 1682 if (mux_client_forward(fd, cancel_flag, MUX_FWD_REMOTE,
1626 options.remote_forwards + i) != 0) 1683 options.remote_forwards + i) != 0)
1627 return -1; 1684 ret = -1;
1628 } 1685 }
1629 return 0; 1686 return ret;
1630} 1687}
1631 1688
1632static int 1689static int
@@ -2014,11 +2071,11 @@ muxclient(const char *path)
2014 fprintf(stderr, "Exit request sent.\r\n"); 2071 fprintf(stderr, "Exit request sent.\r\n");
2015 exit(0); 2072 exit(0);
2016 case SSHMUX_COMMAND_FORWARD: 2073 case SSHMUX_COMMAND_FORWARD:
2017 if (mux_client_request_forwards(sock) != 0) 2074 if (mux_client_forwards(sock, 0) != 0)
2018 fatal("%s: master forward request failed", __func__); 2075 fatal("%s: master forward request failed", __func__);
2019 exit(0); 2076 exit(0);
2020 case SSHMUX_COMMAND_OPEN: 2077 case SSHMUX_COMMAND_OPEN:
2021 if (mux_client_request_forwards(sock) != 0) { 2078 if (mux_client_forwards(sock, 0) != 0) {
2022 error("%s: master forward request failed", __func__); 2079 error("%s: master forward request failed", __func__);
2023 return; 2080 return;
2024 } 2081 }
@@ -2031,6 +2088,11 @@ muxclient(const char *path)
2031 mux_client_request_stop_listening(sock); 2088 mux_client_request_stop_listening(sock);
2032 fprintf(stderr, "Stop listening request sent.\r\n"); 2089 fprintf(stderr, "Stop listening request sent.\r\n");
2033 exit(0); 2090 exit(0);
2091 case SSHMUX_COMMAND_CANCEL_FWD:
2092 if (mux_client_forwards(sock, 1) != 0)
2093 error("%s: master cancel forward request failed",
2094 __func__);
2095 exit(0);
2034 default: 2096 default:
2035 fatal("unrecognised muxclient_command %d", muxclient_command); 2097 fatal("unrecognised muxclient_command %d", muxclient_command);
2036 } 2098 }