Annotation of src/usr.bin/ssh/mux.c, Revision 1.22
1.22 ! djm 1: /* $OpenBSD: mux.c,v 1.21 2010/06/25 23:15:36 djm Exp $ */
1.1 djm 2: /*
3: * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: /* ssh session multiplexing support */
19:
1.2 djm 20: /*
21: * TODO:
1.10 djm 22: * - Better signalling from master to slave, especially passing of
1.2 djm 23: * error messages
1.10 djm 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.
1.2 djm 31: */
32:
1.1 djm 33: #include <sys/types.h>
34: #include <sys/param.h>
35: #include <sys/queue.h>
36: #include <sys/stat.h>
37: #include <sys/socket.h>
38: #include <sys/un.h>
39:
40: #include <errno.h>
41: #include <fcntl.h>
1.10 djm 42: #include <poll.h>
1.1 djm 43: #include <signal.h>
44: #include <stdarg.h>
45: #include <stddef.h>
46: #include <stdlib.h>
47: #include <stdio.h>
48: #include <string.h>
49: #include <unistd.h>
50: #include <util.h>
51: #include <paths.h>
52:
1.10 djm 53: #include "atomicio.h"
1.1 djm 54: #include "xmalloc.h"
55: #include "log.h"
56: #include "ssh.h"
1.18 markus 57: #include "ssh2.h"
1.1 djm 58: #include "pathnames.h"
59: #include "misc.h"
60: #include "match.h"
61: #include "buffer.h"
62: #include "channels.h"
63: #include "msg.h"
64: #include "packet.h"
65: #include "monitor_fdpass.h"
66: #include "sshpty.h"
67: #include "key.h"
68: #include "readconf.h"
69: #include "clientloop.h"
70:
71: /* from ssh.c */
72: extern int tty_flag;
1.9 djm 73: extern int force_tty_flag;
1.1 djm 74: extern Options options;
75: extern int stdin_null_flag;
76: extern char *host;
1.8 dtucker 77: extern int subsystem_flag;
1.1 djm 78: extern Buffer command;
1.10 djm 79: extern volatile sig_atomic_t quit_pending;
80: extern char *stdio_forward_host;
81: extern int stdio_forward_port;
1.1 djm 82:
1.2 djm 83: /* Context for session open confirmation callback */
84: struct mux_session_confirm_ctx {
1.10 djm 85: u_int want_tty;
86: u_int want_subsys;
87: u_int want_x_fwd;
88: u_int want_agent_fwd;
1.2 djm 89: Buffer cmd;
90: char *term;
91: struct termios tio;
92: char **env;
1.17 djm 93: u_int rid;
1.2 djm 94: };
95:
1.18 markus 96: /* Context for global channel callback */
97: struct mux_channel_confirm_ctx {
98: u_int cid; /* channel id */
99: u_int rid; /* request id */
100: int fid; /* forward id */
101: };
102:
1.1 djm 103: /* fd to control socket */
104: int muxserver_sock = -1;
105:
1.10 djm 106: /* client request id */
107: u_int muxclient_request_id = 0;
108:
1.1 djm 109: /* Multiplexing control command */
110: u_int muxclient_command = 0;
111:
112: /* Set when signalled. */
113: static volatile sig_atomic_t muxclient_terminate = 0;
114:
115: /* PID of multiplex server */
116: static u_int muxserver_pid = 0;
117:
1.10 djm 118: static Channel *mux_listener_channel = NULL;
119:
120: struct mux_master_state {
121: int hello_rcvd;
122: };
1.1 djm 123:
1.10 djm 124: /* mux protocol messages */
125: #define MUX_MSG_HELLO 0x00000001
126: #define MUX_C_NEW_SESSION 0x10000002
127: #define MUX_C_ALIVE_CHECK 0x10000004
128: #define MUX_C_TERMINATE 0x10000005
129: #define MUX_C_OPEN_FWD 0x10000006
130: #define MUX_C_CLOSE_FWD 0x10000007
131: #define MUX_C_NEW_STDIO_FWD 0x10000008
132: #define MUX_S_OK 0x80000001
133: #define MUX_S_PERMISSION_DENIED 0x80000002
134: #define MUX_S_FAILURE 0x80000003
135: #define MUX_S_EXIT_MESSAGE 0x80000004
136: #define MUX_S_ALIVE 0x80000005
137: #define MUX_S_SESSION_OPENED 0x80000006
1.18 markus 138: #define MUX_S_REMOTE_PORT 0x80000007
1.10 djm 139:
140: /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
141: #define MUX_FWD_LOCAL 1
142: #define MUX_FWD_REMOTE 2
143: #define MUX_FWD_DYNAMIC 3
144:
1.17 djm 145: static void mux_session_confirm(int, int, void *);
1.10 djm 146:
147: static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *);
148: static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *);
149: static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *);
150: static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *);
151: static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
152: static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
153: static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
154:
155: static const struct {
156: u_int type;
157: int (*handler)(u_int, Channel *, Buffer *, Buffer *);
158: } mux_master_handlers[] = {
159: { MUX_MSG_HELLO, process_mux_master_hello },
160: { MUX_C_NEW_SESSION, process_mux_new_session },
161: { MUX_C_ALIVE_CHECK, process_mux_alive_check },
162: { MUX_C_TERMINATE, process_mux_terminate },
163: { MUX_C_OPEN_FWD, process_mux_open_fwd },
164: { MUX_C_CLOSE_FWD, process_mux_close_fwd },
165: { MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },
166: { 0, NULL }
167: };
1.1 djm 168:
1.10 djm 169: /* Cleanup callback fired on closure of mux slave _session_ channel */
170: /* ARGSUSED */
171: static void
172: mux_master_session_cleanup_cb(int cid, void *unused)
1.1 djm 173: {
1.10 djm 174: Channel *cc, *c = channel_by_id(cid);
1.1 djm 175:
1.10 djm 176: debug3("%s: entering for channel %d", __func__, cid);
177: if (c == NULL)
178: fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
179: if (c->ctl_chan != -1) {
180: if ((cc = channel_by_id(c->ctl_chan)) == NULL)
181: fatal("%s: channel %d missing control channel %d",
182: __func__, c->self, c->ctl_chan);
183: c->ctl_chan = -1;
184: cc->remote_id = -1;
185: chan_rcvd_oclose(cc);
1.1 djm 186: }
1.10 djm 187: channel_cancel_cleanup(c->self);
1.1 djm 188: }
189:
1.10 djm 190: /* Cleanup callback fired on closure of mux slave _control_ channel */
191: /* ARGSUSED */
1.1 djm 192: static void
1.10 djm 193: mux_master_control_cleanup_cb(int cid, void *unused)
1.1 djm 194: {
1.10 djm 195: Channel *sc, *c = channel_by_id(cid);
1.1 djm 196:
1.10 djm 197: debug3("%s: entering for channel %d", __func__, cid);
198: if (c == NULL)
199: fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
200: if (c->remote_id != -1) {
201: if ((sc = channel_by_id(c->remote_id)) == NULL)
1.15 djm 202: fatal("%s: channel %d missing session channel %d",
1.10 djm 203: __func__, c->self, c->remote_id);
204: c->remote_id = -1;
205: sc->ctl_chan = -1;
1.12 djm 206: if (sc->type != SSH_CHANNEL_OPEN) {
207: debug2("%s: channel %d: not open", __func__, sc->self);
1.13 djm 208: chan_mark_dead(sc);
1.12 djm 209: } else {
1.14 djm 210: if (sc->istate == CHAN_INPUT_OPEN)
211: chan_read_failed(sc);
212: if (sc->ostate == CHAN_OUTPUT_OPEN)
213: chan_write_failed(sc);
1.12 djm 214: }
1.1 djm 215: }
1.10 djm 216: channel_cancel_cleanup(c->self);
1.1 djm 217: }
218:
1.10 djm 219: /* Check mux client environment variables before passing them to mux master. */
220: static int
221: env_permitted(char *env)
1.1 djm 222: {
1.10 djm 223: int i, ret;
224: char name[1024], *cp;
1.1 djm 225:
1.10 djm 226: if ((cp = strchr(env, '=')) == NULL || cp == env)
1.1 djm 227: return 0;
1.10 djm 228: ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
229: if (ret <= 0 || (size_t)ret >= sizeof(name)) {
230: error("env_permitted: name '%.100s...' too long", env);
1.1 djm 231: return 0;
232: }
233:
1.10 djm 234: for (i = 0; i < options.num_send_env; i++)
235: if (match_pattern(name, options.send_env[i]))
236: return 1;
1.1 djm 237:
1.10 djm 238: return 0;
239: }
1.1 djm 240:
1.10 djm 241: /* Mux master protocol message handlers */
1.1 djm 242:
1.10 djm 243: static int
244: process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)
245: {
246: u_int ver;
247: struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
1.1 djm 248:
1.10 djm 249: if (state == NULL)
250: fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self);
251: if (state->hello_rcvd) {
252: error("%s: HELLO received twice", __func__);
253: return -1;
254: }
255: if (buffer_get_int_ret(&ver, m) != 0) {
256: malf:
257: error("%s: malformed message", __func__);
258: return -1;
259: }
260: if (ver != SSHMUX_VER) {
261: error("Unsupported multiplexing protocol version %d "
262: "(expected %d)", ver, SSHMUX_VER);
263: return -1;
264: }
265: debug2("%s: channel %d slave version %u", __func__, c->self, ver);
266:
267: /* No extensions are presently defined */
268: while (buffer_len(m) > 0) {
269: char *name = buffer_get_string_ret(m, NULL);
270: char *value = buffer_get_string_ret(m, NULL);
271:
272: if (name == NULL || value == NULL) {
273: if (name != NULL)
274: xfree(name);
275: goto malf;
1.1 djm 276: }
1.10 djm 277: debug2("Unrecognised slave extension \"%s\"", name);
278: xfree(name);
279: xfree(value);
1.1 djm 280: }
1.10 djm 281: state->hello_rcvd = 1;
282: return 0;
283: }
284:
285: static int
286: process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
287: {
288: Channel *nc;
289: struct mux_session_confirm_ctx *cctx;
290: char *reserved, *cmd, *cp;
291: u_int i, j, len, env_len, escape_char, window, packetmax;
292: int new_fd[3];
1.1 djm 293:
294: /* Reply for SSHMUX_COMMAND_OPEN */
1.10 djm 295: cctx = xcalloc(1, sizeof(*cctx));
296: cctx->term = NULL;
1.17 djm 297: cctx->rid = rid;
1.11 djm 298: cmd = reserved = NULL;
1.10 djm 299: if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
300: buffer_get_int_ret(&cctx->want_tty, m) != 0 ||
301: buffer_get_int_ret(&cctx->want_x_fwd, m) != 0 ||
302: buffer_get_int_ret(&cctx->want_agent_fwd, m) != 0 ||
303: buffer_get_int_ret(&cctx->want_subsys, m) != 0 ||
304: buffer_get_int_ret(&escape_char, m) != 0 ||
305: (cctx->term = buffer_get_string_ret(m, &len)) == NULL ||
306: (cmd = buffer_get_string_ret(m, &len)) == NULL) {
307: malf:
1.11 djm 308: if (cmd != NULL)
309: xfree(cmd);
310: if (reserved != NULL)
311: xfree(reserved);
1.10 djm 312: if (cctx->term != NULL)
313: xfree(cctx->term);
314: error("%s: malformed message", __func__);
315: return -1;
1.1 djm 316: }
1.10 djm 317: xfree(reserved);
1.11 djm 318: reserved = NULL;
1.1 djm 319:
1.10 djm 320: cctx->env = NULL;
321: env_len = 0;
322: while (buffer_len(m) > 0) {
323: #define MUX_MAX_ENV_VARS 4096
324: if ((cp = buffer_get_string_ret(m, &len)) == NULL) {
325: xfree(cmd);
326: goto malf;
327: }
328: if (!env_permitted(cp)) {
329: xfree(cp);
330: continue;
331: }
332: cctx->env = xrealloc(cctx->env, env_len + 2,
333: sizeof(*cctx->env));
334: cctx->env[env_len++] = cp;
335: cctx->env[env_len] = NULL;
336: if (env_len > MUX_MAX_ENV_VARS) {
337: error(">%d environment variables received, ignoring "
338: "additional", MUX_MAX_ENV_VARS);
339: break;
340: }
1.1 djm 341: }
342:
1.10 djm 343: debug2("%s: channel %d: request tty %d, X %d, agent %d, subsys %d, "
344: "term \"%s\", cmd \"%s\", env %u", __func__, c->self,
345: cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd,
346: cctx->want_subsys, cctx->term, cmd, env_len);
1.1 djm 347:
348: buffer_init(&cctx->cmd);
349: buffer_append(&cctx->cmd, cmd, strlen(cmd));
350: xfree(cmd);
1.11 djm 351: cmd = NULL;
1.1 djm 352:
353: /* Gather fds from client */
354: for(i = 0; i < 3; i++) {
1.10 djm 355: if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
1.1 djm 356: error("%s: failed to receive fd %d from slave",
357: __func__, i);
358: for (j = 0; j < i; j++)
359: close(new_fd[j]);
360: for (j = 0; j < env_len; j++)
361: xfree(cctx->env[j]);
362: if (env_len > 0)
363: xfree(cctx->env);
364: xfree(cctx->term);
365: buffer_free(&cctx->cmd);
366: xfree(cctx);
1.10 djm 367:
368: /* prepare reply */
369: buffer_put_int(r, MUX_S_FAILURE);
370: buffer_put_int(r, rid);
371: buffer_put_cstring(r,
372: "did not receive file descriptors");
373: return -1;
1.1 djm 374: }
375: }
376:
1.10 djm 377: debug3("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
1.1 djm 378: new_fd[0], new_fd[1], new_fd[2]);
379:
1.10 djm 380: /* XXX support multiple child sessions in future */
381: if (c->remote_id != -1) {
382: debug2("%s: session already open", __func__);
383: /* prepare reply */
384: buffer_put_int(r, MUX_S_FAILURE);
385: buffer_put_int(r, rid);
386: buffer_put_cstring(r, "Multiple sessions not supported");
387: cleanup:
1.1 djm 388: close(new_fd[0]);
389: close(new_fd[1]);
390: close(new_fd[2]);
391: xfree(cctx->term);
392: if (env_len != 0) {
393: for (i = 0; i < env_len; i++)
394: xfree(cctx->env[i]);
395: xfree(cctx->env);
396: }
1.10 djm 397: buffer_free(&cctx->cmd);
1.1 djm 398: return 0;
399: }
1.10 djm 400:
401: if (options.control_master == SSHCTL_MASTER_ASK ||
402: options.control_master == SSHCTL_MASTER_AUTO_ASK) {
403: if (!ask_permission("Allow shared connection to %s? ", host)) {
404: debug2("%s: session refused by user", __func__);
405: /* prepare reply */
406: buffer_put_int(r, MUX_S_PERMISSION_DENIED);
407: buffer_put_int(r, rid);
408: buffer_put_cstring(r, "Permission denied");
409: goto cleanup;
410: }
411: }
412:
413: /* Try to pick up ttymodes from client before it goes raw */
414: if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
415: error("%s: tcgetattr: %s", __func__, strerror(errno));
1.1 djm 416:
417: /* enable nonblocking unless tty */
418: if (!isatty(new_fd[0]))
419: set_nonblock(new_fd[0]);
420: if (!isatty(new_fd[1]))
421: set_nonblock(new_fd[1]);
422: if (!isatty(new_fd[2]))
423: set_nonblock(new_fd[2]);
424:
425: window = CHAN_SES_WINDOW_DEFAULT;
426: packetmax = CHAN_SES_PACKET_DEFAULT;
427: if (cctx->want_tty) {
428: window >>= 1;
429: packetmax >>= 1;
430: }
1.10 djm 431:
432: nc = channel_new("session", SSH_CHANNEL_OPENING,
1.1 djm 433: new_fd[0], new_fd[1], new_fd[2], window, packetmax,
434: CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
435:
1.10 djm 436: nc->ctl_chan = c->self; /* link session -> control channel */
437: c->remote_id = nc->self; /* link control -> session channel */
438:
1.2 djm 439: if (cctx->want_tty && escape_char != 0xffffffff) {
1.10 djm 440: channel_register_filter(nc->self,
1.2 djm 441: client_simple_escape_filter, NULL,
1.4 djm 442: client_filter_cleanup,
1.2 djm 443: client_new_escape_filter_ctx((int)escape_char));
444: }
1.1 djm 445:
1.10 djm 446: debug2("%s: channel_new: %d linked to control channel %d",
447: __func__, nc->self, nc->ctl_chan);
448:
449: channel_send_open(nc->self);
450: channel_register_open_confirm(nc->self, mux_session_confirm, cctx);
1.17 djm 451: c->mux_pause = 1; /* stop handling messages until open_confirm done */
1.16 djm 452: channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);
1.10 djm 453:
1.17 djm 454: /* reply is deferred, sent by mux_session_confirm */
1.1 djm 455: return 0;
456: }
457:
1.10 djm 458: static int
459: process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r)
1.1 djm 460: {
1.10 djm 461: debug2("%s: channel %d: alive check", __func__, c->self);
1.1 djm 462:
1.10 djm 463: /* prepare reply */
464: buffer_put_int(r, MUX_S_ALIVE);
465: buffer_put_int(r, rid);
466: buffer_put_int(r, (u_int)getpid());
1.1 djm 467:
1.10 djm 468: return 0;
1.1 djm 469: }
470:
471: static int
1.10 djm 472: process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r)
1.1 djm 473: {
1.10 djm 474: debug2("%s: channel %d: terminate request", __func__, c->self);
1.1 djm 475:
1.10 djm 476: if (options.control_master == SSHCTL_MASTER_ASK ||
477: options.control_master == SSHCTL_MASTER_AUTO_ASK) {
478: if (!ask_permission("Terminate shared connection to %s? ",
479: host)) {
480: debug2("%s: termination refused by user", __func__);
481: buffer_put_int(r, MUX_S_PERMISSION_DENIED);
482: buffer_put_int(r, rid);
483: buffer_put_cstring(r, "Permission denied");
484: return 0;
485: }
486: }
1.1 djm 487:
1.10 djm 488: quit_pending = 1;
489: buffer_put_int(r, MUX_S_OK);
490: buffer_put_int(r, rid);
491: /* XXX exit happens too soon - message never makes it to client */
492: return 0;
1.1 djm 493: }
494:
1.10 djm 495: static char *
496: format_forward(u_int ftype, Forward *fwd)
1.1 djm 497: {
1.10 djm 498: char *ret;
1.1 djm 499:
1.10 djm 500: switch (ftype) {
501: case MUX_FWD_LOCAL:
502: xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",
503: (fwd->listen_host == NULL) ?
504: (options.gateway_ports ? "*" : "LOCALHOST") :
505: fwd->listen_host, fwd->listen_port,
506: fwd->connect_host, fwd->connect_port);
507: break;
508: case MUX_FWD_DYNAMIC:
509: xasprintf(&ret, "dynamic forward %.200s:%d -> *",
510: (fwd->listen_host == NULL) ?
511: (options.gateway_ports ? "*" : "LOCALHOST") :
512: fwd->listen_host, fwd->listen_port);
513: break;
514: case MUX_FWD_REMOTE:
515: xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",
516: (fwd->listen_host == NULL) ?
517: "LOCALHOST" : fwd->listen_host,
518: fwd->listen_port,
519: fwd->connect_host, fwd->connect_port);
1.1 djm 520: break;
521: default:
1.10 djm 522: fatal("%s: unknown forward type %u", __func__, ftype);
1.1 djm 523: }
1.10 djm 524: return ret;
525: }
1.1 djm 526:
1.10 djm 527: static int
528: compare_host(const char *a, const char *b)
529: {
530: if (a == NULL && b == NULL)
531: return 1;
532: if (a == NULL || b == NULL)
533: return 0;
534: return strcmp(a, b) == 0;
535: }
1.1 djm 536:
1.10 djm 537: static int
538: compare_forward(Forward *a, Forward *b)
539: {
540: if (!compare_host(a->listen_host, b->listen_host))
541: return 0;
542: if (a->listen_port != b->listen_port)
543: return 0;
544: if (!compare_host(a->connect_host, b->connect_host))
545: return 0;
546: if (a->connect_port != b->connect_port)
547: return 0;
1.1 djm 548:
1.10 djm 549: return 1;
550: }
1.1 djm 551:
1.18 markus 552: static void
553: mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
554: {
555: struct mux_channel_confirm_ctx *fctx = ctxt;
556: char *failmsg = NULL;
557: Forward *rfwd;
558: Channel *c;
559: Buffer out;
560:
561: if ((c = channel_by_id(fctx->cid)) == NULL) {
562: /* no channel for reply */
563: error("%s: unknown channel", __func__);
564: return;
565: }
566: buffer_init(&out);
567: if (fctx->fid >= options.num_remote_forwards) {
568: xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid);
569: goto fail;
570: }
571: rfwd = &options.remote_forwards[fctx->fid];
572: debug("%s: %s for: listen %d, connect %s:%d", __func__,
573: type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
574: rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
575: if (type == SSH2_MSG_REQUEST_SUCCESS) {
576: if (rfwd->listen_port == 0) {
577: rfwd->allocated_port = packet_get_int();
578: logit("Allocated port %u for mux remote forward"
579: " to %s:%d", rfwd->allocated_port,
580: rfwd->connect_host, rfwd->connect_port);
581: buffer_put_int(&out, MUX_S_REMOTE_PORT);
582: buffer_put_int(&out, fctx->rid);
583: buffer_put_int(&out, rfwd->allocated_port);
584: } else {
585: buffer_put_int(&out, MUX_S_OK);
586: buffer_put_int(&out, fctx->rid);
587: }
588: goto out;
589: } else {
590: xasprintf(&failmsg, "remote port forwarding failed for "
591: "listen port %d", rfwd->listen_port);
592: }
593: fail:
594: error("%s: %s", __func__, failmsg);
595: buffer_put_int(&out, MUX_S_FAILURE);
596: buffer_put_int(&out, fctx->rid);
597: buffer_put_cstring(&out, failmsg);
598: xfree(failmsg);
599: out:
600: buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out));
601: buffer_free(&out);
602: if (c->mux_pause <= 0)
603: fatal("%s: mux_pause %d", __func__, c->mux_pause);
604: c->mux_pause = 0; /* start processing messages again */
605: }
606:
1.10 djm 607: static int
608: process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
609: {
610: Forward fwd;
611: char *fwd_desc = NULL;
612: u_int ftype;
613: int i, ret = 0, freefwd = 1;
614:
615: fwd.listen_host = fwd.connect_host = NULL;
616: if (buffer_get_int_ret(&ftype, m) != 0 ||
617: (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
618: buffer_get_int_ret(&fwd.listen_port, m) != 0 ||
619: (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
620: buffer_get_int_ret(&fwd.connect_port, m) != 0) {
621: error("%s: malformed message", __func__);
622: ret = -1;
623: goto out;
624: }
625:
626: if (*fwd.listen_host == '\0') {
627: xfree(fwd.listen_host);
628: fwd.listen_host = NULL;
629: }
630: if (*fwd.connect_host == '\0') {
631: xfree(fwd.connect_host);
632: fwd.connect_host = NULL;
633: }
634:
635: debug2("%s: channel %d: request %s", __func__, c->self,
636: (fwd_desc = format_forward(ftype, &fwd)));
637:
638: if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE &&
639: ftype != MUX_FWD_DYNAMIC) {
640: logit("%s: invalid forwarding type %u", __func__, ftype);
641: invalid:
1.18 markus 642: if (fwd.listen_host)
643: xfree(fwd.listen_host);
644: if (fwd.connect_host)
645: xfree(fwd.connect_host);
1.10 djm 646: buffer_put_int(r, MUX_S_FAILURE);
647: buffer_put_int(r, rid);
648: buffer_put_cstring(r, "Invalid forwarding request");
649: return 0;
650: }
1.18 markus 651: if (fwd.listen_port >= 65536) {
1.10 djm 652: logit("%s: invalid listen port %u", __func__,
653: fwd.listen_port);
654: goto invalid;
655: }
656: if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC &&
657: ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
658: logit("%s: invalid connect port %u", __func__,
659: fwd.connect_port);
660: goto invalid;
661: }
662: if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) {
663: logit("%s: missing connect host", __func__);
664: goto invalid;
665: }
666:
667: /* Skip forwards that have already been requested */
668: switch (ftype) {
669: case MUX_FWD_LOCAL:
670: case MUX_FWD_DYNAMIC:
671: for (i = 0; i < options.num_local_forwards; i++) {
672: if (compare_forward(&fwd,
673: options.local_forwards + i)) {
674: exists:
675: debug2("%s: found existing forwarding",
676: __func__);
677: buffer_put_int(r, MUX_S_OK);
678: buffer_put_int(r, rid);
679: goto out;
680: }
681: }
682: break;
683: case MUX_FWD_REMOTE:
684: for (i = 0; i < options.num_remote_forwards; i++) {
685: if (compare_forward(&fwd,
1.18 markus 686: options.remote_forwards + i)) {
687: if (fwd.listen_port != 0)
688: goto exists;
689: debug2("%s: found allocated port",
690: __func__);
691: buffer_put_int(r, MUX_S_REMOTE_PORT);
692: buffer_put_int(r, rid);
693: buffer_put_int(r,
694: options.remote_forwards[i].allocated_port);
695: goto out;
696: }
1.10 djm 697: }
698: break;
699: }
700:
701: if (options.control_master == SSHCTL_MASTER_ASK ||
702: options.control_master == SSHCTL_MASTER_AUTO_ASK) {
703: if (!ask_permission("Open %s on %s?", fwd_desc, host)) {
704: debug2("%s: forwarding refused by user", __func__);
705: buffer_put_int(r, MUX_S_PERMISSION_DENIED);
706: buffer_put_int(r, rid);
707: buffer_put_cstring(r, "Permission denied");
708: goto out;
709: }
710: }
711:
712: if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
1.20 djm 713: if (channel_setup_local_fwd_listener(fwd.listen_host,
1.10 djm 714: fwd.listen_port, fwd.connect_host, fwd.connect_port,
715: options.gateway_ports) < 0) {
716: fail:
717: logit("slave-requested %s failed", fwd_desc);
718: buffer_put_int(r, MUX_S_FAILURE);
719: buffer_put_int(r, rid);
720: buffer_put_cstring(r, "Port forwarding failed");
721: goto out;
722: }
723: add_local_forward(&options, &fwd);
724: freefwd = 0;
725: } else {
1.18 markus 726: struct mux_channel_confirm_ctx *fctx;
727:
1.20 djm 728: if (channel_request_remote_forwarding(fwd.listen_host,
1.10 djm 729: fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0)
730: goto fail;
731: add_remote_forward(&options, &fwd);
1.18 markus 732: fctx = xcalloc(1, sizeof(*fctx));
733: fctx->cid = c->self;
734: fctx->rid = rid;
1.20 djm 735: fctx->fid = options.num_remote_forwards - 1;
1.18 markus 736: client_register_global_confirm(mux_confirm_remote_forward,
737: fctx);
1.10 djm 738: freefwd = 0;
1.18 markus 739: c->mux_pause = 1; /* wait for mux_confirm_remote_forward */
740: /* delayed reply in mux_confirm_remote_forward */
741: goto out;
1.10 djm 742: }
743: buffer_put_int(r, MUX_S_OK);
744: buffer_put_int(r, rid);
745: out:
746: if (fwd_desc != NULL)
747: xfree(fwd_desc);
748: if (freefwd) {
749: if (fwd.listen_host != NULL)
750: xfree(fwd.listen_host);
751: if (fwd.connect_host != NULL)
752: xfree(fwd.connect_host);
753: }
754: return ret;
755: }
756:
757: static int
758: process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
759: {
760: Forward fwd;
761: char *fwd_desc = NULL;
762: u_int ftype;
763: int ret = 0;
764:
765: fwd.listen_host = fwd.connect_host = NULL;
766: if (buffer_get_int_ret(&ftype, m) != 0 ||
767: (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||
768: buffer_get_int_ret(&fwd.listen_port, m) != 0 ||
769: (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||
770: buffer_get_int_ret(&fwd.connect_port, m) != 0) {
771: error("%s: malformed message", __func__);
772: ret = -1;
773: goto out;
774: }
775:
776: if (*fwd.listen_host == '\0') {
777: xfree(fwd.listen_host);
778: fwd.listen_host = NULL;
779: }
780: if (*fwd.connect_host == '\0') {
781: xfree(fwd.connect_host);
782: fwd.connect_host = NULL;
783: }
784:
785: debug2("%s: channel %d: request %s", __func__, c->self,
786: (fwd_desc = format_forward(ftype, &fwd)));
787:
788: /* XXX implement this */
789: buffer_put_int(r, MUX_S_FAILURE);
790: buffer_put_int(r, rid);
791: buffer_put_cstring(r, "unimplemented");
792:
793: out:
794: if (fwd_desc != NULL)
795: xfree(fwd_desc);
796: if (fwd.listen_host != NULL)
797: xfree(fwd.listen_host);
798: if (fwd.connect_host != NULL)
799: xfree(fwd.connect_host);
800:
801: return ret;
802: }
803:
804: static int
805: process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
806: {
807: Channel *nc;
808: char *reserved, *chost;
809: u_int cport, i, j;
810: int new_fd[2];
811:
1.11 djm 812: chost = reserved = NULL;
1.10 djm 813: if ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||
814: (chost = buffer_get_string_ret(m, NULL)) == NULL ||
815: buffer_get_int_ret(&cport, m) != 0) {
1.11 djm 816: if (reserved != NULL)
817: xfree(reserved);
1.10 djm 818: if (chost != NULL)
819: xfree(chost);
820: error("%s: malformed message", __func__);
821: return -1;
822: }
823: xfree(reserved);
824:
825: debug2("%s: channel %d: request stdio fwd to %s:%u",
826: __func__, c->self, chost, cport);
827:
828: /* Gather fds from client */
829: for(i = 0; i < 2; i++) {
830: if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
831: error("%s: failed to receive fd %d from slave",
832: __func__, i);
833: for (j = 0; j < i; j++)
834: close(new_fd[j]);
835: xfree(chost);
836:
837: /* prepare reply */
838: buffer_put_int(r, MUX_S_FAILURE);
839: buffer_put_int(r, rid);
840: buffer_put_cstring(r,
841: "did not receive file descriptors");
842: return -1;
843: }
844: }
845:
846: debug3("%s: got fds stdin %d, stdout %d", __func__,
847: new_fd[0], new_fd[1]);
848:
849: /* XXX support multiple child sessions in future */
850: if (c->remote_id != -1) {
851: debug2("%s: session already open", __func__);
852: /* prepare reply */
853: buffer_put_int(r, MUX_S_FAILURE);
854: buffer_put_int(r, rid);
855: buffer_put_cstring(r, "Multiple sessions not supported");
856: cleanup:
857: close(new_fd[0]);
858: close(new_fd[1]);
859: xfree(chost);
860: return 0;
861: }
862:
863: if (options.control_master == SSHCTL_MASTER_ASK ||
864: options.control_master == SSHCTL_MASTER_AUTO_ASK) {
865: if (!ask_permission("Allow forward to to %s:%u? ",
866: chost, cport)) {
867: debug2("%s: stdio fwd refused by user", __func__);
868: /* prepare reply */
869: buffer_put_int(r, MUX_S_PERMISSION_DENIED);
870: buffer_put_int(r, rid);
871: buffer_put_cstring(r, "Permission denied");
872: goto cleanup;
873: }
874: }
875:
876: /* enable nonblocking unless tty */
877: if (!isatty(new_fd[0]))
878: set_nonblock(new_fd[0]);
879: if (!isatty(new_fd[1]))
880: set_nonblock(new_fd[1]);
881:
882: nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]);
883:
884: nc->ctl_chan = c->self; /* link session -> control channel */
885: c->remote_id = nc->self; /* link control -> session channel */
886:
887: debug2("%s: channel_new: %d linked to control channel %d",
888: __func__, nc->self, nc->ctl_chan);
889:
1.16 djm 890: channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);
1.10 djm 891:
892: /* prepare reply */
893: /* XXX defer until channel confirmed */
894: buffer_put_int(r, MUX_S_SESSION_OPENED);
895: buffer_put_int(r, rid);
896: buffer_put_int(r, nc->self);
897:
898: return 0;
899: }
900:
901: /* Channel callbacks fired on read/write from mux slave fd */
902: static int
903: mux_master_read_cb(Channel *c)
904: {
905: struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
906: Buffer in, out;
907: void *ptr;
908: u_int type, rid, have, i;
909: int ret = -1;
910:
911: /* Setup ctx and */
912: if (c->mux_ctx == NULL) {
1.19 djm 913: state = xcalloc(1, sizeof(*state));
1.10 djm 914: c->mux_ctx = state;
915: channel_register_cleanup(c->self,
916: mux_master_control_cleanup_cb, 0);
917:
918: /* Send hello */
919: buffer_init(&out);
920: buffer_put_int(&out, MUX_MSG_HELLO);
921: buffer_put_int(&out, SSHMUX_VER);
922: /* no extensions */
923: buffer_put_string(&c->output, buffer_ptr(&out),
924: buffer_len(&out));
925: buffer_free(&out);
926: debug3("%s: channel %d: hello sent", __func__, c->self);
927: return 0;
928: }
929:
930: buffer_init(&in);
931: buffer_init(&out);
932:
933: /* Channel code ensures that we receive whole packets */
934: if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) {
935: malf:
936: error("%s: malformed message", __func__);
937: goto out;
938: }
939: buffer_append(&in, ptr, have);
940:
941: if (buffer_get_int_ret(&type, &in) != 0)
942: goto malf;
943: debug3("%s: channel %d packet type 0x%08x len %u",
944: __func__, c->self, type, buffer_len(&in));
945:
946: if (type == MUX_MSG_HELLO)
947: rid = 0;
948: else {
949: if (!state->hello_rcvd) {
950: error("%s: expected MUX_MSG_HELLO(0x%08x), "
951: "received 0x%08x", __func__, MUX_MSG_HELLO, type);
952: goto out;
1.1 djm 953: }
1.10 djm 954: if (buffer_get_int_ret(&rid, &in) != 0)
955: goto malf;
956: }
957:
958: for (i = 0; mux_master_handlers[i].handler != NULL; i++) {
959: if (type == mux_master_handlers[i].type) {
960: ret = mux_master_handlers[i].handler(rid, c, &in, &out);
961: break;
1.1 djm 962: }
1.10 djm 963: }
964: if (mux_master_handlers[i].handler == NULL) {
965: error("%s: unsupported mux message 0x%08x", __func__, type);
966: buffer_put_int(&out, MUX_S_FAILURE);
967: buffer_put_int(&out, rid);
968: buffer_put_cstring(&out, "unsupported request");
969: ret = 0;
970: }
971: /* Enqueue reply packet */
972: if (buffer_len(&out) != 0) {
973: buffer_put_string(&c->output, buffer_ptr(&out),
974: buffer_len(&out));
975: }
976: out:
977: buffer_free(&in);
978: buffer_free(&out);
979: return ret;
980: }
981:
982: void
983: mux_exit_message(Channel *c, int exitval)
984: {
985: Buffer m;
986: Channel *mux_chan;
987:
988: debug3("%s: channel %d: exit message, evitval %d", __func__, c->self,
989: exitval);
990:
991: if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)
992: fatal("%s: channel %d missing mux channel %d",
993: __func__, c->self, c->ctl_chan);
994:
995: /* Append exit message packet to control socket output queue */
996: buffer_init(&m);
997: buffer_put_int(&m, MUX_S_EXIT_MESSAGE);
998: buffer_put_int(&m, c->self);
999: buffer_put_int(&m, exitval);
1000:
1001: buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));
1002: buffer_free(&m);
1003: }
1004:
1005: /* Prepare a mux master to listen on a Unix domain socket. */
1006: void
1007: muxserver_listen(void)
1008: {
1009: struct sockaddr_un addr;
1010: mode_t old_umask;
1.22 ! djm 1011: char *orig_control_path = options.control_path;
! 1012: char rbuf[16+1];
! 1013: u_int i, r;
1.10 djm 1014:
1015: if (options.control_path == NULL ||
1016: options.control_master == SSHCTL_MASTER_NO)
1.1 djm 1017: return;
1.10 djm 1018:
1019: debug("setting up multiplex master socket");
1020:
1.22 ! djm 1021: /*
! 1022: * Use a temporary path before listen so we can pseudo-atomically
! 1023: * establish the listening socket in its final location to avoid
! 1024: * other processes racing in between bind() and listen() and hitting
! 1025: * an unready socket.
! 1026: */
! 1027: for (i = 0; i < sizeof(rbuf) - 1; i++) {
! 1028: r = arc4random_uniform(26+26+10);
! 1029: rbuf[i] = (r < 26) ? 'a' + r :
! 1030: (r < 26*2) ? 'A' + r - 26 :
! 1031: '0' + r - 26 - 26;
! 1032: }
! 1033: rbuf[sizeof(rbuf) - 1] = '\0';
! 1034: options.control_path = NULL;
! 1035: xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
! 1036: debug3("%s: temporary control path %s", __func__, options.control_path);
! 1037:
1.10 djm 1038: memset(&addr, '\0', sizeof(addr));
1039: addr.sun_family = AF_UNIX;
1040: addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
1041: strlen(options.control_path) + 1;
1042:
1043: if (strlcpy(addr.sun_path, options.control_path,
1044: sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
1045: fatal("ControlPath too long");
1046:
1047: if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1048: fatal("%s socket(): %s", __func__, strerror(errno));
1049:
1050: old_umask = umask(0177);
1051: if (bind(muxserver_sock, (struct sockaddr *)&addr, addr.sun_len) == -1) {
1052: muxserver_sock = -1;
1053: if (errno == EINVAL || errno == EADDRINUSE) {
1054: error("ControlSocket %s already exists, "
1055: "disabling multiplexing", options.control_path);
1.22 ! djm 1056: disable_mux_master:
1.10 djm 1057: close(muxserver_sock);
1058: muxserver_sock = -1;
1059: xfree(options.control_path);
1060: options.control_path = NULL;
1061: options.control_master = SSHCTL_MASTER_NO;
1062: return;
1063: } else
1064: fatal("%s bind(): %s", __func__, strerror(errno));
1065: }
1066: umask(old_umask);
1067:
1068: if (listen(muxserver_sock, 64) == -1)
1069: fatal("%s listen(): %s", __func__, strerror(errno));
1070:
1.22 ! djm 1071: /* Now atomically "move" the mux socket into position */
! 1072: if (link(options.control_path, orig_control_path) != 0) {
! 1073: if (errno != EEXIST) {
! 1074: fatal("%s: link mux listener %s => %s: %s", __func__,
! 1075: options.control_path, orig_control_path,
! 1076: strerror(errno));
! 1077: }
! 1078: error("ControlSocket %s already exists, disabling multiplexing",
! 1079: orig_control_path);
! 1080: xfree(orig_control_path);
! 1081: unlink(options.control_path);
! 1082: goto disable_mux_master;
! 1083: }
! 1084: unlink(options.control_path);
! 1085: xfree(options.control_path);
! 1086: options.control_path = orig_control_path;
! 1087:
1.10 djm 1088: set_nonblock(muxserver_sock);
1089:
1090: mux_listener_channel = channel_new("mux listener",
1091: SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
1092: CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1.22 ! djm 1093: 0, options.control_path, 1);
1.10 djm 1094: mux_listener_channel->mux_rcb = mux_master_read_cb;
1095: debug3("%s: mux listener channel %d fd %d", __func__,
1096: mux_listener_channel->self, mux_listener_channel->sock);
1097: }
1098:
1099: /* Callback on open confirmation in mux master for a mux client session. */
1100: static void
1.17 djm 1101: mux_session_confirm(int id, int success, void *arg)
1.10 djm 1102: {
1103: struct mux_session_confirm_ctx *cctx = arg;
1104: const char *display;
1.17 djm 1105: Channel *c, *cc;
1.10 djm 1106: int i;
1.17 djm 1107: Buffer reply;
1.10 djm 1108:
1109: if (cctx == NULL)
1110: fatal("%s: cctx == NULL", __func__);
1111: if ((c = channel_by_id(id)) == NULL)
1112: fatal("%s: no channel for id %d", __func__, id);
1.17 djm 1113: if ((cc = channel_by_id(c->ctl_chan)) == NULL)
1114: fatal("%s: channel %d lacks control channel %d", __func__,
1115: id, c->ctl_chan);
1116:
1117: if (!success) {
1118: debug3("%s: sending failure reply", __func__);
1119: /* prepare reply */
1120: buffer_init(&reply);
1121: buffer_put_int(&reply, MUX_S_FAILURE);
1122: buffer_put_int(&reply, cctx->rid);
1123: buffer_put_cstring(&reply, "Session open refused by peer");
1124: goto done;
1125: }
1.10 djm 1126:
1127: display = getenv("DISPLAY");
1128: if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
1129: char *proto, *data;
1.21 djm 1130:
1.10 djm 1131: /* Get reasonable local authentication information. */
1132: client_x11_get_proto(display, options.xauth_location,
1.21 djm 1133: options.forward_x11_trusted, options.forward_x11_timeout,
1134: &proto, &data);
1.10 djm 1135: /* Request forwarding with authentication spoofing. */
1.21 djm 1136: debug("Requesting X11 forwarding with authentication "
1137: "spoofing.");
1.10 djm 1138: x11_request_forwarding_with_spoofing(id, display, proto, data);
1139: /* XXX wait for reply */
1140: }
1141:
1142: if (cctx->want_agent_fwd && options.forward_agent) {
1143: debug("Requesting authentication agent forwarding.");
1144: channel_request_start(id, "auth-agent-req@openssh.com", 0);
1145: packet_send();
1146: }
1147:
1148: client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
1149: cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);
1150:
1.17 djm 1151: debug3("%s: sending success reply", __func__);
1152: /* prepare reply */
1153: buffer_init(&reply);
1154: buffer_put_int(&reply, MUX_S_SESSION_OPENED);
1155: buffer_put_int(&reply, cctx->rid);
1156: buffer_put_int(&reply, c->self);
1157:
1158: done:
1159: /* Send reply */
1160: buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply));
1161: buffer_free(&reply);
1162:
1163: if (cc->mux_pause <= 0)
1164: fatal("%s: mux_pause %d", __func__, cc->mux_pause);
1165: cc->mux_pause = 0; /* start processing messages again */
1.10 djm 1166: c->open_confirm_ctx = NULL;
1167: buffer_free(&cctx->cmd);
1168: xfree(cctx->term);
1169: if (cctx->env != NULL) {
1170: for (i = 0; cctx->env[i] != NULL; i++)
1171: xfree(cctx->env[i]);
1172: xfree(cctx->env);
1.1 djm 1173: }
1.10 djm 1174: xfree(cctx);
1175: }
1176:
1177: /* ** Multiplexing client support */
1178:
1179: /* Exit signal handler */
1180: static void
1181: control_client_sighandler(int signo)
1182: {
1183: muxclient_terminate = signo;
1184: }
1185:
1186: /*
1187: * Relay signal handler - used to pass some signals from mux client to
1188: * mux master.
1189: */
1190: static void
1191: control_client_sigrelay(int signo)
1192: {
1193: int save_errno = errno;
1194:
1195: if (muxserver_pid > 1)
1196: kill(muxserver_pid, signo);
1197:
1198: errno = save_errno;
1199: }
1.1 djm 1200:
1.10 djm 1201: static int
1202: mux_client_read(int fd, Buffer *b, u_int need)
1203: {
1204: u_int have;
1205: ssize_t len;
1206: u_char *p;
1207: struct pollfd pfd;
1208:
1209: pfd.fd = fd;
1210: pfd.events = POLLIN;
1211: p = buffer_append_space(b, need);
1212: for (have = 0; have < need; ) {
1213: if (muxclient_terminate) {
1214: errno = EINTR;
1215: return -1;
1216: }
1217: len = read(fd, p + have, need - have);
1218: if (len < 0) {
1219: switch (errno) {
1220: case EAGAIN:
1221: (void)poll(&pfd, 1, -1);
1222: /* FALLTHROUGH */
1223: case EINTR:
1224: continue;
1225: default:
1226: return -1;
1227: }
1228: }
1229: if (len == 0) {
1230: errno = EPIPE;
1231: return -1;
1232: }
1233: have += (u_int)len;
1.1 djm 1234: }
1.10 djm 1235: return 0;
1236: }
1.1 djm 1237:
1.10 djm 1238: static int
1239: mux_client_write_packet(int fd, Buffer *m)
1240: {
1241: Buffer queue;
1242: u_int have, need;
1243: int oerrno, len;
1244: u_char *ptr;
1245: struct pollfd pfd;
1246:
1247: pfd.fd = fd;
1248: pfd.events = POLLOUT;
1249: buffer_init(&queue);
1250: buffer_put_string(&queue, buffer_ptr(m), buffer_len(m));
1251:
1252: need = buffer_len(&queue);
1253: ptr = buffer_ptr(&queue);
1254:
1255: for (have = 0; have < need; ) {
1256: if (muxclient_terminate) {
1257: buffer_free(&queue);
1258: errno = EINTR;
1259: return -1;
1260: }
1261: len = write(fd, ptr + have, need - have);
1262: if (len < 0) {
1263: switch (errno) {
1264: case EAGAIN:
1265: (void)poll(&pfd, 1, -1);
1266: /* FALLTHROUGH */
1267: case EINTR:
1268: continue;
1269: default:
1270: oerrno = errno;
1271: buffer_free(&queue);
1272: errno = oerrno;
1273: return -1;
1274: }
1275: }
1276: if (len == 0) {
1277: buffer_free(&queue);
1278: errno = EPIPE;
1279: return -1;
1280: }
1281: have += (u_int)len;
1282: }
1283: buffer_free(&queue);
1284: return 0;
1285: }
1.1 djm 1286:
1.10 djm 1287: static int
1288: mux_client_read_packet(int fd, Buffer *m)
1289: {
1290: Buffer queue;
1291: u_int need, have;
1292: void *ptr;
1293: int oerrno;
1294:
1295: buffer_init(&queue);
1296: if (mux_client_read(fd, &queue, 4) != 0) {
1297: if ((oerrno = errno) == EPIPE)
1298: debug3("%s: read header failed: %s", __func__, strerror(errno));
1299: errno = oerrno;
1300: return -1;
1301: }
1302: need = get_u32(buffer_ptr(&queue));
1303: if (mux_client_read(fd, &queue, need) != 0) {
1304: oerrno = errno;
1305: debug3("%s: read body failed: %s", __func__, strerror(errno));
1306: errno = oerrno;
1307: return -1;
1308: }
1309: ptr = buffer_get_string_ptr(&queue, &have);
1310: buffer_append(m, ptr, have);
1311: buffer_free(&queue);
1312: return 0;
1313: }
1.1 djm 1314:
1.10 djm 1315: static int
1316: mux_client_hello_exchange(int fd)
1317: {
1318: Buffer m;
1319: u_int type, ver;
1.1 djm 1320:
1321: buffer_init(&m);
1.10 djm 1322: buffer_put_int(&m, MUX_MSG_HELLO);
1323: buffer_put_int(&m, SSHMUX_VER);
1324: /* no extensions */
1325:
1326: if (mux_client_write_packet(fd, &m) != 0)
1327: fatal("%s: write packet: %s", __func__, strerror(errno));
1.1 djm 1328:
1.10 djm 1329: buffer_clear(&m);
1330:
1331: /* Read their HELLO */
1332: if (mux_client_read_packet(fd, &m) != 0) {
1.5 djm 1333: buffer_free(&m);
1.10 djm 1334: return -1;
1335: }
1336:
1337: type = buffer_get_int(&m);
1338: if (type != MUX_MSG_HELLO)
1339: fatal("%s: expected HELLO (%u) received %u",
1340: __func__, MUX_MSG_HELLO, type);
1341: ver = buffer_get_int(&m);
1342: if (ver != SSHMUX_VER)
1343: fatal("Unsupported multiplexing protocol version %d "
1344: "(expected %d)", ver, SSHMUX_VER);
1345: debug2("%s: master version %u", __func__, ver);
1346: /* No extensions are presently defined */
1347: while (buffer_len(&m) > 0) {
1348: char *name = buffer_get_string(&m, NULL);
1349: char *value = buffer_get_string(&m, NULL);
1350:
1351: debug2("Unrecognised master extension \"%s\"", name);
1352: xfree(name);
1353: xfree(value);
1.5 djm 1354: }
1.10 djm 1355: buffer_free(&m);
1356: return 0;
1357: }
1358:
1359: static u_int
1360: mux_client_request_alive(int fd)
1361: {
1362: Buffer m;
1363: char *e;
1364: u_int pid, type, rid;
1365:
1366: debug3("%s: entering", __func__);
1367:
1368: buffer_init(&m);
1369: buffer_put_int(&m, MUX_C_ALIVE_CHECK);
1370: buffer_put_int(&m, muxclient_request_id);
1371:
1372: if (mux_client_write_packet(fd, &m) != 0)
1373: fatal("%s: write packet: %s", __func__, strerror(errno));
1374:
1.1 djm 1375: buffer_clear(&m);
1376:
1.10 djm 1377: /* Read their reply */
1378: if (mux_client_read_packet(fd, &m) != 0) {
1379: buffer_free(&m);
1380: return 0;
1381: }
1382:
1383: type = buffer_get_int(&m);
1384: if (type != MUX_S_ALIVE) {
1385: e = buffer_get_string(&m, NULL);
1386: fatal("%s: master returned error: %s", __func__, e);
1.5 djm 1387: }
1.10 djm 1388:
1389: if ((rid = buffer_get_int(&m)) != muxclient_request_id)
1390: fatal("%s: out of sequence reply: my id %u theirs %u",
1391: __func__, muxclient_request_id, rid);
1392: pid = buffer_get_int(&m);
1393: buffer_free(&m);
1394:
1395: debug3("%s: done pid = %u", __func__, pid);
1396:
1397: muxclient_request_id++;
1398:
1399: return pid;
1400: }
1401:
1402: static void
1403: mux_client_request_terminate(int fd)
1404: {
1405: Buffer m;
1406: char *e;
1407: u_int type, rid;
1408:
1409: debug3("%s: entering", __func__);
1410:
1411: buffer_init(&m);
1412: buffer_put_int(&m, MUX_C_TERMINATE);
1413: buffer_put_int(&m, muxclient_request_id);
1414:
1415: if (mux_client_write_packet(fd, &m) != 0)
1416: fatal("%s: write packet: %s", __func__, strerror(errno));
1.1 djm 1417:
1418: buffer_clear(&m);
1419:
1.10 djm 1420: /* Read their reply */
1421: if (mux_client_read_packet(fd, &m) != 0) {
1422: /* Remote end exited already */
1423: if (errno == EPIPE) {
1424: buffer_free(&m);
1425: return;
1.2 djm 1426: }
1.10 djm 1427: fatal("%s: read from master failed: %s",
1428: __func__, strerror(errno));
1429: }
1430:
1431: type = buffer_get_int(&m);
1432: if ((rid = buffer_get_int(&m)) != muxclient_request_id)
1433: fatal("%s: out of sequence reply: my id %u theirs %u",
1434: __func__, muxclient_request_id, rid);
1435: switch (type) {
1436: case MUX_S_OK:
1437: break;
1438: case MUX_S_PERMISSION_DENIED:
1439: e = buffer_get_string(&m, NULL);
1440: fatal("Master refused termination request: %s", e);
1441: case MUX_S_FAILURE:
1442: e = buffer_get_string(&m, NULL);
1443: fatal("%s: termination request failed: %s", __func__, e);
1444: default:
1445: fatal("%s: unexpected response from master 0x%08x",
1446: __func__, type);
1447: }
1448: buffer_free(&m);
1449: muxclient_request_id++;
1450: }
1451:
1452: static int
1453: mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
1454: {
1455: Buffer m;
1456: char *e, *fwd_desc;
1457: u_int type, rid;
1458:
1459: fwd_desc = format_forward(ftype, fwd);
1460: debug("Requesting %s", fwd_desc);
1461: xfree(fwd_desc);
1462:
1463: buffer_init(&m);
1464: buffer_put_int(&m, MUX_C_OPEN_FWD);
1465: buffer_put_int(&m, muxclient_request_id);
1466: buffer_put_int(&m, ftype);
1467: buffer_put_cstring(&m,
1468: fwd->listen_host == NULL ? "" : fwd->listen_host);
1469: buffer_put_int(&m, fwd->listen_port);
1470: buffer_put_cstring(&m,
1471: fwd->connect_host == NULL ? "" : fwd->connect_host);
1472: buffer_put_int(&m, fwd->connect_port);
1473:
1474: if (mux_client_write_packet(fd, &m) != 0)
1475: fatal("%s: write packet: %s", __func__, strerror(errno));
1476:
1477: buffer_clear(&m);
1478:
1479: /* Read their reply */
1480: if (mux_client_read_packet(fd, &m) != 0) {
1481: buffer_free(&m);
1482: return -1;
1483: }
1484:
1485: type = buffer_get_int(&m);
1486: if ((rid = buffer_get_int(&m)) != muxclient_request_id)
1487: fatal("%s: out of sequence reply: my id %u theirs %u",
1488: __func__, muxclient_request_id, rid);
1489: switch (type) {
1490: case MUX_S_OK:
1.1 djm 1491: break;
1.18 markus 1492: case MUX_S_REMOTE_PORT:
1493: fwd->allocated_port = buffer_get_int(&m);
1494: logit("Allocated port %u for remote forward to %s:%d",
1495: fwd->allocated_port,
1496: fwd->connect_host ? fwd->connect_host : "",
1497: fwd->connect_port);
1498: if (muxclient_command == SSHMUX_COMMAND_FORWARD)
1499: fprintf(stdout, "%u\n", fwd->allocated_port);
1500: break;
1.10 djm 1501: case MUX_S_PERMISSION_DENIED:
1502: e = buffer_get_string(&m, NULL);
1503: buffer_free(&m);
1504: error("Master refused forwarding request: %s", e);
1505: return -1;
1506: case MUX_S_FAILURE:
1507: e = buffer_get_string(&m, NULL);
1508: buffer_free(&m);
1509: error("%s: session request failed: %s", __func__, e);
1510: return -1;
1.1 djm 1511: default:
1.10 djm 1512: fatal("%s: unexpected response from master 0x%08x",
1513: __func__, type);
1514: }
1515: buffer_free(&m);
1516:
1517: muxclient_request_id++;
1518: return 0;
1519: }
1520:
1521: static int
1522: mux_client_request_forwards(int fd)
1523: {
1524: int i;
1525:
1526: debug3("%s: requesting forwardings: %d local, %d remote", __func__,
1527: options.num_local_forwards, options.num_remote_forwards);
1528:
1529: /* XXX ExitOnForwardingFailure */
1530: for (i = 0; i < options.num_local_forwards; i++) {
1531: if (mux_client_request_forward(fd,
1532: options.local_forwards[i].connect_port == 0 ?
1533: MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
1534: options.local_forwards + i) != 0)
1535: return -1;
1536: }
1537: for (i = 0; i < options.num_remote_forwards; i++) {
1538: if (mux_client_request_forward(fd, MUX_FWD_REMOTE,
1539: options.remote_forwards + i) != 0)
1540: return -1;
1541: }
1542: return 0;
1543: }
1544:
1545: static int
1546: mux_client_request_session(int fd)
1547: {
1548: Buffer m;
1549: char *e, *term;
1550: u_int i, rid, sid, esid, exitval, type, exitval_seen;
1551: extern char **environ;
1552: int devnull;
1553:
1554: debug3("%s: entering", __func__);
1555:
1556: if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
1557: error("%s: master alive request failed", __func__);
1558: return -1;
1.1 djm 1559: }
1560:
1.10 djm 1561: signal(SIGPIPE, SIG_IGN);
1562:
1563: if (stdin_null_flag) {
1564: if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)
1565: fatal("open(/dev/null): %s", strerror(errno));
1566: if (dup2(devnull, STDIN_FILENO) == -1)
1567: fatal("dup2: %s", strerror(errno));
1568: if (devnull > STDERR_FILENO)
1569: close(devnull);
1.5 djm 1570: }
1.1 djm 1571:
1.10 djm 1572: term = getenv("TERM");
1573:
1574: buffer_init(&m);
1575: buffer_put_int(&m, MUX_C_NEW_SESSION);
1576: buffer_put_int(&m, muxclient_request_id);
1577: buffer_put_cstring(&m, ""); /* reserved */
1578: buffer_put_int(&m, tty_flag);
1579: buffer_put_int(&m, options.forward_x11);
1580: buffer_put_int(&m, options.forward_agent);
1581: buffer_put_int(&m, subsystem_flag);
1582: buffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ?
1583: 0xffffffff : (u_int)options.escape_char);
1584: buffer_put_cstring(&m, term == NULL ? "" : term);
1585: buffer_put_string(&m, buffer_ptr(&command), buffer_len(&command));
1586:
1587: if (options.num_send_env > 0 && environ != NULL) {
1588: /* Pass environment */
1589: for (i = 0; environ[i] != NULL; i++) {
1590: if (env_permitted(environ[i])) {
1591: buffer_put_cstring(&m, environ[i]);
1592: }
1593: }
1.5 djm 1594: }
1595:
1.10 djm 1596: if (mux_client_write_packet(fd, &m) != 0)
1597: fatal("%s: write packet: %s", __func__, strerror(errno));
1598:
1599: /* Send the stdio file descriptors */
1600: if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
1601: mm_send_fd(fd, STDOUT_FILENO) == -1 ||
1602: mm_send_fd(fd, STDERR_FILENO) == -1)
1603: fatal("%s: send fds failed", __func__);
1604:
1605: debug3("%s: session request sent", __func__);
1.1 djm 1606:
1.10 djm 1607: /* Read their reply */
1.1 djm 1608: buffer_clear(&m);
1.10 djm 1609: if (mux_client_read_packet(fd, &m) != 0) {
1610: error("%s: read from master failed: %s",
1611: __func__, strerror(errno));
1612: buffer_free(&m);
1613: return -1;
1614: }
1615:
1616: type = buffer_get_int(&m);
1617: if ((rid = buffer_get_int(&m)) != muxclient_request_id)
1618: fatal("%s: out of sequence reply: my id %u theirs %u",
1619: __func__, muxclient_request_id, rid);
1620: switch (type) {
1621: case MUX_S_SESSION_OPENED:
1622: sid = buffer_get_int(&m);
1623: debug("%s: master session id: %u", __func__, sid);
1624: break;
1625: case MUX_S_PERMISSION_DENIED:
1626: e = buffer_get_string(&m, NULL);
1627: buffer_free(&m);
1628: error("Master refused forwarding request: %s", e);
1629: return -1;
1630: case MUX_S_FAILURE:
1631: e = buffer_get_string(&m, NULL);
1632: buffer_free(&m);
1633: error("%s: forwarding request failed: %s", __func__, e);
1634: return -1;
1635: default:
1636: buffer_free(&m);
1637: error("%s: unexpected response from master 0x%08x",
1638: __func__, type);
1639: return -1;
1640: }
1641: muxclient_request_id++;
1.1 djm 1642:
1643: signal(SIGHUP, control_client_sighandler);
1644: signal(SIGINT, control_client_sighandler);
1645: signal(SIGTERM, control_client_sighandler);
1646: signal(SIGWINCH, control_client_sigrelay);
1647:
1648: if (tty_flag)
1.9 djm 1649: enter_raw_mode(force_tty_flag);
1.1 djm 1650:
1651: /*
1652: * Stick around until the controlee closes the client_fd.
1.10 djm 1653: * Before it does, it is expected to write an exit message.
1654: * This process must read the value and wait for the closure of
1655: * the client_fd; if this one closes early, the multiplex master will
1656: * terminate early too (possibly losing data).
1.1 djm 1657: */
1.10 djm 1658: for (exitval = 255, exitval_seen = 0;;) {
1659: buffer_clear(&m);
1660: if (mux_client_read_packet(fd, &m) != 0)
1.1 djm 1661: break;
1.10 djm 1662: type = buffer_get_int(&m);
1663: if (type != MUX_S_EXIT_MESSAGE) {
1664: e = buffer_get_string(&m, NULL);
1665: fatal("%s: master returned error: %s", __func__, e);
1.1 djm 1666: }
1.10 djm 1667: if ((esid = buffer_get_int(&m)) != sid)
1668: fatal("%s: exit on unknown session: my id %u theirs %u",
1669: __func__, sid, esid);
1670: debug("%s: master session id: %u", __func__, sid);
1671: if (exitval_seen)
1672: fatal("%s: exitval sent twice", __func__);
1673: exitval = buffer_get_int(&m);
1674: exitval_seen = 1;
1.1 djm 1675: }
1676:
1.10 djm 1677: close(fd);
1.9 djm 1678: leave_raw_mode(force_tty_flag);
1.10 djm 1679:
1.1 djm 1680: if (muxclient_terminate) {
1681: debug2("Exiting on signal %d", muxclient_terminate);
1.10 djm 1682: exitval = 255;
1683: } else if (!exitval_seen) {
1.1 djm 1684: debug2("Control master terminated unexpectedly");
1.10 djm 1685: exitval = 255;
1.1 djm 1686: } else
1.10 djm 1687: debug2("Received exit status from master %d", exitval);
1.1 djm 1688:
1689: if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
1690: fprintf(stderr, "Shared connection to %s closed.\r\n", host);
1691:
1.10 djm 1692: exit(exitval);
1693: }
1694:
1695: static int
1696: mux_client_request_stdio_fwd(int fd)
1697: {
1698: Buffer m;
1699: char *e;
1700: u_int type, rid, sid;
1701: int devnull;
1702:
1703: debug3("%s: entering", __func__);
1704:
1705: if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
1706: error("%s: master alive request failed", __func__);
1707: return -1;
1708: }
1709:
1710: signal(SIGPIPE, SIG_IGN);
1711:
1712: if (stdin_null_flag) {
1713: if ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)
1714: fatal("open(/dev/null): %s", strerror(errno));
1715: if (dup2(devnull, STDIN_FILENO) == -1)
1716: fatal("dup2: %s", strerror(errno));
1717: if (devnull > STDERR_FILENO)
1718: close(devnull);
1719: }
1720:
1721: buffer_init(&m);
1722: buffer_put_int(&m, MUX_C_NEW_STDIO_FWD);
1723: buffer_put_int(&m, muxclient_request_id);
1724: buffer_put_cstring(&m, ""); /* reserved */
1725: buffer_put_cstring(&m, stdio_forward_host);
1726: buffer_put_int(&m, stdio_forward_port);
1727:
1728: if (mux_client_write_packet(fd, &m) != 0)
1729: fatal("%s: write packet: %s", __func__, strerror(errno));
1730:
1731: /* Send the stdio file descriptors */
1732: if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
1733: mm_send_fd(fd, STDOUT_FILENO) == -1)
1734: fatal("%s: send fds failed", __func__);
1735:
1736: debug3("%s: stdio forward request sent", __func__);
1737:
1738: /* Read their reply */
1739: buffer_clear(&m);
1740:
1741: if (mux_client_read_packet(fd, &m) != 0) {
1742: error("%s: read from master failed: %s",
1743: __func__, strerror(errno));
1744: buffer_free(&m);
1745: return -1;
1746: }
1747:
1748: type = buffer_get_int(&m);
1749: if ((rid = buffer_get_int(&m)) != muxclient_request_id)
1750: fatal("%s: out of sequence reply: my id %u theirs %u",
1751: __func__, muxclient_request_id, rid);
1752: switch (type) {
1753: case MUX_S_SESSION_OPENED:
1754: sid = buffer_get_int(&m);
1755: debug("%s: master session id: %u", __func__, sid);
1756: break;
1757: case MUX_S_PERMISSION_DENIED:
1758: e = buffer_get_string(&m, NULL);
1759: buffer_free(&m);
1760: fatal("Master refused forwarding request: %s", e);
1761: case MUX_S_FAILURE:
1762: e = buffer_get_string(&m, NULL);
1763: buffer_free(&m);
1764: fatal("%s: stdio forwarding request failed: %s", __func__, e);
1765: default:
1766: buffer_free(&m);
1767: error("%s: unexpected response from master 0x%08x",
1768: __func__, type);
1769: return -1;
1770: }
1771: muxclient_request_id++;
1772:
1773: signal(SIGHUP, control_client_sighandler);
1774: signal(SIGINT, control_client_sighandler);
1775: signal(SIGTERM, control_client_sighandler);
1776: signal(SIGWINCH, control_client_sigrelay);
1777:
1778: /*
1779: * Stick around until the controlee closes the client_fd.
1780: */
1781: buffer_clear(&m);
1782: if (mux_client_read_packet(fd, &m) != 0) {
1783: if (errno == EPIPE ||
1784: (errno == EINTR && muxclient_terminate != 0))
1785: return 0;
1786: fatal("%s: mux_client_read_packet: %s",
1787: __func__, strerror(errno));
1788: }
1789: fatal("%s: master returned unexpected message %u", __func__, type);
1790: }
1791:
1792: /* Multiplex client main loop. */
1793: void
1794: muxclient(const char *path)
1795: {
1796: struct sockaddr_un addr;
1797: int sock;
1798: u_int pid;
1799:
1800: if (muxclient_command == 0) {
1801: if (stdio_forward_host != NULL)
1802: muxclient_command = SSHMUX_COMMAND_STDIO_FWD;
1803: else
1804: muxclient_command = SSHMUX_COMMAND_OPEN;
1805: }
1806:
1807: switch (options.control_master) {
1808: case SSHCTL_MASTER_AUTO:
1809: case SSHCTL_MASTER_AUTO_ASK:
1810: debug("auto-mux: Trying existing master");
1811: /* FALLTHROUGH */
1812: case SSHCTL_MASTER_NO:
1813: break;
1814: default:
1815: return;
1816: }
1817:
1818: memset(&addr, '\0', sizeof(addr));
1819: addr.sun_family = AF_UNIX;
1820: addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
1821: strlen(path) + 1;
1822:
1823: if (strlcpy(addr.sun_path, path,
1824: sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
1825: fatal("ControlPath too long");
1826:
1827: if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1828: fatal("%s socket(): %s", __func__, strerror(errno));
1829:
1830: if (connect(sock, (struct sockaddr *)&addr, addr.sun_len) == -1) {
1831: switch (muxclient_command) {
1832: case SSHMUX_COMMAND_OPEN:
1833: case SSHMUX_COMMAND_STDIO_FWD:
1834: break;
1835: default:
1836: fatal("Control socket connect(%.100s): %s", path,
1837: strerror(errno));
1838: }
1.22 ! djm 1839: if (errno == ECONNREFUSED &&
! 1840: options.control_master != SSHCTL_MASTER_NO) {
! 1841: debug("Stale control socket %.100s, unlinking", path);
! 1842: unlink(path);
! 1843: } else if (errno == ENOENT) {
1.10 djm 1844: debug("Control socket \"%.100s\" does not exist", path);
1.22 ! djm 1845: } else {
1.10 djm 1846: error("Control socket connect(%.100s): %s", path,
1847: strerror(errno));
1848: }
1849: close(sock);
1850: return;
1851: }
1852: set_nonblock(sock);
1853:
1854: if (mux_client_hello_exchange(sock) != 0) {
1855: error("%s: master hello exchange failed", __func__);
1856: close(sock);
1857: return;
1858: }
1859:
1860: switch (muxclient_command) {
1861: case SSHMUX_COMMAND_ALIVE_CHECK:
1862: if ((pid = mux_client_request_alive(sock)) == 0)
1863: fatal("%s: master alive check failed", __func__);
1864: fprintf(stderr, "Master running (pid=%d)\r\n", pid);
1865: exit(0);
1866: case SSHMUX_COMMAND_TERMINATE:
1867: mux_client_request_terminate(sock);
1868: fprintf(stderr, "Exit request sent.\r\n");
1.18 markus 1869: exit(0);
1870: case SSHMUX_COMMAND_FORWARD:
1871: if (mux_client_request_forwards(sock) != 0)
1872: fatal("%s: master forward request failed", __func__);
1.10 djm 1873: exit(0);
1874: case SSHMUX_COMMAND_OPEN:
1875: if (mux_client_request_forwards(sock) != 0) {
1876: error("%s: master forward request failed", __func__);
1877: return;
1878: }
1879: mux_client_request_session(sock);
1880: return;
1881: case SSHMUX_COMMAND_STDIO_FWD:
1882: mux_client_request_stdio_fwd(sock);
1883: exit(0);
1884: default:
1885: fatal("unrecognised muxclient_command %d", muxclient_command);
1886: }
1.1 djm 1887: }