Bug Summary

File:src/usr.bin/ssh/ssh/../mux.c
Warning:line 848, column 7
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'

Annotated Source Code

Press '?' to see keyboard shortcuts

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