OpenCoverage

mux.c

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

Generated by Squish Coco 4.2.2