diff options
Diffstat (limited to 'mux.c')
-rw-r--r-- | mux.c | 86 |
1 files changed, 85 insertions, 1 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mux.c,v 1.24 2011/01/13 21:54:53 djm Exp $ */ | 1 | /* $OpenBSD: mux.c,v 1.25 2011/04/17 22:42:41 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 | * |
@@ -146,6 +146,7 @@ struct mux_master_state { | |||
146 | #define MUX_C_OPEN_FWD 0x10000006 | 146 | #define MUX_C_OPEN_FWD 0x10000006 |
147 | #define MUX_C_CLOSE_FWD 0x10000007 | 147 | #define MUX_C_CLOSE_FWD 0x10000007 |
148 | #define MUX_C_NEW_STDIO_FWD 0x10000008 | 148 | #define MUX_C_NEW_STDIO_FWD 0x10000008 |
149 | #define MUX_C_STOP_LISTENING 0x10000009 | ||
149 | #define MUX_S_OK 0x80000001 | 150 | #define MUX_S_OK 0x80000001 |
150 | #define MUX_S_PERMISSION_DENIED 0x80000002 | 151 | #define MUX_S_PERMISSION_DENIED 0x80000002 |
151 | #define MUX_S_FAILURE 0x80000003 | 152 | #define MUX_S_FAILURE 0x80000003 |
@@ -168,6 +169,7 @@ static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *); | |||
168 | static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *); | 169 | static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *); |
169 | static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); | 170 | static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); |
170 | static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); | 171 | static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); |
172 | static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); | ||
171 | 173 | ||
172 | static const struct { | 174 | static const struct { |
173 | u_int type; | 175 | u_int type; |
@@ -180,6 +182,7 @@ static const struct { | |||
180 | { MUX_C_OPEN_FWD, process_mux_open_fwd }, | 182 | { MUX_C_OPEN_FWD, process_mux_open_fwd }, |
181 | { MUX_C_CLOSE_FWD, process_mux_close_fwd }, | 183 | { MUX_C_CLOSE_FWD, process_mux_close_fwd }, |
182 | { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd }, | 184 | { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd }, |
185 | { MUX_C_STOP_LISTENING, process_mux_stop_listening }, | ||
183 | { 0, NULL } | 186 | { 0, NULL } |
184 | }; | 187 | }; |
185 | 188 | ||
@@ -915,6 +918,39 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
915 | return 0; | 918 | return 0; |
916 | } | 919 | } |
917 | 920 | ||
921 | static int | ||
922 | process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | ||
923 | { | ||
924 | debug("%s: channel %d: stop listening", __func__, c->self); | ||
925 | |||
926 | if (options.control_master == SSHCTL_MASTER_ASK || | ||
927 | options.control_master == SSHCTL_MASTER_AUTO_ASK) { | ||
928 | if (!ask_permission("Disable further multiplexing on shared " | ||
929 | "connection to %s? ", host)) { | ||
930 | debug2("%s: stop listen refused by user", __func__); | ||
931 | buffer_put_int(r, MUX_S_PERMISSION_DENIED); | ||
932 | buffer_put_int(r, rid); | ||
933 | buffer_put_cstring(r, "Permission denied"); | ||
934 | return 0; | ||
935 | } | ||
936 | } | ||
937 | |||
938 | if (mux_listener_channel != NULL) { | ||
939 | channel_free(mux_listener_channel); | ||
940 | client_stop_mux(); | ||
941 | xfree(options.control_path); | ||
942 | options.control_path = NULL; | ||
943 | mux_listener_channel = NULL; | ||
944 | muxserver_sock = -1; | ||
945 | } | ||
946 | |||
947 | /* prepare reply */ | ||
948 | buffer_put_int(r, MUX_S_OK); | ||
949 | buffer_put_int(r, rid); | ||
950 | |||
951 | return 0; | ||
952 | } | ||
953 | |||
918 | /* Channel callbacks fired on read/write from mux slave fd */ | 954 | /* Channel callbacks fired on read/write from mux slave fd */ |
919 | static int | 955 | static int |
920 | mux_master_read_cb(Channel *c) | 956 | mux_master_read_cb(Channel *c) |
@@ -1813,6 +1849,50 @@ mux_client_request_stdio_fwd(int fd) | |||
1813 | fatal("%s: master returned unexpected message %u", __func__, type); | 1849 | fatal("%s: master returned unexpected message %u", __func__, type); |
1814 | } | 1850 | } |
1815 | 1851 | ||
1852 | static void | ||
1853 | mux_client_request_stop_listening(int fd) | ||
1854 | { | ||
1855 | Buffer m; | ||
1856 | char *e; | ||
1857 | u_int type, rid; | ||
1858 | |||
1859 | debug3("%s: entering", __func__); | ||
1860 | |||
1861 | buffer_init(&m); | ||
1862 | buffer_put_int(&m, MUX_C_STOP_LISTENING); | ||
1863 | buffer_put_int(&m, muxclient_request_id); | ||
1864 | |||
1865 | if (mux_client_write_packet(fd, &m) != 0) | ||
1866 | fatal("%s: write packet: %s", __func__, strerror(errno)); | ||
1867 | |||
1868 | buffer_clear(&m); | ||
1869 | |||
1870 | /* Read their reply */ | ||
1871 | if (mux_client_read_packet(fd, &m) != 0) | ||
1872 | fatal("%s: read from master failed: %s", | ||
1873 | __func__, strerror(errno)); | ||
1874 | |||
1875 | type = buffer_get_int(&m); | ||
1876 | if ((rid = buffer_get_int(&m)) != muxclient_request_id) | ||
1877 | fatal("%s: out of sequence reply: my id %u theirs %u", | ||
1878 | __func__, muxclient_request_id, rid); | ||
1879 | switch (type) { | ||
1880 | case MUX_S_OK: | ||
1881 | break; | ||
1882 | case MUX_S_PERMISSION_DENIED: | ||
1883 | e = buffer_get_string(&m, NULL); | ||
1884 | fatal("Master refused stop listening request: %s", e); | ||
1885 | case MUX_S_FAILURE: | ||
1886 | e = buffer_get_string(&m, NULL); | ||
1887 | fatal("%s: stop listening request failed: %s", __func__, e); | ||
1888 | default: | ||
1889 | fatal("%s: unexpected response from master 0x%08x", | ||
1890 | __func__, type); | ||
1891 | } | ||
1892 | buffer_free(&m); | ||
1893 | muxclient_request_id++; | ||
1894 | } | ||
1895 | |||
1816 | /* Multiplex client main loop. */ | 1896 | /* Multiplex client main loop. */ |
1817 | void | 1897 | void |
1818 | muxclient(const char *path) | 1898 | muxclient(const char *path) |
@@ -1906,6 +1986,10 @@ muxclient(const char *path) | |||
1906 | case SSHMUX_COMMAND_STDIO_FWD: | 1986 | case SSHMUX_COMMAND_STDIO_FWD: |
1907 | mux_client_request_stdio_fwd(sock); | 1987 | mux_client_request_stdio_fwd(sock); |
1908 | exit(0); | 1988 | exit(0); |
1989 | case SSHMUX_COMMAND_STOP: | ||
1990 | mux_client_request_stop_listening(sock); | ||
1991 | fprintf(stderr, "Stop listening request sent.\r\n"); | ||
1992 | exit(0); | ||
1909 | default: | 1993 | default: |
1910 | fatal("unrecognised muxclient_command %d", muxclient_command); | 1994 | fatal("unrecognised muxclient_command %d", muxclient_command); |
1911 | } | 1995 | } |