summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c87
1 files changed, 38 insertions, 49 deletions
diff --git a/mux.c b/mux.c
index e607acd08..8e4b60827 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.75 2018/07/31 03:07:24 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.77 2018/09/26 07:32: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 *
@@ -17,19 +17,6 @@
17 17
18/* ssh session multiplexing support */ 18/* ssh session multiplexing support */
19 19
20/*
21 * TODO:
22 * - Better signalling from master to slave, especially passing of
23 * error messages
24 * - Better fall-back from mux slave error to new connection.
25 * - ExitOnForwardingFailure
26 * - Maybe extension mechanisms for multi-X11/multi-agent forwarding
27 * - Support ~^Z in mux slaves.
28 * - Inspect or control sessions in master.
29 * - If we ever support the "signal" channel request, send signals on
30 * sessions in master.
31 */
32
33#include "includes.h" 20#include "includes.h"
34 21
35#include <sys/types.h> 22#include <sys/types.h>
@@ -164,23 +151,23 @@ struct mux_master_state {
164static void mux_session_confirm(struct ssh *, int, int, void *); 151static void mux_session_confirm(struct ssh *, int, int, void *);
165static void mux_stdio_confirm(struct ssh *, int, int, void *); 152static void mux_stdio_confirm(struct ssh *, int, int, void *);
166 153
167static int process_mux_master_hello(struct ssh *, u_int, 154static int mux_master_process_hello(struct ssh *, u_int,
168 Channel *, struct sshbuf *, struct sshbuf *); 155 Channel *, struct sshbuf *, struct sshbuf *);
169static int process_mux_new_session(struct ssh *, u_int, 156static int mux_master_process_new_session(struct ssh *, u_int,
170 Channel *, struct sshbuf *, struct sshbuf *); 157 Channel *, struct sshbuf *, struct sshbuf *);
171static int process_mux_alive_check(struct ssh *, u_int, 158static int mux_master_process_alive_check(struct ssh *, u_int,
172 Channel *, struct sshbuf *, struct sshbuf *); 159 Channel *, struct sshbuf *, struct sshbuf *);
173static int process_mux_terminate(struct ssh *, u_int, 160static int mux_master_process_terminate(struct ssh *, u_int,
174 Channel *, struct sshbuf *, struct sshbuf *); 161 Channel *, struct sshbuf *, struct sshbuf *);
175static int process_mux_open_fwd(struct ssh *, u_int, 162static int mux_master_process_open_fwd(struct ssh *, u_int,
176 Channel *, struct sshbuf *, struct sshbuf *); 163 Channel *, struct sshbuf *, struct sshbuf *);
177static int process_mux_close_fwd(struct ssh *, u_int, 164static int mux_master_process_close_fwd(struct ssh *, u_int,
178 Channel *, struct sshbuf *, struct sshbuf *); 165 Channel *, struct sshbuf *, struct sshbuf *);
179static int process_mux_stdio_fwd(struct ssh *, u_int, 166static int mux_master_process_stdio_fwd(struct ssh *, u_int,
180 Channel *, struct sshbuf *, struct sshbuf *); 167 Channel *, struct sshbuf *, struct sshbuf *);
181static int process_mux_stop_listening(struct ssh *, u_int, 168static int mux_master_process_stop_listening(struct ssh *, u_int,
182 Channel *, struct sshbuf *, struct sshbuf *); 169 Channel *, struct sshbuf *, struct sshbuf *);
183static int process_mux_proxy(struct ssh *, u_int, 170static int mux_master_process_proxy(struct ssh *, u_int,
184 Channel *, struct sshbuf *, struct sshbuf *); 171 Channel *, struct sshbuf *, struct sshbuf *);
185 172
186static const struct { 173static const struct {
@@ -188,15 +175,15 @@ static const struct {
188 int (*handler)(struct ssh *, u_int, Channel *, 175 int (*handler)(struct ssh *, u_int, Channel *,
189 struct sshbuf *, struct sshbuf *); 176 struct sshbuf *, struct sshbuf *);
190} mux_master_handlers[] = { 177} mux_master_handlers[] = {
191 { MUX_MSG_HELLO, process_mux_master_hello }, 178 { MUX_MSG_HELLO, mux_master_process_hello },
192 { MUX_C_NEW_SESSION, process_mux_new_session }, 179 { MUX_C_NEW_SESSION, mux_master_process_new_session },
193 { MUX_C_ALIVE_CHECK, process_mux_alive_check }, 180 { MUX_C_ALIVE_CHECK, mux_master_process_alive_check },
194 { MUX_C_TERMINATE, process_mux_terminate }, 181 { MUX_C_TERMINATE, mux_master_process_terminate },
195 { MUX_C_OPEN_FWD, process_mux_open_fwd }, 182 { MUX_C_OPEN_FWD, mux_master_process_open_fwd },
196 { MUX_C_CLOSE_FWD, process_mux_close_fwd }, 183 { MUX_C_CLOSE_FWD, mux_master_process_close_fwd },
197 { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd }, 184 { MUX_C_NEW_STDIO_FWD, mux_master_process_stdio_fwd },
198 { MUX_C_STOP_LISTENING, process_mux_stop_listening }, 185 { MUX_C_STOP_LISTENING, mux_master_process_stop_listening },
199 { MUX_C_PROXY, process_mux_proxy }, 186 { MUX_C_PROXY, mux_master_process_proxy },
200 { 0, NULL } 187 { 0, NULL }
201}; 188};
202 189
@@ -264,7 +251,7 @@ env_permitted(char *env)
264 return 0; 251 return 0;
265 ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env); 252 ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
266 if (ret <= 0 || (size_t)ret >= sizeof(name)) { 253 if (ret <= 0 || (size_t)ret >= sizeof(name)) {
267 error("env_permitted: name '%.100s...' too long", env); 254 error("%s: name '%.100s...' too long", __func__, env);
268 return 0; 255 return 0;
269 } 256 }
270 257
@@ -278,7 +265,7 @@ env_permitted(char *env)
278/* Mux master protocol message handlers */ 265/* Mux master protocol message handlers */
279 266
280static int 267static int
281process_mux_master_hello(struct ssh *ssh, u_int rid, 268mux_master_process_hello(struct ssh *ssh, u_int rid,
282 Channel *c, struct sshbuf *m, struct sshbuf *reply) 269 Channel *c, struct sshbuf *m, struct sshbuf *reply)
283{ 270{
284 u_int ver; 271 u_int ver;
@@ -296,8 +283,8 @@ process_mux_master_hello(struct ssh *ssh, u_int rid,
296 return -1; 283 return -1;
297 } 284 }
298 if (ver != SSHMUX_VER) { 285 if (ver != SSHMUX_VER) {
299 error("Unsupported multiplexing protocol version %d " 286 error("%s: unsupported multiplexing protocol version %u "
300 "(expected %d)", ver, SSHMUX_VER); 287 "(expected %u)", __func__, ver, SSHMUX_VER);
301 return -1; 288 return -1;
302 } 289 }
303 debug2("%s: channel %d slave version %u", __func__, c->self, ver); 290 debug2("%s: channel %d slave version %u", __func__, c->self, ver);
@@ -305,14 +292,16 @@ process_mux_master_hello(struct ssh *ssh, u_int rid,
305 /* No extensions are presently defined */ 292 /* No extensions are presently defined */
306 while (sshbuf_len(m) > 0) { 293 while (sshbuf_len(m) > 0) {
307 char *name = NULL; 294 char *name = NULL;
295 size_t value_len = 0;
308 296
309 if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 || 297 if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||
310 (r = sshbuf_skip_string(m)) != 0) { /* value */ 298 (r = sshbuf_get_string_direct(m, NULL, &value_len)) != 0) {
311 error("%s: malformed extension: %s", 299 error("%s: malformed extension: %s",
312 __func__, ssh_err(r)); 300 __func__, ssh_err(r));
313 return -1; 301 return -1;
314 } 302 }
315 debug2("Unrecognised slave extension \"%s\"", name); 303 debug2("%s: Unrecognised extension \"%s\" length %zu",
304 __func__, name, value_len);
316 free(name); 305 free(name);
317 } 306 }
318 state->hello_rcvd = 1; 307 state->hello_rcvd = 1;
@@ -343,7 +332,7 @@ reply_error(struct sshbuf *reply, u_int type, u_int rid, const char *msg)
343} 332}
344 333
345static int 334static int
346process_mux_new_session(struct ssh *ssh, u_int rid, 335mux_master_process_new_session(struct ssh *ssh, u_int rid,
347 Channel *c, struct sshbuf *m, struct sshbuf *reply) 336 Channel *c, struct sshbuf *m, struct sshbuf *reply)
348{ 337{
349 Channel *nc; 338 Channel *nc;
@@ -391,8 +380,8 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
391 cctx->env[env_len++] = cp; 380 cctx->env[env_len++] = cp;
392 cctx->env[env_len] = NULL; 381 cctx->env[env_len] = NULL;
393 if (env_len > MUX_MAX_ENV_VARS) { 382 if (env_len > MUX_MAX_ENV_VARS) {
394 error(">%d environment variables received, ignoring " 383 error("%s: >%d environment variables received, "
395 "additional", MUX_MAX_ENV_VARS); 384 "ignoring additional", __func__, MUX_MAX_ENV_VARS);
396 break; 385 break;
397 } 386 }
398 } 387 }
@@ -509,7 +498,7 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
509} 498}
510 499
511static int 500static int
512process_mux_alive_check(struct ssh *ssh, u_int rid, 501mux_master_process_alive_check(struct ssh *ssh, u_int rid,
513 Channel *c, struct sshbuf *m, struct sshbuf *reply) 502 Channel *c, struct sshbuf *m, struct sshbuf *reply)
514{ 503{
515 int r; 504 int r;
@@ -526,7 +515,7 @@ process_mux_alive_check(struct ssh *ssh, u_int rid,
526} 515}
527 516
528static int 517static int
529process_mux_terminate(struct ssh *ssh, u_int rid, 518mux_master_process_terminate(struct ssh *ssh, u_int rid,
530 Channel *c, struct sshbuf *m, struct sshbuf *reply) 519 Channel *c, struct sshbuf *m, struct sshbuf *reply)
531{ 520{
532 debug2("%s: channel %d: terminate request", __func__, c->self); 521 debug2("%s: channel %d: terminate request", __func__, c->self);
@@ -694,7 +683,7 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
694} 683}
695 684
696static int 685static int
697process_mux_open_fwd(struct ssh *ssh, u_int rid, 686mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
698 Channel *c, struct sshbuf *m, struct sshbuf *reply) 687 Channel *c, struct sshbuf *m, struct sshbuf *reply)
699{ 688{
700 struct Forward fwd; 689 struct Forward fwd;
@@ -823,7 +812,7 @@ process_mux_open_fwd(struct ssh *ssh, u_int rid,
823 if (!channel_setup_local_fwd_listener(ssh, &fwd, 812 if (!channel_setup_local_fwd_listener(ssh, &fwd,
824 &options.fwd_opts)) { 813 &options.fwd_opts)) {
825 fail: 814 fail:
826 logit("slave-requested %s failed", fwd_desc); 815 logit("%s: requested %s failed", __func__, fwd_desc);
827 reply_error(reply, MUX_S_FAILURE, rid, 816 reply_error(reply, MUX_S_FAILURE, rid,
828 "Port forwarding failed"); 817 "Port forwarding failed");
829 goto out; 818 goto out;
@@ -861,7 +850,7 @@ process_mux_open_fwd(struct ssh *ssh, u_int rid,
861} 850}
862 851
863static int 852static int
864process_mux_close_fwd(struct ssh *ssh, u_int rid, 853mux_master_process_close_fwd(struct ssh *ssh, u_int rid,
865 Channel *c, struct sshbuf *m, struct sshbuf *reply) 854 Channel *c, struct sshbuf *m, struct sshbuf *reply)
866{ 855{
867 struct Forward fwd, *found_fwd; 856 struct Forward fwd, *found_fwd;
@@ -973,7 +962,7 @@ process_mux_close_fwd(struct ssh *ssh, u_int rid,
973} 962}
974 963
975static int 964static int
976process_mux_stdio_fwd(struct ssh *ssh, u_int rid, 965mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid,
977 Channel *c, struct sshbuf *m, struct sshbuf *reply) 966 Channel *c, struct sshbuf *m, struct sshbuf *reply)
978{ 967{
979 Channel *nc; 968 Channel *nc;
@@ -1111,7 +1100,7 @@ mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1111} 1100}
1112 1101
1113static int 1102static int
1114process_mux_stop_listening(struct ssh *ssh, u_int rid, 1103mux_master_process_stop_listening(struct ssh *ssh, u_int rid,
1115 Channel *c, struct sshbuf *m, struct sshbuf *reply) 1104 Channel *c, struct sshbuf *m, struct sshbuf *reply)
1116{ 1105{
1117 debug("%s: channel %d: stop listening", __func__, c->self); 1106 debug("%s: channel %d: stop listening", __func__, c->self);
@@ -1141,7 +1130,7 @@ process_mux_stop_listening(struct ssh *ssh, u_int rid,
1141} 1130}
1142 1131
1143static int 1132static int
1144process_mux_proxy(struct ssh *ssh, u_int rid, 1133mux_master_process_proxy(struct ssh *ssh, u_int rid,
1145 Channel *c, struct sshbuf *m, struct sshbuf *reply) 1134 Channel *c, struct sshbuf *m, struct sshbuf *reply)
1146{ 1135{
1147 int r; 1136 int r;