summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2008-06-13 04:49:33 +1000
committerDarren Tucker <dtucker@zip.com.au>2008-06-13 04:49:33 +1000
commit2fb66caca2c9e69c6a0584060114fcd52e59d5ff (patch)
treede895acfd51886da7e4ca547baea0b45e954c72e /mux.c
parent267e28bb75e97755ab3bbe128b75623734f2b3fd (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.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/mux.c b/mux.c
index 8b9105b04..efc3840cb 100644
--- a/mux.c
+++ b/mux.c
@@ -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;
71int subsystem_flag; 85int subsystem_flag;
72extern Buffer command; 86extern Buffer command;
73 87
88/* Context for session open confirmation callback */
89struct 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 */
75int muxserver_sock = -1; 101int 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. */
133static void 159static void
134client_extra_session2_setup(int id, void *arg) 160mux_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)