summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2016-09-30 09:19:13 +0000
committerDamien Miller <djm@mindrot.org>2016-10-01 02:45:10 +1000
commit8d0578478586e283e751ca51e7b0690631da139a (patch)
tree3621da2b97213f8ff0b434f5fd239dfd4f50d83d /mux.c
parentb7689155f3f5c4999846c07a852b1c7a43b09cec (diff)
upstream commit
ssh proxy mux mode (-O proxy; idea from Simon Tatham): - mux client speaks the ssh-packet protocol directly over unix-domain socket. - mux server acts as a proxy, translates channel IDs and relays to the server. - no filedescriptor passing necessary. - combined with unix-domain forwarding it's even possible to run mux client and server on different machines. feedback & ok djm@ Upstream-ID: 666a2fb79f58e5c50e246265fb2b9251e505c25b
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c69
1 files changed, 62 insertions, 7 deletions
diff --git a/mux.c b/mux.c
index a8a753b54..ec42bf520 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.61 2016/08/08 22:40:57 dtucker Exp $ */ 1/* $OpenBSD: mux.c,v 1.62 2016/09/30 09:19:13 markus 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 *
@@ -79,6 +79,7 @@
79#include "key.h" 79#include "key.h"
80#include "readconf.h" 80#include "readconf.h"
81#include "clientloop.h" 81#include "clientloop.h"
82#include "ssherr.h"
82 83
83/* from ssh.c */ 84/* from ssh.c */
84extern int tty_flag; 85extern int tty_flag;
@@ -144,6 +145,7 @@ struct mux_master_state {
144#define MUX_C_CLOSE_FWD 0x10000007 145#define MUX_C_CLOSE_FWD 0x10000007
145#define MUX_C_NEW_STDIO_FWD 0x10000008 146#define MUX_C_NEW_STDIO_FWD 0x10000008
146#define MUX_C_STOP_LISTENING 0x10000009 147#define MUX_C_STOP_LISTENING 0x10000009
148#define MUX_C_PROXY 0x1000000f
147#define MUX_S_OK 0x80000001 149#define MUX_S_OK 0x80000001
148#define MUX_S_PERMISSION_DENIED 0x80000002 150#define MUX_S_PERMISSION_DENIED 0x80000002
149#define MUX_S_FAILURE 0x80000003 151#define MUX_S_FAILURE 0x80000003
@@ -152,6 +154,7 @@ struct mux_master_state {
152#define MUX_S_SESSION_OPENED 0x80000006 154#define MUX_S_SESSION_OPENED 0x80000006
153#define MUX_S_REMOTE_PORT 0x80000007 155#define MUX_S_REMOTE_PORT 0x80000007
154#define MUX_S_TTY_ALLOC_FAIL 0x80000008 156#define MUX_S_TTY_ALLOC_FAIL 0x80000008
157#define MUX_S_PROXY 0x8000000f
155 158
156/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ 159/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
157#define MUX_FWD_LOCAL 1 160#define MUX_FWD_LOCAL 1
@@ -169,6 +172,7 @@ static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
169static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); 172static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
170static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); 173static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
171static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); 174static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *);
175static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *);
172 176
173static const struct { 177static const struct {
174 u_int type; 178 u_int type;
@@ -182,6 +186,7 @@ static const struct {
182 { MUX_C_CLOSE_FWD, process_mux_close_fwd }, 186 { MUX_C_CLOSE_FWD, process_mux_close_fwd },
183 { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd }, 187 { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },
184 { MUX_C_STOP_LISTENING, process_mux_stop_listening }, 188 { MUX_C_STOP_LISTENING, process_mux_stop_listening },
189 { MUX_C_PROXY, process_mux_proxy },
185 { 0, NULL } 190 { 0, NULL }
186}; 191};
187 192
@@ -1110,6 +1115,18 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
1110 return 0; 1115 return 0;
1111} 1116}
1112 1117
1118static int
1119process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r)
1120{
1121 debug("%s: channel %d: proxy request", __func__, c->self);
1122
1123 c->mux_rcb = channel_proxy_downstream;
1124 buffer_put_int(r, MUX_S_PROXY);
1125 buffer_put_int(r, rid);
1126
1127 return 0;
1128}
1129
1113/* Channel callbacks fired on read/write from mux slave fd */ 1130/* Channel callbacks fired on read/write from mux slave fd */
1114static int 1131static int
1115mux_master_read_cb(Channel *c) 1132mux_master_read_cb(Channel *c)
@@ -1960,6 +1977,41 @@ mux_client_request_session(int fd)
1960} 1977}
1961 1978
1962static int 1979static int
1980mux_client_proxy(int fd)
1981{
1982 Buffer m;
1983 char *e;
1984 u_int type, rid;
1985
1986 buffer_init(&m);
1987 buffer_put_int(&m, MUX_C_PROXY);
1988 buffer_put_int(&m, muxclient_request_id);
1989 if (mux_client_write_packet(fd, &m) != 0)
1990 fatal("%s: write packet: %s", __func__, strerror(errno));
1991
1992 buffer_clear(&m);
1993
1994 /* Read their reply */
1995 if (mux_client_read_packet(fd, &m) != 0) {
1996 buffer_free(&m);
1997 return 0;
1998 }
1999 type = buffer_get_int(&m);
2000 if (type != MUX_S_PROXY) {
2001 e = buffer_get_string(&m, NULL);
2002 fatal("%s: master returned error: %s", __func__, e);
2003 }
2004 if ((rid = buffer_get_int(&m)) != muxclient_request_id)
2005 fatal("%s: out of sequence reply: my id %u theirs %u",
2006 __func__, muxclient_request_id, rid);
2007 buffer_free(&m);
2008
2009 debug3("%s: done", __func__);
2010 muxclient_request_id++;
2011 return 0;
2012}
2013
2014static int
1963mux_client_request_stdio_fwd(int fd) 2015mux_client_request_stdio_fwd(int fd)
1964{ 2016{
1965 Buffer m; 2017 Buffer m;
@@ -2105,7 +2157,7 @@ mux_client_request_stop_listening(int fd)
2105} 2157}
2106 2158
2107/* Multiplex client main loop. */ 2159/* Multiplex client main loop. */
2108void 2160int
2109muxclient(const char *path) 2161muxclient(const char *path)
2110{ 2162{
2111 struct sockaddr_un addr; 2163 struct sockaddr_un addr;
@@ -2128,7 +2180,7 @@ muxclient(const char *path)
2128 case SSHCTL_MASTER_NO: 2180 case SSHCTL_MASTER_NO:
2129 break; 2181 break;
2130 default: 2182 default:
2131 return; 2183 return -1;
2132 } 2184 }
2133 2185
2134 memset(&addr, '\0', sizeof(addr)); 2186 memset(&addr, '\0', sizeof(addr));
@@ -2164,14 +2216,14 @@ muxclient(const char *path)
2164 strerror(errno)); 2216 strerror(errno));
2165 } 2217 }
2166 close(sock); 2218 close(sock);
2167 return; 2219 return -1;
2168 } 2220 }
2169 set_nonblock(sock); 2221 set_nonblock(sock);
2170 2222
2171 if (mux_client_hello_exchange(sock) != 0) { 2223 if (mux_client_hello_exchange(sock) != 0) {
2172 error("%s: master hello exchange failed", __func__); 2224 error("%s: master hello exchange failed", __func__);
2173 close(sock); 2225 close(sock);
2174 return; 2226 return -1;
2175 } 2227 }
2176 2228
2177 switch (muxclient_command) { 2229 switch (muxclient_command) {
@@ -2191,10 +2243,10 @@ muxclient(const char *path)
2191 case SSHMUX_COMMAND_OPEN: 2243 case SSHMUX_COMMAND_OPEN:
2192 if (mux_client_forwards(sock, 0) != 0) { 2244 if (mux_client_forwards(sock, 0) != 0) {
2193 error("%s: master forward request failed", __func__); 2245 error("%s: master forward request failed", __func__);
2194 return; 2246 return -1;
2195 } 2247 }
2196 mux_client_request_session(sock); 2248 mux_client_request_session(sock);
2197 return; 2249 return -1;
2198 case SSHMUX_COMMAND_STDIO_FWD: 2250 case SSHMUX_COMMAND_STDIO_FWD:
2199 mux_client_request_stdio_fwd(sock); 2251 mux_client_request_stdio_fwd(sock);
2200 exit(0); 2252 exit(0);
@@ -2207,6 +2259,9 @@ muxclient(const char *path)
2207 error("%s: master cancel forward request failed", 2259 error("%s: master cancel forward request failed",
2208 __func__); 2260 __func__);
2209 exit(0); 2261 exit(0);
2262 case SSHMUX_COMMAND_PROXY:
2263 mux_client_proxy(sock);
2264 return (sock);
2210 default: 2265 default:
2211 fatal("unrecognised muxclient_command %d", muxclient_command); 2266 fatal("unrecognised muxclient_command %d", muxclient_command);
2212 } 2267 }