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