xref: /openbsd-src/usr.bin/ssh/mux.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /* $OpenBSD: mux.c,v 1.7 2008/06/13 17:21:20 dtucker Exp $ */
2 /*
3  * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /* ssh session multiplexing support */
19 
20 /*
21  * TODO:
22  *   1. partial reads in muxserver_accept_control (maybe make channels
23  *      from accepted connections)
24  *   2. Better signalling from master to slave, especially passing of
25  *      error messages
26  *   3. Better fall-back from mux slave error to new connection.
27  *   3. Add/delete forwardings via slave
28  *   4. ExitOnForwardingFailure (after #3 obviously)
29  *   5. Maybe extension mechanisms for multi-X11/multi-agent forwarding
30  *   6. Document the mux mini-protocol somewhere.
31  *   7. Support ~^Z in mux slaves.
32  *   8. Inspect or control sessions in master.
33  *   9. If we ever support the "signal" channel request, send signals on
34  *      sessions in master.
35  */
36 
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/queue.h>
40 #include <sys/stat.h>
41 #include <sys/socket.h>
42 #include <sys/un.h>
43 
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <signal.h>
47 #include <stdarg.h>
48 #include <stddef.h>
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <unistd.h>
53 #include <util.h>
54 #include <paths.h>
55 
56 #include "xmalloc.h"
57 #include "log.h"
58 #include "ssh.h"
59 #include "pathnames.h"
60 #include "misc.h"
61 #include "match.h"
62 #include "buffer.h"
63 #include "channels.h"
64 #include "msg.h"
65 #include "packet.h"
66 #include "monitor_fdpass.h"
67 #include "sshpty.h"
68 #include "key.h"
69 #include "readconf.h"
70 #include "clientloop.h"
71 
72 /* from ssh.c */
73 extern int tty_flag;
74 extern Options options;
75 extern int stdin_null_flag;
76 extern char *host;
77 int subsystem_flag;
78 extern Buffer command;
79 
80 /* Context for session open confirmation callback */
81 struct mux_session_confirm_ctx {
82 	int want_tty;
83 	int want_subsys;
84 	int want_x_fwd;
85 	int want_agent_fwd;
86 	Buffer cmd;
87 	char *term;
88 	struct termios tio;
89 	char **env;
90 };
91 
92 /* fd to control socket */
93 int muxserver_sock = -1;
94 
95 /* Multiplexing control command */
96 u_int muxclient_command = 0;
97 
98 /* Set when signalled. */
99 static volatile sig_atomic_t muxclient_terminate = 0;
100 
101 /* PID of multiplex server */
102 static u_int muxserver_pid = 0;
103 
104 
105 /* ** Multiplexing master support */
106 
107 /* Prepare a mux master to listen on a Unix domain socket. */
108 void
109 muxserver_listen(void)
110 {
111 	struct sockaddr_un addr;
112 	mode_t old_umask;
113 
114 	if (options.control_path == NULL ||
115 	    options.control_master == SSHCTL_MASTER_NO)
116 		return;
117 
118 	debug("setting up multiplex master socket");
119 
120 	memset(&addr, '\0', sizeof(addr));
121 	addr.sun_family = AF_UNIX;
122 	addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
123 	    strlen(options.control_path) + 1;
124 
125 	if (strlcpy(addr.sun_path, options.control_path,
126 	    sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
127 		fatal("ControlPath too long");
128 
129 	if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
130 		fatal("%s socket(): %s", __func__, strerror(errno));
131 
132 	old_umask = umask(0177);
133 	if (bind(muxserver_sock, (struct sockaddr *)&addr, addr.sun_len) == -1) {
134 		muxserver_sock = -1;
135 		if (errno == EINVAL || errno == EADDRINUSE) {
136 			error("ControlSocket %s already exists, "
137 			    "disabling multiplexing", options.control_path);
138 			close(muxserver_sock);
139 			muxserver_sock = -1;
140 			xfree(options.control_path);
141 			options.control_path = NULL;
142 			options.control_master = SSHCTL_MASTER_NO;
143 			return;
144 		} else
145 			fatal("%s bind(): %s", __func__, strerror(errno));
146 	}
147 	umask(old_umask);
148 
149 	if (listen(muxserver_sock, 64) == -1)
150 		fatal("%s listen(): %s", __func__, strerror(errno));
151 
152 	set_nonblock(muxserver_sock);
153 }
154 
155 /* Callback on open confirmation in mux master for a mux client session. */
156 static void
157 mux_session_confirm(int id, void *arg)
158 {
159 	struct mux_session_confirm_ctx *cctx = arg;
160 	const char *display;
161 	Channel *c;
162 	int i;
163 
164 	if (cctx == NULL)
165 		fatal("%s: cctx == NULL", __func__);
166 	if ((c = channel_lookup(id)) == NULL)
167 		fatal("%s: no channel for id %d", __func__, id);
168 
169 	display = getenv("DISPLAY");
170 	if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
171 		char *proto, *data;
172 		/* Get reasonable local authentication information. */
173 		client_x11_get_proto(display, options.xauth_location,
174 		    options.forward_x11_trusted, &proto, &data);
175 		/* Request forwarding with authentication spoofing. */
176 		debug("Requesting X11 forwarding with authentication spoofing.");
177 		x11_request_forwarding_with_spoofing(id, display, proto, data);
178 		/* XXX wait for reply */
179 	}
180 
181 	if (cctx->want_agent_fwd && options.forward_agent) {
182 		debug("Requesting authentication agent forwarding.");
183 		channel_request_start(id, "auth-agent-req@openssh.com", 0);
184 		packet_send();
185 	}
186 
187 	client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
188 	    cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);
189 
190 	c->open_confirm_ctx = NULL;
191 	buffer_free(&cctx->cmd);
192 	xfree(cctx->term);
193 	if (cctx->env != NULL) {
194 		for (i = 0; cctx->env[i] != NULL; i++)
195 			xfree(cctx->env[i]);
196 		xfree(cctx->env);
197 	}
198 	xfree(cctx);
199 }
200 
201 /*
202  * Accept a connection on the mux master socket and process the
203  * client's request. Returns flag indicating whether mux master should
204  * begin graceful close.
205  */
206 int
207 muxserver_accept_control(void)
208 {
209 	Buffer m;
210 	Channel *c;
211 	int client_fd, new_fd[3], ver, allowed, window, packetmax;
212 	socklen_t addrlen;
213 	struct sockaddr_storage addr;
214 	struct mux_session_confirm_ctx *cctx;
215 	char *cmd;
216 	u_int i, j, len, env_len, mux_command, flags, escape_char;
217 	uid_t euid;
218 	gid_t egid;
219 	int start_close = 0;
220 
221 	/*
222 	 * Accept connection on control socket
223 	 */
224 	memset(&addr, 0, sizeof(addr));
225 	addrlen = sizeof(addr);
226 	if ((client_fd = accept(muxserver_sock,
227 	    (struct sockaddr*)&addr, &addrlen)) == -1) {
228 		error("%s accept: %s", __func__, strerror(errno));
229 		return 0;
230 	}
231 
232 	if (getpeereid(client_fd, &euid, &egid) < 0) {
233 		error("%s getpeereid failed: %s", __func__, strerror(errno));
234 		close(client_fd);
235 		return 0;
236 	}
237 	if ((euid != 0) && (getuid() != euid)) {
238 		error("control mode uid mismatch: peer euid %u != uid %u",
239 		    (u_int) euid, (u_int) getuid());
240 		close(client_fd);
241 		return 0;
242 	}
243 
244 	/* XXX handle asynchronously */
245 	unset_nonblock(client_fd);
246 
247 	/* Read command */
248 	buffer_init(&m);
249 	if (ssh_msg_recv(client_fd, &m) == -1) {
250 		error("%s: client msg_recv failed", __func__);
251 		close(client_fd);
252 		buffer_free(&m);
253 		return 0;
254 	}
255 	if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
256 		error("%s: wrong client version %d", __func__, ver);
257 		buffer_free(&m);
258 		close(client_fd);
259 		return 0;
260 	}
261 
262 	allowed = 1;
263 	mux_command = buffer_get_int(&m);
264 	flags = buffer_get_int(&m);
265 
266 	buffer_clear(&m);
267 
268 	switch (mux_command) {
269 	case SSHMUX_COMMAND_OPEN:
270 		if (options.control_master == SSHCTL_MASTER_ASK ||
271 		    options.control_master == SSHCTL_MASTER_AUTO_ASK)
272 			allowed = ask_permission("Allow shared connection "
273 			    "to %s? ", host);
274 		/* continue below */
275 		break;
276 	case SSHMUX_COMMAND_TERMINATE:
277 		if (options.control_master == SSHCTL_MASTER_ASK ||
278 		    options.control_master == SSHCTL_MASTER_AUTO_ASK)
279 			allowed = ask_permission("Terminate shared connection "
280 			    "to %s? ", host);
281 		if (allowed)
282 			start_close = 1;
283 		/* FALLTHROUGH */
284 	case SSHMUX_COMMAND_ALIVE_CHECK:
285 		/* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */
286 		buffer_clear(&m);
287 		buffer_put_int(&m, allowed);
288 		buffer_put_int(&m, getpid());
289 		if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
290 			error("%s: client msg_send failed", __func__);
291 			close(client_fd);
292 			buffer_free(&m);
293 			return start_close;
294 		}
295 		buffer_free(&m);
296 		close(client_fd);
297 		return start_close;
298 	default:
299 		error("Unsupported command %d", mux_command);
300 		buffer_free(&m);
301 		close(client_fd);
302 		return 0;
303 	}
304 
305 	/* Reply for SSHMUX_COMMAND_OPEN */
306 	buffer_clear(&m);
307 	buffer_put_int(&m, allowed);
308 	buffer_put_int(&m, getpid());
309 	if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
310 		error("%s: client msg_send failed", __func__);
311 		close(client_fd);
312 		buffer_free(&m);
313 		return 0;
314 	}
315 
316 	if (!allowed) {
317 		error("Refused control connection");
318 		close(client_fd);
319 		buffer_free(&m);
320 		return 0;
321 	}
322 
323 	buffer_clear(&m);
324 	if (ssh_msg_recv(client_fd, &m) == -1) {
325 		error("%s: client msg_recv failed", __func__);
326 		close(client_fd);
327 		buffer_free(&m);
328 		return 0;
329 	}
330 	if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
331 		error("%s: wrong client version %d", __func__, ver);
332 		buffer_free(&m);
333 		close(client_fd);
334 		return 0;
335 	}
336 
337 	cctx = xcalloc(1, sizeof(*cctx));
338 	cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0;
339 	cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
340 	cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
341 	cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
342 	cctx->term = buffer_get_string(&m, &len);
343 	escape_char = buffer_get_int(&m);
344 
345 	cmd = buffer_get_string(&m, &len);
346 	buffer_init(&cctx->cmd);
347 	buffer_append(&cctx->cmd, cmd, strlen(cmd));
348 
349 	env_len = buffer_get_int(&m);
350 	env_len = MIN(env_len, 4096);
351 	debug3("%s: receiving %d env vars", __func__, env_len);
352 	if (env_len != 0) {
353 		cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env));
354 		for (i = 0; i < env_len; i++)
355 			cctx->env[i] = buffer_get_string(&m, &len);
356 		cctx->env[i] = NULL;
357 	}
358 
359 	debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__,
360 	    cctx->want_tty, cctx->want_subsys, cmd);
361 	xfree(cmd);
362 
363 	/* Gather fds from client */
364 	for(i = 0; i < 3; i++) {
365 		if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) {
366 			error("%s: failed to receive fd %d from slave",
367 			    __func__, i);
368 			for (j = 0; j < i; j++)
369 				close(new_fd[j]);
370 			for (j = 0; j < env_len; j++)
371 				xfree(cctx->env[j]);
372 			if (env_len > 0)
373 				xfree(cctx->env);
374 			xfree(cctx->term);
375 			buffer_free(&cctx->cmd);
376 			close(client_fd);
377 			xfree(cctx);
378 			return 0;
379 		}
380 	}
381 
382 	debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
383 	    new_fd[0], new_fd[1], new_fd[2]);
384 
385 	/* Try to pick up ttymodes from client before it goes raw */
386 	if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
387 		error("%s: tcgetattr: %s", __func__, strerror(errno));
388 
389 	/* This roundtrip is just for synchronisation of ttymodes */
390 	buffer_clear(&m);
391 	if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
392 		error("%s: client msg_send failed", __func__);
393 		close(client_fd);
394 		close(new_fd[0]);
395 		close(new_fd[1]);
396 		close(new_fd[2]);
397 		buffer_free(&m);
398 		xfree(cctx->term);
399 		if (env_len != 0) {
400 			for (i = 0; i < env_len; i++)
401 				xfree(cctx->env[i]);
402 			xfree(cctx->env);
403 		}
404 		return 0;
405 	}
406 	buffer_free(&m);
407 
408 	/* enable nonblocking unless tty */
409 	if (!isatty(new_fd[0]))
410 		set_nonblock(new_fd[0]);
411 	if (!isatty(new_fd[1]))
412 		set_nonblock(new_fd[1]);
413 	if (!isatty(new_fd[2]))
414 		set_nonblock(new_fd[2]);
415 
416 	set_nonblock(client_fd);
417 
418 	window = CHAN_SES_WINDOW_DEFAULT;
419 	packetmax = CHAN_SES_PACKET_DEFAULT;
420 	if (cctx->want_tty) {
421 		window >>= 1;
422 		packetmax >>= 1;
423 	}
424 
425 	c = channel_new("session", SSH_CHANNEL_OPENING,
426 	    new_fd[0], new_fd[1], new_fd[2], window, packetmax,
427 	    CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
428 
429 	c->ctl_fd = client_fd;
430 	if (cctx->want_tty && escape_char != 0xffffffff) {
431 		channel_register_filter(c->self,
432 		    client_simple_escape_filter, NULL,
433 		    client_filter_cleanup,
434 		    client_new_escape_filter_ctx((int)escape_char));
435 	}
436 
437 	debug3("%s: channel_new: %d", __func__, c->self);
438 
439 	channel_send_open(c->self);
440 	channel_register_open_confirm(c->self, mux_session_confirm, cctx);
441 	return 0;
442 }
443 
444 /* ** Multiplexing client support */
445 
446 /* Exit signal handler */
447 static void
448 control_client_sighandler(int signo)
449 {
450 	muxclient_terminate = signo;
451 }
452 
453 /*
454  * Relay signal handler - used to pass some signals from mux client to
455  * mux master.
456  */
457 static void
458 control_client_sigrelay(int signo)
459 {
460 	int save_errno = errno;
461 
462 	if (muxserver_pid > 1)
463 		kill(muxserver_pid, signo);
464 
465 	errno = save_errno;
466 }
467 
468 /* Check mux client environment variables before passing them to mux master. */
469 static int
470 env_permitted(char *env)
471 {
472 	int i, ret;
473 	char name[1024], *cp;
474 
475 	if ((cp = strchr(env, '=')) == NULL || cp == env)
476 		return (0);
477 	ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
478 	if (ret <= 0 || (size_t)ret >= sizeof(name))
479 		fatal("env_permitted: name '%.100s...' too long", env);
480 
481 	for (i = 0; i < options.num_send_env; i++)
482 		if (match_pattern(name, options.send_env[i]))
483 			return (1);
484 
485 	return (0);
486 }
487 
488 /* Multiplex client main loop. */
489 void
490 muxclient(const char *path)
491 {
492 	struct sockaddr_un addr;
493 	int i, r, fd, sock, exitval[2], num_env;
494 	Buffer m;
495 	char *term;
496 	extern char **environ;
497 	u_int allowed, flags;
498 
499 	if (muxclient_command == 0)
500 		muxclient_command = SSHMUX_COMMAND_OPEN;
501 
502 	switch (options.control_master) {
503 	case SSHCTL_MASTER_AUTO:
504 	case SSHCTL_MASTER_AUTO_ASK:
505 		debug("auto-mux: Trying existing master");
506 		/* FALLTHROUGH */
507 	case SSHCTL_MASTER_NO:
508 		break;
509 	default:
510 		return;
511 	}
512 
513 	memset(&addr, '\0', sizeof(addr));
514 	addr.sun_family = AF_UNIX;
515 	addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
516 	    strlen(path) + 1;
517 
518 	if (strlcpy(addr.sun_path, path,
519 	    sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
520 		fatal("ControlPath too long");
521 
522 	if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
523 		fatal("%s socket(): %s", __func__, strerror(errno));
524 
525 	if (connect(sock, (struct sockaddr *)&addr, addr.sun_len) == -1) {
526 		if (muxclient_command != SSHMUX_COMMAND_OPEN) {
527 			fatal("Control socket connect(%.100s): %s", path,
528 			    strerror(errno));
529 		}
530 		if (errno == ENOENT)
531 			debug("Control socket \"%.100s\" does not exist", path);
532 		else {
533 			error("Control socket connect(%.100s): %s", path,
534 			    strerror(errno));
535 		}
536 		close(sock);
537 		return;
538 	}
539 
540 	if (stdin_null_flag) {
541 		if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
542 			fatal("open(/dev/null): %s", strerror(errno));
543 		if (dup2(fd, STDIN_FILENO) == -1)
544 			fatal("dup2: %s", strerror(errno));
545 		if (fd > STDERR_FILENO)
546 			close(fd);
547 	}
548 
549 	term = getenv("TERM");
550 
551 	flags = 0;
552 	if (tty_flag)
553 		flags |= SSHMUX_FLAG_TTY;
554 	if (subsystem_flag)
555 		flags |= SSHMUX_FLAG_SUBSYS;
556 	if (options.forward_x11)
557 		flags |= SSHMUX_FLAG_X11_FWD;
558 	if (options.forward_agent)
559 		flags |= SSHMUX_FLAG_AGENT_FWD;
560 
561 	signal(SIGPIPE, SIG_IGN);
562 
563 	buffer_init(&m);
564 
565 	/* Send our command to server */
566 	buffer_put_int(&m, muxclient_command);
567 	buffer_put_int(&m, flags);
568 	if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
569 		error("%s: msg_send", __func__);
570  muxerr:
571 		close(sock);
572 		buffer_free(&m);
573 		if (muxclient_command != SSHMUX_COMMAND_OPEN)
574 			cleanup_exit(255);
575 		logit("Falling back to non-multiplexed connection");
576 		xfree(options.control_path);
577 		options.control_path = NULL;
578 		options.control_master = SSHCTL_MASTER_NO;
579 		return;
580 	}
581 	buffer_clear(&m);
582 
583 	/* Get authorisation status and PID of controlee */
584 	if (ssh_msg_recv(sock, &m) == -1) {
585 		error("%s: Did not receive reply from master", __func__);
586 		goto muxerr;
587 	}
588 	if (buffer_get_char(&m) != SSHMUX_VER) {
589 		error("%s: Master replied with wrong version", __func__);
590 		goto muxerr;
591 	}
592 	if (buffer_get_int_ret(&allowed, &m) != 0) {
593 		error("%s: bad server reply", __func__);
594 		goto muxerr;
595 	}
596 	if (allowed != 1) {
597 		error("Connection to master denied");
598 		goto muxerr;
599 	}
600 	muxserver_pid = buffer_get_int(&m);
601 
602 	buffer_clear(&m);
603 
604 	switch (muxclient_command) {
605 	case SSHMUX_COMMAND_ALIVE_CHECK:
606 		fprintf(stderr, "Master running (pid=%d)\r\n",
607 		    muxserver_pid);
608 		exit(0);
609 	case SSHMUX_COMMAND_TERMINATE:
610 		fprintf(stderr, "Exit request sent.\r\n");
611 		exit(0);
612 	case SSHMUX_COMMAND_OPEN:
613 		buffer_put_cstring(&m, term ? term : "");
614 		if (options.escape_char == SSH_ESCAPECHAR_NONE)
615 			buffer_put_int(&m, 0xffffffff);
616 		else
617 			buffer_put_int(&m, options.escape_char);
618 		buffer_append(&command, "\0", 1);
619 		buffer_put_cstring(&m, buffer_ptr(&command));
620 
621 		if (options.num_send_env == 0 || environ == NULL) {
622 			buffer_put_int(&m, 0);
623 		} else {
624 			/* Pass environment */
625 			num_env = 0;
626 			for (i = 0; environ[i] != NULL; i++) {
627 				if (env_permitted(environ[i]))
628 					num_env++; /* Count */
629 			}
630 			buffer_put_int(&m, num_env);
631 		for (i = 0; environ[i] != NULL && num_env >= 0; i++) {
632 				if (env_permitted(environ[i])) {
633 					num_env--;
634 					buffer_put_cstring(&m, environ[i]);
635 				}
636 			}
637 		}
638 		break;
639 	default:
640 		fatal("unrecognised muxclient_command %d", muxclient_command);
641 	}
642 
643 	if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
644 		error("%s: msg_send", __func__);
645 		goto muxerr;
646 	}
647 
648 	if (mm_send_fd(sock, STDIN_FILENO) == -1 ||
649 	    mm_send_fd(sock, STDOUT_FILENO) == -1 ||
650 	    mm_send_fd(sock, STDERR_FILENO) == -1) {
651 		error("%s: send fds failed", __func__);
652 		goto muxerr;
653 	}
654 
655 	/*
656 	 * Mux errors are non-recoverable from this point as the master
657 	 * has ownership of the session now.
658 	 */
659 
660 	/* Wait for reply, so master has a chance to gather ttymodes */
661 	buffer_clear(&m);
662 	if (ssh_msg_recv(sock, &m) == -1)
663 		fatal("%s: msg_recv", __func__);
664 	if (buffer_get_char(&m) != SSHMUX_VER)
665 		fatal("%s: wrong version", __func__);
666 	buffer_free(&m);
667 
668 	signal(SIGHUP, control_client_sighandler);
669 	signal(SIGINT, control_client_sighandler);
670 	signal(SIGTERM, control_client_sighandler);
671 	signal(SIGWINCH, control_client_sigrelay);
672 
673 	if (tty_flag)
674 		enter_raw_mode();
675 
676 	/*
677 	 * Stick around until the controlee closes the client_fd.
678 	 * Before it does, it is expected to write this process' exit
679 	 * value (one int). This process must read the value and wait for
680 	 * the closure of the client_fd; if this one closes early, the
681 	 * multiplex master will terminate early too (possibly losing data).
682 	 */
683 	exitval[0] = 0;
684 	for (i = 0; !muxclient_terminate && i < (int)sizeof(exitval);) {
685 		r = read(sock, (char *)exitval + i, sizeof(exitval) - i);
686 		if (r == 0) {
687 			debug2("Received EOF from master");
688 			break;
689 		}
690 		if (r == -1) {
691 			if (errno == EINTR)
692 				continue;
693 			fatal("%s: read %s", __func__, strerror(errno));
694 		}
695 		i += r;
696 	}
697 
698 	close(sock);
699 	leave_raw_mode();
700 	if (i > (int)sizeof(int))
701 		fatal("%s: master returned too much data (%d > %lu)",
702 		    __func__, i, (u_long)sizeof(int));
703 	if (muxclient_terminate) {
704 		debug2("Exiting on signal %d", muxclient_terminate);
705 		exitval[0] = 255;
706 	} else if (i < (int)sizeof(int)) {
707 		debug2("Control master terminated unexpectedly");
708 		exitval[0] = 255;
709 	} else
710 		debug2("Received exit status from master %d", exitval[0]);
711 
712 	if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
713 		fprintf(stderr, "Shared connection to %s closed.\r\n", host);
714 
715 	exit(exitval[0]);
716 }
717