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