=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/mux.c,v retrieving revision 1.61 retrieving revision 1.62 diff -u -r1.61 -r1.62 --- src/usr.bin/ssh/mux.c 2016/08/08 22:40:57 1.61 +++ src/usr.bin/ssh/mux.c 2016/09/30 09:19:13 1.62 @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.61 2016/08/08 22:40:57 dtucker Exp $ */ +/* $OpenBSD: mux.c,v 1.62 2016/09/30 09:19:13 markus Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -66,6 +66,7 @@ #include "key.h" #include "readconf.h" #include "clientloop.h" +#include "ssherr.h" /* from ssh.c */ extern int tty_flag; @@ -131,6 +132,7 @@ #define MUX_C_CLOSE_FWD 0x10000007 #define MUX_C_NEW_STDIO_FWD 0x10000008 #define MUX_C_STOP_LISTENING 0x10000009 +#define MUX_C_PROXY 0x1000000f #define MUX_S_OK 0x80000001 #define MUX_S_PERMISSION_DENIED 0x80000002 #define MUX_S_FAILURE 0x80000003 @@ -139,6 +141,7 @@ #define MUX_S_SESSION_OPENED 0x80000006 #define MUX_S_REMOTE_PORT 0x80000007 #define MUX_S_TTY_ALLOC_FAIL 0x80000008 +#define MUX_S_PROXY 0x8000000f /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ #define MUX_FWD_LOCAL 1 @@ -156,6 +159,7 @@ static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); +static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *); static const struct { u_int type; @@ -169,6 +173,7 @@ { MUX_C_CLOSE_FWD, process_mux_close_fwd }, { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd }, { MUX_C_STOP_LISTENING, process_mux_stop_listening }, + { MUX_C_PROXY, process_mux_proxy }, { 0, NULL } }; @@ -1097,6 +1102,18 @@ return 0; } +static int +process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) +{ + debug("%s: channel %d: proxy request", __func__, c->self); + + c->mux_rcb = channel_proxy_downstream; + buffer_put_int(r, MUX_S_PROXY); + buffer_put_int(r, rid); + + return 0; +} + /* Channel callbacks fired on read/write from mux slave fd */ static int mux_master_read_cb(Channel *c) @@ -1940,6 +1957,41 @@ } static int +mux_client_proxy(int fd) +{ + Buffer m; + char *e; + u_int type, rid; + + buffer_init(&m); + buffer_put_int(&m, MUX_C_PROXY); + buffer_put_int(&m, muxclient_request_id); + if (mux_client_write_packet(fd, &m) != 0) + fatal("%s: write packet: %s", __func__, strerror(errno)); + + buffer_clear(&m); + + /* Read their reply */ + if (mux_client_read_packet(fd, &m) != 0) { + buffer_free(&m); + return 0; + } + type = buffer_get_int(&m); + if (type != MUX_S_PROXY) { + e = buffer_get_string(&m, NULL); + fatal("%s: master returned error: %s", __func__, e); + } + if ((rid = buffer_get_int(&m)) != muxclient_request_id) + fatal("%s: out of sequence reply: my id %u theirs %u", + __func__, muxclient_request_id, rid); + buffer_free(&m); + + debug3("%s: done", __func__); + muxclient_request_id++; + return 0; +} + +static int mux_client_request_stdio_fwd(int fd) { Buffer m; @@ -2084,7 +2136,7 @@ } /* Multiplex client main loop. */ -void +int muxclient(const char *path) { struct sockaddr_un addr; @@ -2106,7 +2158,7 @@ case SSHCTL_MASTER_NO: break; default: - return; + return -1; } memset(&addr, '\0', sizeof(addr)); @@ -2142,14 +2194,14 @@ strerror(errno)); } close(sock); - return; + return -1; } set_nonblock(sock); if (mux_client_hello_exchange(sock) != 0) { error("%s: master hello exchange failed", __func__); close(sock); - return; + return -1; } switch (muxclient_command) { @@ -2169,10 +2221,10 @@ case SSHMUX_COMMAND_OPEN: if (mux_client_forwards(sock, 0) != 0) { error("%s: master forward request failed", __func__); - return; + return -1; } mux_client_request_session(sock); - return; + return -1; case SSHMUX_COMMAND_STDIO_FWD: mux_client_request_stdio_fwd(sock); exit(0); @@ -2185,6 +2237,9 @@ error("%s: master cancel forward request failed", __func__); exit(0); + case SSHMUX_COMMAND_PROXY: + mux_client_proxy(sock); + return (sock); default: fatal("unrecognised muxclient_command %d", muxclient_command); }