diff options
author | dtucker <dtucker> | 2008-06-12 18:49:33 +0000 |
---|---|---|
committer | dtucker <dtucker> | 2008-06-12 18:49:33 +0000 |
commit | ea1d8db08490f82efa3149b0df499291ed793fe3 (patch) | |
tree | 78c16d89e940cd21c83d3dad2d73045e909f47b5 /mux.c | |
parent | cbd570934d2554c78d25f6e4c71bb742de21f000 (diff) | |
download | openssh-ea1d8db08490f82efa3149b0df499291ed793fe3.tar.gz |
- 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 @@ -/* $OpenBSD: mux.c,v 1.1 2008/05/09 14:18:44 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.2 2008/06/12 03:40:52 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> * @@ -19,6 +19,20 @@ #include "includes.h" +/* + * TODO: + * 1. partial reads in muxserver_accept_control (maybe make channels + * from accepted connections) + * 2. Better signalling from master to slave, especially passing of + * error messages + * 3. Better fall-back from mux slave error to new connection. + * 3. Add/delete forwardings via slave + * 4. ExitOnForwardingFailure (after #3 obviously) + * 5. Maybe extension mechanisms for multi-X11/multi-agent forwarding + * 6. Document the mux mini-protocol somewhere. + * 6. Support ~^Z in mux slaves. + */ + #include <sys/types.h> #include <sys/param.h> #include <sys/stat.h> @@ -71,6 +85,18 @@ extern char *host; int subsystem_flag; extern Buffer command; +/* Context for session open confirmation callback */ +struct mux_session_confirm_ctx { + int want_tty; + int want_subsys; + int want_x_fwd; + int want_agent_fwd; + Buffer cmd; + char *term; + struct termios tio; + char **env; +}; + /* fd to control socket */ int muxserver_sock = -1; @@ -131,7 +157,7 @@ muxserver_listen(void) /* Callback on open confirmation in mux master for a mux client session. */ static void -client_extra_session2_setup(int id, void *arg) +mux_session_confirm(int id, void *arg) { struct mux_session_confirm_ctx *cctx = arg; const char *display; @@ -190,7 +216,7 @@ muxserver_accept_control(void) struct sockaddr_storage addr; struct mux_session_confirm_ctx *cctx; char *cmd; - u_int i, j, len, env_len, mux_command, flags; + u_int i, j, len, env_len, mux_command, flags, escape_char; uid_t euid; gid_t egid; int start_close = 0; @@ -317,6 +343,7 @@ muxserver_accept_control(void) cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; cctx->term = buffer_get_string(&m, &len); + escape_char = buffer_get_int(&m); cmd = buffer_get_string(&m, &len); buffer_init(&cctx->cmd); @@ -402,14 +429,17 @@ muxserver_accept_control(void) new_fd[0], new_fd[1], new_fd[2], window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); - /* XXX */ c->ctl_fd = client_fd; + if (cctx->want_tty && escape_char != 0xffffffff) { + channel_register_filter(c->self, + client_simple_escape_filter, NULL, + client_new_escape_filter_ctx((int)escape_char)); + } debug3("%s: channel_new: %d", __func__, c->self); channel_send_open(c->self); - channel_register_open_confirm(c->self, - client_extra_session2_setup, cctx); + channel_register_open_confirm(c->self, mux_session_confirm, cctx); return 0; } @@ -561,33 +591,34 @@ muxclient(const char *path) fprintf(stderr, "Exit request sent.\r\n"); exit(0); case SSHMUX_COMMAND_OPEN: - /* continue below */ + buffer_put_cstring(&m, term ? term : ""); + if (options.escape_char == SSH_ESCAPECHAR_NONE) + buffer_put_int(&m, 0xffffffff); + else + buffer_put_int(&m, options.escape_char); + buffer_append(&command, "\0", 1); + buffer_put_cstring(&m, buffer_ptr(&command)); + + if (options.num_send_env == 0 || environ == NULL) { + buffer_put_int(&m, 0); + } else { + /* Pass environment */ + num_env = 0; + for (i = 0; environ[i] != NULL; i++) { + if (env_permitted(environ[i])) + num_env++; /* Count */ + } + buffer_put_int(&m, num_env); + for (i = 0; environ[i] != NULL && num_env >= 0; i++) { + if (env_permitted(environ[i])) { + num_env--; + buffer_put_cstring(&m, environ[i]); + } + } + } break; default: - fatal("silly muxclient_command %d", muxclient_command); - } - - /* SSHMUX_COMMAND_OPEN */ - buffer_put_cstring(&m, term ? term : ""); - buffer_append(&command, "\0", 1); - buffer_put_cstring(&m, buffer_ptr(&command)); - - if (options.num_send_env == 0 || environ == NULL) { - buffer_put_int(&m, 0); - } else { - /* Pass environment */ - num_env = 0; - for (i = 0; environ[i] != NULL; i++) - if (env_permitted(environ[i])) - num_env++; /* Count */ - - buffer_put_int(&m, num_env); - - for (i = 0; environ[i] != NULL && num_env >= 0; i++) - if (env_permitted(environ[i])) { - num_env--; - buffer_put_cstring(&m, environ[i]); - } + fatal("unrecognised muxclient_command %d", muxclient_command); } if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) |