diff options
Diffstat (limited to 'mux.c')
-rw-r--r-- | mux.c | 87 |
1 files changed, 38 insertions, 49 deletions
@@ -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 { | |||
164 | static void mux_session_confirm(struct ssh *, int, int, void *); | 151 | static void mux_session_confirm(struct ssh *, int, int, void *); |
165 | static void mux_stdio_confirm(struct ssh *, int, int, void *); | 152 | static void mux_stdio_confirm(struct ssh *, int, int, void *); |
166 | 153 | ||
167 | static int process_mux_master_hello(struct ssh *, u_int, | 154 | static int mux_master_process_hello(struct ssh *, u_int, |
168 | Channel *, struct sshbuf *, struct sshbuf *); | 155 | Channel *, struct sshbuf *, struct sshbuf *); |
169 | static int process_mux_new_session(struct ssh *, u_int, | 156 | static int mux_master_process_new_session(struct ssh *, u_int, |
170 | Channel *, struct sshbuf *, struct sshbuf *); | 157 | Channel *, struct sshbuf *, struct sshbuf *); |
171 | static int process_mux_alive_check(struct ssh *, u_int, | 158 | static int mux_master_process_alive_check(struct ssh *, u_int, |
172 | Channel *, struct sshbuf *, struct sshbuf *); | 159 | Channel *, struct sshbuf *, struct sshbuf *); |
173 | static int process_mux_terminate(struct ssh *, u_int, | 160 | static int mux_master_process_terminate(struct ssh *, u_int, |
174 | Channel *, struct sshbuf *, struct sshbuf *); | 161 | Channel *, struct sshbuf *, struct sshbuf *); |
175 | static int process_mux_open_fwd(struct ssh *, u_int, | 162 | static int mux_master_process_open_fwd(struct ssh *, u_int, |
176 | Channel *, struct sshbuf *, struct sshbuf *); | 163 | Channel *, struct sshbuf *, struct sshbuf *); |
177 | static int process_mux_close_fwd(struct ssh *, u_int, | 164 | static int mux_master_process_close_fwd(struct ssh *, u_int, |
178 | Channel *, struct sshbuf *, struct sshbuf *); | 165 | Channel *, struct sshbuf *, struct sshbuf *); |
179 | static int process_mux_stdio_fwd(struct ssh *, u_int, | 166 | static int mux_master_process_stdio_fwd(struct ssh *, u_int, |
180 | Channel *, struct sshbuf *, struct sshbuf *); | 167 | Channel *, struct sshbuf *, struct sshbuf *); |
181 | static int process_mux_stop_listening(struct ssh *, u_int, | 168 | static int mux_master_process_stop_listening(struct ssh *, u_int, |
182 | Channel *, struct sshbuf *, struct sshbuf *); | 169 | Channel *, struct sshbuf *, struct sshbuf *); |
183 | static int process_mux_proxy(struct ssh *, u_int, | 170 | static int mux_master_process_proxy(struct ssh *, u_int, |
184 | Channel *, struct sshbuf *, struct sshbuf *); | 171 | Channel *, struct sshbuf *, struct sshbuf *); |
185 | 172 | ||
186 | static const struct { | 173 | static 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 | ||
280 | static int | 267 | static int |
281 | process_mux_master_hello(struct ssh *ssh, u_int rid, | 268 | mux_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 | ||
345 | static int | 334 | static int |
346 | process_mux_new_session(struct ssh *ssh, u_int rid, | 335 | mux_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 | ||
511 | static int | 500 | static int |
512 | process_mux_alive_check(struct ssh *ssh, u_int rid, | 501 | mux_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 | ||
528 | static int | 517 | static int |
529 | process_mux_terminate(struct ssh *ssh, u_int rid, | 518 | mux_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 | ||
696 | static int | 685 | static int |
697 | process_mux_open_fwd(struct ssh *ssh, u_int rid, | 686 | mux_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 | ||
863 | static int | 852 | static int |
864 | process_mux_close_fwd(struct ssh *ssh, u_int rid, | 853 | mux_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 | ||
975 | static int | 964 | static int |
976 | process_mux_stdio_fwd(struct ssh *ssh, u_int rid, | 965 | mux_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 | ||
1113 | static int | 1102 | static int |
1114 | process_mux_stop_listening(struct ssh *ssh, u_int rid, | 1103 | mux_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 | ||
1143 | static int | 1132 | static int |
1144 | process_mux_proxy(struct ssh *ssh, u_int rid, | 1133 | mux_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; |