summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
authordtucker <dtucker>2008-06-12 18:49:33 +0000
committerdtucker <dtucker>2008-06-12 18:49:33 +0000
commitea1d8db08490f82efa3149b0df499291ed793fe3 (patch)
tree78c16d89e940cd21c83d3dad2d73045e909f47b5 /mux.c
parentcbd570934d2554c78d25f6e4c71bb742de21f000 (diff)
downloadopenssh-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.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/mux.c b/mux.c
index 8b9105b0..efc3840c 100644
--- a/mux.c
+++ b/mux.c
@@ -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)