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