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