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