Bug Summary

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