diff options
author | Darren Tucker <dtucker@zip.com.au> | 2008-06-13 04:49:33 +1000 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2008-06-13 04:49:33 +1000 |
commit | 2fb66caca2c9e69c6a0584060114fcd52e59d5ff (patch) | |
tree | de895acfd51886da7e4ca547baea0b45e954c72e /mux.c | |
parent | 267e28bb75e97755ab3bbe128b75623734f2b3fd (diff) |
- djm@cvs.openbsd.org 2008/06/12 03:40:52
[clientloop.h mux.c channels.c clientloop.c channels.h]
Enable ~ escapes for multiplex slave sessions; give each channel
its own escape state and hook the escape filters up to muxed
channels. bz #1331
Mux slaves do not currently support the ~^Z and ~& escapes.
NB. this change cranks the mux protocol version, so a new ssh
mux client will not be able to connect to a running old ssh
mux master.
ok dtucker@
Diffstat (limited to 'mux.c')
-rw-r--r-- | mux.c | 93 |
1 files changed, 62 insertions, 31 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mux.c,v 1.1 2008/05/09 14:18:44 djm Exp $ */ | 1 | /* $OpenBSD: mux.c,v 1.2 2008/06/12 03:40:52 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 | * |
@@ -19,6 +19,20 @@ | |||
19 | 19 | ||
20 | #include "includes.h" | 20 | #include "includes.h" |
21 | 21 | ||
22 | /* | ||
23 | * TODO: | ||
24 | * 1. partial reads in muxserver_accept_control (maybe make channels | ||
25 | * from accepted connections) | ||
26 | * 2. Better signalling from master to slave, especially passing of | ||
27 | * error messages | ||
28 | * 3. Better fall-back from mux slave error to new connection. | ||
29 | * 3. Add/delete forwardings via slave | ||
30 | * 4. ExitOnForwardingFailure (after #3 obviously) | ||
31 | * 5. Maybe extension mechanisms for multi-X11/multi-agent forwarding | ||
32 | * 6. Document the mux mini-protocol somewhere. | ||
33 | * 6. Support ~^Z in mux slaves. | ||
34 | */ | ||
35 | |||
22 | #include <sys/types.h> | 36 | #include <sys/types.h> |
23 | #include <sys/param.h> | 37 | #include <sys/param.h> |
24 | #include <sys/stat.h> | 38 | #include <sys/stat.h> |
@@ -71,6 +85,18 @@ extern char *host; | |||
71 | int subsystem_flag; | 85 | int subsystem_flag; |
72 | extern Buffer command; | 86 | extern Buffer command; |
73 | 87 | ||
88 | /* Context for session open confirmation callback */ | ||
89 | struct mux_session_confirm_ctx { | ||
90 | int want_tty; | ||
91 | int want_subsys; | ||
92 | int want_x_fwd; | ||
93 | int want_agent_fwd; | ||
94 | Buffer cmd; | ||
95 | char *term; | ||
96 | struct termios tio; | ||
97 | char **env; | ||
98 | }; | ||
99 | |||
74 | /* fd to control socket */ | 100 | /* fd to control socket */ |
75 | int muxserver_sock = -1; | 101 | int muxserver_sock = -1; |
76 | 102 | ||
@@ -131,7 +157,7 @@ muxserver_listen(void) | |||
131 | 157 | ||
132 | /* Callback on open confirmation in mux master for a mux client session. */ | 158 | /* Callback on open confirmation in mux master for a mux client session. */ |
133 | static void | 159 | static void |
134 | client_extra_session2_setup(int id, void *arg) | 160 | mux_session_confirm(int id, void *arg) |
135 | { | 161 | { |
136 | struct mux_session_confirm_ctx *cctx = arg; | 162 | struct mux_session_confirm_ctx *cctx = arg; |
137 | const char *display; | 163 | const char *display; |
@@ -190,7 +216,7 @@ muxserver_accept_control(void) | |||
190 | struct sockaddr_storage addr; | 216 | struct sockaddr_storage addr; |
191 | struct mux_session_confirm_ctx *cctx; | 217 | struct mux_session_confirm_ctx *cctx; |
192 | char *cmd; | 218 | char *cmd; |
193 | u_int i, j, len, env_len, mux_command, flags; | 219 | u_int i, j, len, env_len, mux_command, flags, escape_char; |
194 | uid_t euid; | 220 | uid_t euid; |
195 | gid_t egid; | 221 | gid_t egid; |
196 | int start_close = 0; | 222 | int start_close = 0; |
@@ -317,6 +343,7 @@ muxserver_accept_control(void) | |||
317 | cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; | 343 | cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; |
318 | cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; | 344 | cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; |
319 | cctx->term = buffer_get_string(&m, &len); | 345 | cctx->term = buffer_get_string(&m, &len); |
346 | escape_char = buffer_get_int(&m); | ||
320 | 347 | ||
321 | cmd = buffer_get_string(&m, &len); | 348 | cmd = buffer_get_string(&m, &len); |
322 | buffer_init(&cctx->cmd); | 349 | buffer_init(&cctx->cmd); |
@@ -402,14 +429,17 @@ muxserver_accept_control(void) | |||
402 | new_fd[0], new_fd[1], new_fd[2], window, packetmax, | 429 | new_fd[0], new_fd[1], new_fd[2], window, packetmax, |
403 | CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); | 430 | CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); |
404 | 431 | ||
405 | /* XXX */ | ||
406 | c->ctl_fd = client_fd; | 432 | c->ctl_fd = client_fd; |
433 | if (cctx->want_tty && escape_char != 0xffffffff) { | ||
434 | channel_register_filter(c->self, | ||
435 | client_simple_escape_filter, NULL, | ||
436 | client_new_escape_filter_ctx((int)escape_char)); | ||
437 | } | ||
407 | 438 | ||
408 | debug3("%s: channel_new: %d", __func__, c->self); | 439 | debug3("%s: channel_new: %d", __func__, c->self); |
409 | 440 | ||
410 | channel_send_open(c->self); | 441 | channel_send_open(c->self); |
411 | channel_register_open_confirm(c->self, | 442 | channel_register_open_confirm(c->self, mux_session_confirm, cctx); |
412 | client_extra_session2_setup, cctx); | ||
413 | return 0; | 443 | return 0; |
414 | } | 444 | } |
415 | 445 | ||
@@ -561,33 +591,34 @@ muxclient(const char *path) | |||
561 | fprintf(stderr, "Exit request sent.\r\n"); | 591 | fprintf(stderr, "Exit request sent.\r\n"); |
562 | exit(0); | 592 | exit(0); |
563 | case SSHMUX_COMMAND_OPEN: | 593 | case SSHMUX_COMMAND_OPEN: |
564 | /* continue below */ | 594 | buffer_put_cstring(&m, term ? term : ""); |
595 | if (options.escape_char == SSH_ESCAPECHAR_NONE) | ||
596 | buffer_put_int(&m, 0xffffffff); | ||
597 | else | ||
598 | buffer_put_int(&m, options.escape_char); | ||
599 | buffer_append(&command, "\0", 1); | ||
600 | buffer_put_cstring(&m, buffer_ptr(&command)); | ||
601 | |||
602 | if (options.num_send_env == 0 || environ == NULL) { | ||
603 | buffer_put_int(&m, 0); | ||
604 | } else { | ||
605 | /* Pass environment */ | ||
606 | num_env = 0; | ||
607 | for (i = 0; environ[i] != NULL; i++) { | ||
608 | if (env_permitted(environ[i])) | ||
609 | num_env++; /* Count */ | ||
610 | } | ||
611 | buffer_put_int(&m, num_env); | ||
612 | for (i = 0; environ[i] != NULL && num_env >= 0; i++) { | ||
613 | if (env_permitted(environ[i])) { | ||
614 | num_env--; | ||
615 | buffer_put_cstring(&m, environ[i]); | ||
616 | } | ||
617 | } | ||
618 | } | ||
565 | break; | 619 | break; |
566 | default: | 620 | default: |
567 | fatal("silly muxclient_command %d", muxclient_command); | 621 | fatal("unrecognised muxclient_command %d", muxclient_command); |
568 | } | ||
569 | |||
570 | /* SSHMUX_COMMAND_OPEN */ | ||
571 | buffer_put_cstring(&m, term ? term : ""); | ||
572 | buffer_append(&command, "\0", 1); | ||
573 | buffer_put_cstring(&m, buffer_ptr(&command)); | ||
574 | |||
575 | if (options.num_send_env == 0 || environ == NULL) { | ||
576 | buffer_put_int(&m, 0); | ||
577 | } else { | ||
578 | /* Pass environment */ | ||
579 | num_env = 0; | ||
580 | for (i = 0; environ[i] != NULL; i++) | ||
581 | if (env_permitted(environ[i])) | ||
582 | num_env++; /* Count */ | ||
583 | |||
584 | buffer_put_int(&m, num_env); | ||
585 | |||
586 | for (i = 0; environ[i] != NULL && num_env >= 0; i++) | ||
587 | if (env_permitted(environ[i])) { | ||
588 | num_env--; | ||
589 | buffer_put_cstring(&m, environ[i]); | ||
590 | } | ||
591 | } | 622 | } |
592 | 623 | ||
593 | if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) | 624 | if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) |