diff options
Diffstat (limited to 'mux.c')
-rw-r--r-- | mux.c | 104 |
1 files changed, 83 insertions, 21 deletions
@@ -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) | |||
777 | static int | 777 | static int |
778 | process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 778 | process_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 | ||
1539 | static int | 1592 | static int |
1540 | mux_client_request_forward(int fd, u_int ftype, Forward *fwd) | 1593 | mux_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 | ||
1608 | static int | 1664 | static int |
1609 | mux_client_request_forwards(int fd) | 1665 | mux_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 | ||
1632 | static int | 1689 | static 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 | } |