1/*	$NetBSD: session.c,v 1.7 2011/07/25 03:03:11 christos Exp $	*/
2/* $OpenBSD: session.c,v 1.258 2010/11/25 04:10:09 djm Exp $ */
3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 *                    All rights reserved
6 *
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose.  Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
12 *
13 * SSH2 support by Markus Friedl.
14 * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 *    notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in the
23 *    documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "includes.h"
38__RCSID("$NetBSD: session.c,v 1.7 2011/07/25 03:03:11 christos Exp $");
39#include <sys/types.h>
40#include <sys/wait.h>
41#include <sys/un.h>
42#include <sys/stat.h>
43#include <sys/socket.h>
44#include <sys/param.h>
45#include <sys/queue.h>
46
47#include <errno.h>
48#include <fcntl.h>
49#include <grp.h>
50#include <login_cap.h>
51#include <paths.h>
52#include <pwd.h>
53#include <signal.h>
54#include <stdio.h>
55#include <stdlib.h>
56#include <string.h>
57#include <unistd.h>
58
59#include "xmalloc.h"
60#include "ssh.h"
61#include "ssh1.h"
62#include "ssh2.h"
63#include "sshpty.h"
64#include "packet.h"
65#include "buffer.h"
66#include "match.h"
67#include "uidswap.h"
68#include "compat.h"
69#include "channels.h"
70#include "key.h"
71#include "cipher.h"
72#include "kex.h"
73#include "hostfile.h"
74#include "auth.h"
75#include "auth-options.h"
76#include "pathnames.h"
77#include "log.h"
78#include "servconf.h"
79#include "sshlogin.h"
80#include "serverloop.h"
81#include "canohost.h"
82#include "misc.h"
83#include "session.h"
84#ifdef GSSAPI
85#include "ssh-gss.h"
86#endif
87#include "monitor_wrap.h"
88#include "sftp.h"
89
90#ifdef KRB5
91#include <krb5/kafs.h>
92#endif
93
94#define IS_INTERNAL_SFTP(c) \
95	(!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
96	 (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
97	  c[sizeof(INTERNAL_SFTP_NAME) - 1] == ' ' || \
98	  c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\t'))
99
100/* func */
101
102Session *session_new(void);
103void	session_set_fds(Session *, int, int, int, int, int);
104void	session_pty_cleanup(Session *);
105void	session_proctitle(Session *);
106int	session_setup_x11fwd(Session *);
107int	do_exec_pty(Session *, const char *);
108int	do_exec_no_pty(Session *, const char *);
109int	do_exec(Session *, const char *);
110void	do_login(Session *, const char *);
111__dead void	do_child(Session *, const char *);
112void	do_motd(void);
113int	check_quietlogin(Session *, const char *);
114
115static void do_authenticated1(Authctxt *);
116static void do_authenticated2(Authctxt *);
117
118static int session_pty_req(Session *);
119
120/* import */
121extern ServerOptions options;
122extern char *__progname;
123extern int log_stderr;
124extern int debug_flag;
125extern u_int utmp_len;
126extern int startup_pipe;
127extern void destroy_sensitive_data(void);
128extern Buffer loginmsg;
129
130/* original command from peer. */
131const char *original_command = NULL;
132
133/* data */
134static int sessions_first_unused = -1;
135static int sessions_nalloc = 0;
136static Session *sessions = NULL;
137
138#define SUBSYSTEM_NONE			0
139#define SUBSYSTEM_EXT			1
140#define SUBSYSTEM_INT_SFTP		2
141#define SUBSYSTEM_INT_SFTP_ERROR	3
142
143#ifdef HAVE_LOGIN_CAP
144login_cap_t *lc;
145#endif
146
147static int is_child = 0;
148
149/* Name and directory of socket for authentication agent forwarding. */
150static char *auth_sock_name = NULL;
151static char *auth_sock_dir = NULL;
152
153/* removes the agent forwarding socket */
154
155static void
156auth_sock_cleanup_proc(struct passwd *pw)
157{
158	if (auth_sock_name != NULL) {
159		temporarily_use_uid(pw);
160		unlink(auth_sock_name);
161		rmdir(auth_sock_dir);
162		auth_sock_name = NULL;
163		restore_uid();
164	}
165}
166
167static int
168auth_input_request_forwarding(struct passwd * pw)
169{
170	Channel *nc;
171	int sock = -1;
172	struct sockaddr_un sunaddr;
173
174	if (auth_sock_name != NULL) {
175		error("authentication forwarding requested twice.");
176		return 0;
177	}
178
179	/* Temporarily drop privileged uid for mkdir/bind. */
180	temporarily_use_uid(pw);
181
182	/* Allocate a buffer for the socket name, and format the name. */
183	auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX");
184
185	/* Create private directory for socket */
186	if (mkdtemp(auth_sock_dir) == NULL) {
187		packet_send_debug("Agent forwarding disabled: "
188		    "mkdtemp() failed: %.100s", strerror(errno));
189		restore_uid();
190		xfree(auth_sock_dir);
191		auth_sock_dir = NULL;
192		goto authsock_err;
193	}
194
195	xasprintf(&auth_sock_name, "%s/agent.%ld",
196	    auth_sock_dir, (long) getpid());
197
198	/* Create the socket. */
199	sock = socket(AF_UNIX, SOCK_STREAM, 0);
200	if (sock < 0) {
201		error("socket: %.100s", strerror(errno));
202		restore_uid();
203		goto authsock_err;
204	}
205
206	/* Bind it to the name. */
207	memset(&sunaddr, 0, sizeof(sunaddr));
208	sunaddr.sun_family = AF_UNIX;
209	strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
210
211	if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
212		error("bind: %.100s", strerror(errno));
213		restore_uid();
214		goto authsock_err;
215	}
216
217	/* Restore the privileged uid. */
218	restore_uid();
219
220	/* Start listening on the socket. */
221	if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
222		error("listen: %.100s", strerror(errno));
223		goto authsock_err;
224	}
225
226	/* Allocate a channel for the authentication agent socket. */
227	/* this shouldn't matter if its hpn or not - cjr */
228	nc = channel_new("auth socket",
229	    SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
230	    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
231	    0, "auth socket", 1);
232	nc->path = xstrdup(auth_sock_name);
233	return 1;
234
235 authsock_err:
236	if (auth_sock_name != NULL)
237		xfree(auth_sock_name);
238	if (auth_sock_dir != NULL) {
239		rmdir(auth_sock_dir);
240		xfree(auth_sock_dir);
241	}
242	if (sock != -1)
243		close(sock);
244	auth_sock_name = NULL;
245	auth_sock_dir = NULL;
246	return 0;
247}
248
249static void
250display_loginmsg(void)
251{
252	if (buffer_len(&loginmsg) > 0) {
253		buffer_append(&loginmsg, "\0", 1);
254		printf("%s", (char *)buffer_ptr(&loginmsg));
255		buffer_clear(&loginmsg);
256	}
257}
258
259void
260do_authenticated(Authctxt *authctxt)
261{
262	setproctitle("%s", authctxt->pw->pw_name);
263
264	/* setup the channel layer */
265	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
266		channel_permit_all_opens();
267
268	auth_debug_send();
269
270	if (compat20)
271		do_authenticated2(authctxt);
272	else
273		do_authenticated1(authctxt);
274
275	do_cleanup(authctxt);
276}
277
278/*
279 * Prepares for an interactive session.  This is called after the user has
280 * been successfully authenticated.  During this message exchange, pseudo
281 * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
282 * are requested, etc.
283 */
284static void
285do_authenticated1(Authctxt *authctxt)
286{
287	Session *s;
288	char *command;
289	int success, type, screen_flag;
290	int enable_compression_after_reply = 0;
291	u_int proto_len, data_len, dlen, compression_level = 0;
292
293	s = session_new();
294	if (s == NULL) {
295		error("no more sessions");
296		return;
297	}
298	s->authctxt = authctxt;
299	s->pw = authctxt->pw;
300
301	/*
302	 * We stay in this loop until the client requests to execute a shell
303	 * or a command.
304	 */
305	for (;;) {
306		success = 0;
307
308		/* Get a packet from the client. */
309		type = packet_read();
310
311		/* Process the packet. */
312		switch (type) {
313		case SSH_CMSG_REQUEST_COMPRESSION:
314			compression_level = packet_get_int();
315			packet_check_eom();
316			if (compression_level < 1 || compression_level > 9) {
317				packet_send_debug("Received invalid compression level %d.",
318				    compression_level);
319				break;
320			}
321			if (options.compression == COMP_NONE) {
322				debug2("compression disabled");
323				break;
324			}
325			/* Enable compression after we have responded with SUCCESS. */
326			enable_compression_after_reply = 1;
327			success = 1;
328			break;
329
330		case SSH_CMSG_REQUEST_PTY:
331			success = session_pty_req(s);
332			break;
333
334		case SSH_CMSG_X11_REQUEST_FORWARDING:
335			s->auth_proto = packet_get_string(&proto_len);
336			s->auth_data = packet_get_string(&data_len);
337
338			screen_flag = packet_get_protocol_flags() &
339			    SSH_PROTOFLAG_SCREEN_NUMBER;
340			debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
341
342			if (packet_remaining() == 4) {
343				if (!screen_flag)
344					debug2("Buggy client: "
345					    "X11 screen flag missing");
346				s->screen = packet_get_int();
347			} else {
348				s->screen = 0;
349			}
350			packet_check_eom();
351			success = session_setup_x11fwd(s);
352			if (!success) {
353				xfree(s->auth_proto);
354				xfree(s->auth_data);
355				s->auth_proto = NULL;
356				s->auth_data = NULL;
357			}
358			break;
359
360		case SSH_CMSG_AGENT_REQUEST_FORWARDING:
361			if (!options.allow_agent_forwarding ||
362			    no_agent_forwarding_flag || compat13) {
363				debug("Authentication agent forwarding not permitted for this authentication.");
364				break;
365			}
366			debug("Received authentication agent forwarding request.");
367			success = auth_input_request_forwarding(s->pw);
368			break;
369
370		case SSH_CMSG_PORT_FORWARD_REQUEST:
371			if (no_port_forwarding_flag) {
372				debug("Port forwarding not permitted for this authentication.");
373				break;
374			}
375			if (!options.allow_tcp_forwarding) {
376				debug("Port forwarding not permitted.");
377				break;
378			}
379			debug("Received TCP/IP port forwarding request.");
380			if (channel_input_port_forward_request(s->pw->pw_uid == 0,
381			    options.gateway_ports) < 0) {
382				debug("Port forwarding failed.");
383				break;
384			}
385			success = 1;
386			break;
387
388		case SSH_CMSG_MAX_PACKET_SIZE:
389			if (packet_set_maxsize(packet_get_int()) > 0)
390				success = 1;
391			break;
392
393#if defined(AFS) || defined(KRB5)
394		case SSH_CMSG_HAVE_KERBEROS_TGT:
395			if (!options.kerberos_tgt_passing) {
396				verbose("Kerberos TGT passing disabled.");
397			} else {
398				char *kdata = packet_get_string(&dlen);
399				packet_check_eom();
400
401				/* XXX - 0x41, see creds_to_radix version */
402				if (kdata[0] != 0x41) {
403#ifdef KRB5
404					krb5_data tgt;
405					tgt.data = kdata;
406					tgt.length = dlen;
407
408					if (auth_krb5_tgt(s->authctxt, &tgt))
409						success = 1;
410					else
411						verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);
412#endif /* KRB5 */
413				} else {
414#ifdef AFS
415					if (auth_krb4_tgt(s->authctxt, kdata))
416						success = 1;
417					else
418						verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);
419#endif /* AFS */
420				}
421				xfree(kdata);
422			}
423			break;
424#endif /* AFS || KRB5 */
425
426#ifdef AFS
427		case SSH_CMSG_HAVE_AFS_TOKEN:
428			if (!options.afs_token_passing || !k_hasafs()) {
429				verbose("AFS token passing disabled.");
430			} else {
431				/* Accept AFS token. */
432				char *token = packet_get_string(&dlen);
433				packet_check_eom();
434
435				if (auth_afs_token(s->authctxt, token))
436					success = 1;
437				else
438					verbose("AFS token refused for %.100s",
439					    s->authctxt->user);
440				xfree(token);
441			}
442			break;
443#endif /* AFS */
444
445		case SSH_CMSG_EXEC_SHELL:
446		case SSH_CMSG_EXEC_CMD:
447			if (type == SSH_CMSG_EXEC_CMD) {
448				command = packet_get_string(&dlen);
449				debug("Exec command '%.500s'", command);
450				if (do_exec(s, command) != 0)
451					packet_disconnect(
452					    "command execution failed");
453				xfree(command);
454			} else {
455				if (do_exec(s, NULL) != 0)
456					packet_disconnect(
457					    "shell execution failed");
458			}
459			packet_check_eom();
460			session_close(s);
461			return;
462
463		default:
464			/*
465			 * Any unknown messages in this phase are ignored,
466			 * and a failure message is returned.
467			 */
468			logit("Unknown packet type received after authentication: %d", type);
469		}
470		packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
471		packet_send();
472		packet_write_wait();
473
474		/* Enable compression now that we have replied if appropriate. */
475		if (enable_compression_after_reply) {
476			enable_compression_after_reply = 0;
477			packet_start_compression(compression_level);
478		}
479	}
480}
481
482#define USE_PIPES
483/*
484 * This is called to fork and execute a command when we have no tty.  This
485 * will call do_child from the child, and server_loop from the parent after
486 * setting up file descriptors and such.
487 */
488int
489do_exec_no_pty(Session *s, const char *command)
490{
491	pid_t pid;
492#ifdef USE_PIPES
493	int pin[2], pout[2], perr[2];
494
495	if (s == NULL)
496		fatal("do_exec_no_pty: no session");
497
498	/* Allocate pipes for communicating with the program. */
499	if (pipe(pin) < 0) {
500		error("%s: pipe in: %.100s", __func__, strerror(errno));
501		return -1;
502	}
503	if (pipe(pout) < 0) {
504		error("%s: pipe out: %.100s", __func__, strerror(errno));
505		close(pin[0]);
506		close(pin[1]);
507		return -1;
508	}
509	if (pipe(perr) < 0) {
510		error("%s: pipe err: %.100s", __func__,
511		    strerror(errno));
512		close(pin[0]);
513		close(pin[1]);
514		close(pout[0]);
515		close(pout[1]);
516		return -1;
517	}
518#else
519	int inout[2], err[2];
520
521	if (s == NULL)
522		fatal("do_exec_no_pty: no session");
523
524	/* Uses socket pairs to communicate with the program. */
525	if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) {
526		error("%s: socketpair #1: %.100s", __func__, strerror(errno));
527		return -1;
528	}
529	if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) {
530		error("%s: socketpair #2: %.100s", __func__,
531		    strerror(errno));
532		close(inout[0]);
533		close(inout[1]);
534		return -1;
535	}
536#endif
537
538	session_proctitle(s);
539
540#ifdef notdef
541#if defined(USE_PAM)
542	if (options.use_pam && !use_privsep)
543		do_pam_setcred(1);
544#endif /* USE_PAM */
545#endif
546
547	/* Fork the child. */
548	switch ((pid = fork())) {
549	case -1:
550		error("%s: fork: %.100s", __func__, strerror(errno));
551#ifdef USE_PIPES
552		close(pin[0]);
553		close(pin[1]);
554		close(pout[0]);
555		close(pout[1]);
556		close(perr[0]);
557		close(perr[1]);
558#else
559		close(inout[0]);
560		close(inout[1]);
561		close(err[0]);
562		close(err[1]);
563#endif
564		return -1;
565	case 0:
566		is_child = 1;
567
568		/* Child.  Reinitialize the log since the pid has changed. */
569		log_init(__progname, options.log_level,
570		    options.log_facility, log_stderr);
571
572		/*
573		 * Create a new session and process group since the 4.4BSD
574		 * setlogin() affects the entire process group.
575		 */
576		if (setsid() < 0)
577			error("setsid failed: %.100s", strerror(errno));
578
579#ifdef USE_PIPES
580		/*
581		 * Redirect stdin.  We close the parent side of the socket
582		 * pair, and make the child side the standard input.
583		 */
584		close(pin[1]);
585		if (dup2(pin[0], 0) < 0)
586			perror("dup2 stdin");
587		close(pin[0]);
588
589		/* Redirect stdout. */
590		close(pout[0]);
591		if (dup2(pout[1], 1) < 0)
592			perror("dup2 stdout");
593		close(pout[1]);
594
595		/* Redirect stderr. */
596		close(perr[0]);
597		if (dup2(perr[1], 2) < 0)
598			perror("dup2 stderr");
599		close(perr[1]);
600#else
601		/*
602		 * Redirect stdin, stdout, and stderr.  Stdin and stdout will
603		 * use the same socket, as some programs (particularly rdist)
604		 * seem to depend on it.
605		 */
606		close(inout[1]);
607		close(err[1]);
608		if (dup2(inout[0], 0) < 0)	/* stdin */
609			perror("dup2 stdin");
610		if (dup2(inout[0], 1) < 0)	/* stdout (same as stdin) */
611			perror("dup2 stdout");
612		close(inout[0]);
613		if (dup2(err[0], 2) < 0)	/* stderr */
614			perror("dup2 stderr");
615		close(err[0]);
616#endif
617
618		/* Do processing for the child (exec command etc). */
619		do_child(s, command);
620		/* NOTREACHED */
621	default:
622		break;
623	}
624
625	s->pid = pid;
626	/* Set interactive/non-interactive mode. */
627	packet_set_interactive(s->display != NULL,
628	    options.ip_qos_interactive, options.ip_qos_bulk);
629
630#ifdef USE_PIPES
631	/* We are the parent.  Close the child sides of the pipes. */
632	close(pin[0]);
633	close(pout[1]);
634	close(perr[1]);
635
636	if (compat20) {
637		session_set_fds(s, pin[1], pout[0], perr[0],
638		    s->is_subsystem, 0);
639	} else {
640		/* Enter the interactive session. */
641		server_loop(pid, pin[1], pout[0], perr[0]);
642		/* server_loop has closed pin[1], pout[0], and perr[0]. */
643	}
644#else
645	/* We are the parent.  Close the child sides of the socket pairs. */
646	close(inout[0]);
647	close(err[0]);
648
649	/*
650	 * Enter the interactive session.  Note: server_loop must be able to
651	 * handle the case that fdin and fdout are the same.
652	 */
653	if (compat20) {
654		session_set_fds(s, inout[1], inout[1], err[1],
655		    s->is_subsystem, 0);
656	} else {
657		server_loop(pid, inout[1], inout[1], err[1]);
658		/* server_loop has closed inout[1] and err[1]. */
659	}
660#endif
661	return 0;
662}
663
664/*
665 * This is called to fork and execute a command when we have a tty.  This
666 * will call do_child from the child, and server_loop from the parent after
667 * setting up file descriptors, controlling tty, updating wtmp, utmp,
668 * lastlog, and other such operations.
669 */
670int
671do_exec_pty(Session *s, const char *command)
672{
673	int fdout, ptyfd, ttyfd, ptymaster;
674	pid_t pid;
675
676	if (s == NULL)
677		fatal("do_exec_pty: no session");
678	ptyfd = s->ptyfd;
679	ttyfd = s->ttyfd;
680
681#if defined(USE_PAM)
682	if (options.use_pam) {
683		do_pam_set_tty(s->tty);
684		if (!use_privsep)
685			do_pam_setcred(1);
686	}
687#endif
688
689	/*
690	 * Create another descriptor of the pty master side for use as the
691	 * standard input.  We could use the original descriptor, but this
692	 * simplifies code in server_loop.  The descriptor is bidirectional.
693	 * Do this before forking (and cleanup in the child) so as to
694	 * detect and gracefully fail out-of-fd conditions.
695	 */
696	if ((fdout = dup(ptyfd)) < 0) {
697		error("%s: dup #1: %s", __func__, strerror(errno));
698		close(ttyfd);
699		close(ptyfd);
700		return -1;
701	}
702	/* we keep a reference to the pty master */
703	if ((ptymaster = dup(ptyfd)) < 0) {
704		error("%s: dup #2: %s", __func__, strerror(errno));
705		close(ttyfd);
706		close(ptyfd);
707		close(fdout);
708		return -1;
709	}
710
711	/* Fork the child. */
712	switch ((pid = fork())) {
713	case -1:
714		error("%s: fork: %.100s", __func__, strerror(errno));
715		close(fdout);
716		close(ptymaster);
717		close(ttyfd);
718		close(ptyfd);
719		return -1;
720	case 0:
721		is_child = 1;
722
723		close(fdout);
724		close(ptymaster);
725
726		/* Child.  Reinitialize the log because the pid has changed. */
727		log_init(__progname, options.log_level,
728		    options.log_facility, log_stderr);
729		/* Close the master side of the pseudo tty. */
730		close(ptyfd);
731
732		/* Make the pseudo tty our controlling tty. */
733		pty_make_controlling_tty(&ttyfd, s->tty);
734
735		/* Redirect stdin/stdout/stderr from the pseudo tty. */
736		if (dup2(ttyfd, 0) < 0)
737			error("dup2 stdin: %s", strerror(errno));
738		if (dup2(ttyfd, 1) < 0)
739			error("dup2 stdout: %s", strerror(errno));
740		if (dup2(ttyfd, 2) < 0)
741			error("dup2 stderr: %s", strerror(errno));
742
743		/* Close the extra descriptor for the pseudo tty. */
744		close(ttyfd);
745
746		/* record login, etc. similar to login(1) */
747		if (!(options.use_login && command == NULL))
748			do_login(s, command);
749
750		/*
751		 * Do common processing for the child, such as execing
752		 * the command.
753		 */
754		do_child(s, command);
755		/* NOTREACHED */
756	default:
757		break;
758	}
759	s->pid = pid;
760
761	/* Parent.  Close the slave side of the pseudo tty. */
762	close(ttyfd);
763
764	/* Enter interactive session. */
765	s->ptymaster = ptymaster;
766	packet_set_interactive(1,
767	    options.ip_qos_interactive, options.ip_qos_bulk);
768	if (compat20) {
769		session_set_fds(s, ptyfd, fdout, -1, 1, 1);
770	} else {
771		server_loop(pid, ptyfd, fdout, -1);
772		/* server_loop _has_ closed ptyfd and fdout. */
773	}
774	return 0;
775}
776
777/*
778 * This is called to fork and execute a command.  If another command is
779 * to be forced, execute that instead.
780 */
781int
782do_exec(Session *s, const char *command)
783{
784	int ret;
785
786	if (options.adm_forced_command) {
787		original_command = command;
788		command = options.adm_forced_command;
789		if (IS_INTERNAL_SFTP(command)) {
790			s->is_subsystem = s->is_subsystem ?
791			    SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
792		} else if (s->is_subsystem)
793			s->is_subsystem = SUBSYSTEM_EXT;
794		debug("Forced command (config) '%.900s'", command);
795	} else if (forced_command) {
796		original_command = command;
797		command = forced_command;
798		if (IS_INTERNAL_SFTP(command)) {
799			s->is_subsystem = s->is_subsystem ?
800			    SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
801		} else if (s->is_subsystem)
802			s->is_subsystem = SUBSYSTEM_EXT;
803		debug("Forced command (key option) '%.900s'", command);
804	}
805
806#ifdef GSSAPI
807	if (options.gss_authentication) {
808		temporarily_use_uid(s->pw);
809		ssh_gssapi_storecreds();
810		restore_uid();
811	}
812#endif
813	if (s->ttyfd != -1)
814		ret = do_exec_pty(s, command);
815	else
816		ret = do_exec_no_pty(s, command);
817
818	original_command = NULL;
819
820	/*
821	 * Clear loginmsg: it's the child's responsibility to display
822	 * it to the user, otherwise multiple sessions may accumulate
823	 * multiple copies of the login messages.
824	 */
825	buffer_clear(&loginmsg);
826
827	return ret;
828}
829
830
831/* administrative, login(1)-like work */
832void
833do_login(Session *s, const char *command)
834{
835	socklen_t fromlen;
836	struct sockaddr_storage from;
837	struct passwd * pw = s->pw;
838	pid_t pid = getpid();
839
840	/*
841	 * Get IP address of client. If the connection is not a socket, let
842	 * the address be 0.0.0.0.
843	 */
844	memset(&from, 0, sizeof(from));
845	fromlen = sizeof(from);
846	if (packet_connection_is_on_socket()) {
847		if (getpeername(packet_get_connection_in(),
848		    (struct sockaddr *)&from, &fromlen) < 0) {
849			debug("getpeername: %.100s", strerror(errno));
850			cleanup_exit(255);
851		}
852	}
853
854	/* Record that there was a login on that tty from the remote host. */
855	if (!use_privsep)
856		record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
857		    get_remote_name_or_ip(utmp_len,
858		    options.use_dns),
859		    (struct sockaddr *)&from, fromlen);
860
861#ifdef USE_PAM
862	/*
863	 * If password change is needed, do it now.
864	 * This needs to occur before the ~/.hushlogin check.
865	 */
866	if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) {
867		display_loginmsg();
868		do_pam_chauthtok();
869		s->authctxt->force_pwchange = 0;
870		/* XXX - signal [net] parent to enable forwardings */
871	}
872#endif
873
874	if (check_quietlogin(s, command))
875		return;
876
877	display_loginmsg();
878
879	do_motd();
880}
881
882/*
883 * Display the message of the day.
884 */
885void
886do_motd(void)
887{
888	FILE *f;
889	char buf[256];
890
891	if (options.print_motd) {
892#ifdef HAVE_LOGIN_CAP
893		f = fopen(login_getcapstr(lc, "welcome", __UNCONST("/etc/motd"),
894		    __UNCONST("/etc/motd")), "r");
895#else
896		f = fopen("/etc/motd", "r");
897#endif
898		if (f) {
899			while (fgets(buf, sizeof(buf), f))
900				fputs(buf, stdout);
901			fclose(f);
902		}
903	}
904}
905
906
907/*
908 * Check for quiet login, either .hushlogin or command given.
909 */
910int
911check_quietlogin(Session *s, const char *command)
912{
913	char buf[256];
914	struct passwd *pw = s->pw;
915	struct stat st;
916
917	/* Return 1 if .hushlogin exists or a command given. */
918	if (command != NULL)
919		return 1;
920	snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
921#ifdef HAVE_LOGIN_CAP
922	if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
923		return 1;
924#else
925	if (stat(buf, &st) >= 0)
926		return 1;
927#endif
928	return 0;
929}
930
931/*
932 * Sets the value of the given variable in the environment.  If the variable
933 * already exists, its value is overridden.
934 */
935void
936child_set_env(char ***envp, u_int *envsizep, const char *name,
937	const char *value)
938{
939	char **env;
940	u_int envsize;
941	u_int i, namelen;
942
943	/*
944	 * Find the slot where the value should be stored.  If the variable
945	 * already exists, we reuse the slot; otherwise we append a new slot
946	 * at the end of the array, expanding if necessary.
947	 */
948	env = *envp;
949	namelen = strlen(name);
950	for (i = 0; env[i]; i++)
951		if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
952			break;
953	if (env[i]) {
954		/* Reuse the slot. */
955		xfree(env[i]);
956	} else {
957		/* New variable.  Expand if necessary. */
958		envsize = *envsizep;
959		if (i >= envsize - 1) {
960			if (envsize >= 1000)
961				fatal("child_set_env: too many env vars");
962			envsize += 50;
963			env = (*envp) = xrealloc(env, envsize, sizeof(char *));
964			*envsizep = envsize;
965		}
966		/* Need to set the NULL pointer at end of array beyond the new slot. */
967		env[i + 1] = NULL;
968	}
969
970	/* Allocate space and format the variable in the appropriate slot. */
971	env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
972	snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
973}
974
975#ifdef HAVE_LOGIN_CAP
976/*
977 * Sets any environment variables specified in login.conf.
978 * Taken from:
979 *	NetBSD: login_cap.c,v 1.11 2001/07/22 13:34:01 wiz Exp
980 * Modified to use child_set_env instead of setenv.
981 */
982static void
983lc_setuserenv(char ***env, u_int *envsize, login_cap_t *lcp)
984{
985	const char *stop = ", \t";
986	int i, count;
987	char *ptr;
988	char **res;
989	char *str = login_getcapstr(lcp, "setenv", NULL, NULL);
990
991	if (str == NULL || *str == '\0')
992		return;
993
994	/* count the sub-strings */
995	for (i = 1, ptr = str; *ptr; i++) {
996		ptr += strcspn(ptr, stop);
997		if (*ptr)
998			ptr++;
999	}
1000
1001	/* allocate ptr array and string */
1002	count = i;
1003	res = malloc(count * sizeof(char *) + strlen(str) + 1);
1004
1005	if (!res)
1006		return;
1007
1008	ptr = (char *)res + count * sizeof(char *);
1009	strcpy(ptr, str);
1010
1011	/* split string */
1012	for (i = 0; *ptr && i < count; i++) {
1013		res[i] = ptr;
1014		ptr += strcspn(ptr, stop);
1015		if (*ptr)
1016			*ptr++ = '\0';
1017	}
1018
1019	res[i] = NULL;
1020
1021	for (i = 0; i < count && res[i]; i++) {
1022		if (*res[i] != '\0') {
1023			if ((ptr = strchr(res[i], '=')) != NULL)
1024				*ptr++ = '\0';
1025			else
1026				ptr = __UNCONST("");
1027			child_set_env(env, envsize, res[i], ptr);
1028		}
1029	}
1030
1031	free(res);
1032	return;
1033}
1034#endif
1035
1036/*
1037 * Reads environment variables from the given file and adds/overrides them
1038 * into the environment.  If the file does not exist, this does nothing.
1039 * Otherwise, it must consist of empty lines, comments (line starts with '#')
1040 * and assignments of the form name=value.  No other forms are allowed.
1041 */
1042static void
1043read_environment_file(char ***env, u_int *envsize,
1044	const char *filename)
1045{
1046	FILE *f;
1047	char buf[4096];
1048	char *cp, *value;
1049	u_int lineno = 0;
1050
1051	f = fopen(filename, "r");
1052	if (!f)
1053		return;
1054
1055	while (fgets(buf, sizeof(buf), f)) {
1056		if (++lineno > 1000)
1057			fatal("Too many lines in environment file %s", filename);
1058		for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
1059			;
1060		if (!*cp || *cp == '#' || *cp == '\n')
1061			continue;
1062
1063		cp[strcspn(cp, "\n")] = '\0';
1064
1065		value = strchr(cp, '=');
1066		if (value == NULL) {
1067			fprintf(stderr, "Bad line %u in %.100s\n", lineno,
1068			    filename);
1069			continue;
1070		}
1071		/*
1072		 * Replace the equals sign by nul, and advance value to
1073		 * the value string.
1074		 */
1075		*value = '\0';
1076		value++;
1077		child_set_env(env, envsize, cp, value);
1078	}
1079	fclose(f);
1080}
1081
1082#ifdef USE_PAM
1083void copy_environment(char **, char ***, u_int *);
1084void copy_environment(char **source, char ***env, u_int *envsize)
1085{
1086	char *var_name, *var_val;
1087	int i;
1088
1089	if (source == NULL)
1090		return;
1091
1092	for (i = 0; source[i] != NULL; i++) {
1093		var_name = xstrdup(source[i]);
1094		if ((var_val = strstr(var_name, "=")) == NULL) {
1095			xfree(var_name);
1096			continue;
1097		}
1098		*var_val++ = '\0';
1099
1100		debug3("Copy environment: %s=%s", var_name, var_val);
1101		child_set_env(env, envsize, var_name, var_val);
1102
1103		xfree(var_name);
1104	}
1105}
1106#endif
1107
1108static char **
1109do_setup_env(Session *s, const char *shell)
1110{
1111	char buf[256];
1112	u_int i, envsize;
1113	char **env, *laddr;
1114	struct passwd *pw = s->pw;
1115
1116	/* Initialize the environment. */
1117	envsize = 100;
1118	env = xcalloc(envsize, sizeof(char *));
1119	env[0] = NULL;
1120
1121#ifdef GSSAPI
1122	/* Allow any GSSAPI methods that we've used to alter
1123	 * the childs environment as they see fit
1124	 */
1125	ssh_gssapi_do_child(&env, &envsize);
1126#endif
1127
1128	if (!options.use_login) {
1129#ifdef HAVE_LOGIN_CAP
1130		lc_setuserenv(&env, &envsize, lc);
1131#endif
1132		/* Set basic environment. */
1133		for (i = 0; i < s->num_env; i++)
1134			child_set_env(&env, &envsize, s->env[i].name,
1135			    s->env[i].val);
1136
1137		child_set_env(&env, &envsize, "USER", pw->pw_name);
1138		child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
1139		child_set_env(&env, &envsize, "HOME", pw->pw_dir);
1140#ifdef HAVE_LOGIN_CAP
1141		if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)
1142			child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1143		else
1144			child_set_env(&env, &envsize, "PATH", getenv("PATH"));
1145#else
1146		child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1147#endif
1148
1149		snprintf(buf, sizeof buf, "%.200s/%.50s",
1150			 _PATH_MAILDIR, pw->pw_name);
1151		child_set_env(&env, &envsize, "MAIL", buf);
1152
1153		/* Normal systems set SHELL by default. */
1154		child_set_env(&env, &envsize, "SHELL", shell);
1155	}
1156	if (getenv("TZ"))
1157		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1158
1159	/* Set custom environment options from RSA authentication. */
1160	if (!options.use_login) {
1161		while (custom_environment) {
1162			struct envstring *ce = custom_environment;
1163			char *str = ce->s;
1164
1165			for (i = 0; str[i] != '=' && str[i]; i++)
1166				;
1167			if (str[i] == '=') {
1168				str[i] = 0;
1169				child_set_env(&env, &envsize, str, str + i + 1);
1170			}
1171			custom_environment = ce->next;
1172			xfree(ce->s);
1173			xfree(ce);
1174		}
1175	}
1176
1177	/* SSH_CLIENT deprecated */
1178	snprintf(buf, sizeof buf, "%.50s %d %d",
1179	    get_remote_ipaddr(), get_remote_port(), get_local_port());
1180	child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1181
1182	laddr = get_local_ipaddr(packet_get_connection_in());
1183	snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
1184	    get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());
1185	xfree(laddr);
1186	child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1187
1188	if (s->ttyfd != -1)
1189		child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1190	if (s->term)
1191		child_set_env(&env, &envsize, "TERM", s->term);
1192	if (s->display)
1193		child_set_env(&env, &envsize, "DISPLAY", s->display);
1194	if (original_command)
1195		child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1196		    original_command);
1197#ifdef KRB4
1198	if (s->authctxt->krb4_ticket_file)
1199		child_set_env(&env, &envsize, "KRBTKFILE",
1200		    s->authctxt->krb4_ticket_file);
1201#endif
1202#ifdef KRB5
1203	if (s->authctxt->krb5_ticket_file)
1204		child_set_env(&env, &envsize, "KRB5CCNAME",
1205		    s->authctxt->krb5_ticket_file);
1206#endif
1207#ifdef USE_PAM
1208	/*
1209	 * Pull in any environment variables that may have
1210	 * been set by PAM.
1211	 */
1212	if (options.use_pam) {
1213		char **p;
1214
1215		p = fetch_pam_child_environment();
1216		copy_environment(p, &env, &envsize);
1217		free_pam_environment(p);
1218
1219		p = fetch_pam_environment();
1220		copy_environment(p, &env, &envsize);
1221		free_pam_environment(p);
1222	}
1223#endif /* USE_PAM */
1224
1225	if (auth_sock_name != NULL)
1226		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1227		    auth_sock_name);
1228
1229	/* read $HOME/.ssh/environment. */
1230	if (options.permit_user_env && !options.use_login) {
1231		snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
1232		    pw->pw_dir);
1233		read_environment_file(&env, &envsize, buf);
1234	}
1235	if (debug_flag) {
1236		/* dump the environment */
1237		fprintf(stderr, "Environment:\n");
1238		for (i = 0; env[i]; i++)
1239			fprintf(stderr, "  %.200s\n", env[i]);
1240	}
1241	return env;
1242}
1243
1244/*
1245 * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
1246 * first in this order).
1247 */
1248static void
1249do_rc_files(Session *s, const char *shell)
1250{
1251	FILE *f = NULL;
1252	char cmd[1024];
1253	int do_xauth;
1254	struct stat st;
1255
1256	do_xauth =
1257	    s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
1258
1259	/* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */
1260	if (!s->is_subsystem && options.adm_forced_command == NULL &&
1261	    !no_user_rc && stat(_PATH_SSH_USER_RC, &st) >= 0) {
1262		snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
1263		    shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
1264		if (debug_flag)
1265			fprintf(stderr, "Running %s\n", cmd);
1266		f = popen(cmd, "w");
1267		if (f) {
1268			if (do_xauth)
1269				fprintf(f, "%s %s\n", s->auth_proto,
1270				    s->auth_data);
1271			pclose(f);
1272		} else
1273			fprintf(stderr, "Could not run %s\n",
1274			    _PATH_SSH_USER_RC);
1275	} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
1276		if (debug_flag)
1277			fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
1278			    _PATH_SSH_SYSTEM_RC);
1279		f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
1280		if (f) {
1281			if (do_xauth)
1282				fprintf(f, "%s %s\n", s->auth_proto,
1283				    s->auth_data);
1284			pclose(f);
1285		} else
1286			fprintf(stderr, "Could not run %s\n",
1287			    _PATH_SSH_SYSTEM_RC);
1288	} else if (do_xauth && options.xauth_location != NULL) {
1289		/* Add authority data to .Xauthority if appropriate. */
1290		if (debug_flag) {
1291			fprintf(stderr,
1292			    "Running %.500s remove %.100s\n",
1293			    options.xauth_location, s->auth_display);
1294			fprintf(stderr,
1295			    "%.500s add %.100s %.100s %.100s\n",
1296			    options.xauth_location, s->auth_display,
1297			    s->auth_proto, s->auth_data);
1298		}
1299		snprintf(cmd, sizeof cmd, "%s -q -",
1300		    options.xauth_location);
1301		f = popen(cmd, "w");
1302		if (f) {
1303			fprintf(f, "remove %s\n",
1304			    s->auth_display);
1305			fprintf(f, "add %s %s %s\n",
1306			    s->auth_display, s->auth_proto,
1307			    s->auth_data);
1308			pclose(f);
1309		} else {
1310			fprintf(stderr, "Could not run %s\n",
1311			    cmd);
1312		}
1313	}
1314}
1315
1316static void
1317do_nologin(struct passwd *pw)
1318{
1319	FILE *f = NULL;
1320	char buf[1024], *nl, *def_nl = __UNCONST(_PATH_NOLOGIN);
1321	struct stat sb;
1322
1323#ifdef HAVE_LOGIN_CAP
1324	if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
1325		return;
1326	nl = login_getcapstr(lc, "nologin", def_nl, def_nl);
1327
1328	if (stat(nl, &sb) == -1) {
1329		if (nl != def_nl)
1330			xfree(nl);
1331		return;
1332	}
1333#else
1334	if (pw->pw_uid)
1335		nl = def_nl;
1336#endif
1337	/* /etc/nologin exists.  Print its contents if we can and exit. */
1338	logit("User %.100s not allowed because %s exists", pw->pw_name, nl);
1339	if ((f = fopen(nl, "r")) != NULL) {
1340		while (fgets(buf, sizeof(buf), f))
1341			fputs(buf, stderr);
1342		fclose(f);
1343	}
1344	exit(254);
1345}
1346
1347/*
1348 * Chroot into a directory after checking it for safety: all path components
1349 * must be root-owned directories with strict permissions.
1350 */
1351static void
1352safely_chroot(const char *path, uid_t uid)
1353{
1354	const char *cp;
1355	char component[MAXPATHLEN];
1356	struct stat st;
1357
1358	if (*path != '/')
1359		fatal("chroot path does not begin at root");
1360	if (strlen(path) >= sizeof(component))
1361		fatal("chroot path too long");
1362
1363	/*
1364	 * Descend the path, checking that each component is a
1365	 * root-owned directory with strict permissions.
1366	 */
1367	for (cp = path; cp != NULL;) {
1368		if ((cp = strchr(cp, '/')) == NULL)
1369			strlcpy(component, path, sizeof(component));
1370		else {
1371			cp++;
1372			memcpy(component, path, cp - path);
1373			component[cp - path] = '\0';
1374		}
1375
1376		debug3("%s: checking '%s'", __func__, component);
1377
1378		if (stat(component, &st) != 0)
1379			fatal("%s: stat(\"%s\"): %s", __func__,
1380			    component, strerror(errno));
1381		if (st.st_uid != 0 || (st.st_mode & 022) != 0)
1382			fatal("bad ownership or modes for chroot "
1383			    "directory %s\"%s\"",
1384			    cp == NULL ? "" : "component ", component);
1385		if (!S_ISDIR(st.st_mode))
1386			fatal("chroot path %s\"%s\" is not a directory",
1387			    cp == NULL ? "" : "component ", component);
1388
1389	}
1390
1391	if (chdir(path) == -1)
1392		fatal("Unable to chdir to chroot path \"%s\": "
1393		    "%s", path, strerror(errno));
1394	if (chroot(path) == -1)
1395		fatal("chroot(\"%s\"): %s", path, strerror(errno));
1396	if (chdir("/") == -1)
1397		fatal("%s: chdir(/) after chroot: %s",
1398		    __func__, strerror(errno));
1399	verbose("Changed root directory to \"%s\"", path);
1400}
1401
1402/* Set login name, uid, gid, and groups. */
1403void
1404do_setusercontext(struct passwd *pw)
1405{
1406	char *chroot_path, *tmp;
1407
1408	if (getuid() == 0 || geteuid() == 0) {
1409#ifdef HAVE_LOGIN_CAP
1410# ifdef USE_PAM
1411		if (options.use_pam) {
1412			do_pam_setcred(use_privsep);
1413		}
1414# endif /* USE_PAM */
1415		/* Prepare groups */
1416		if (setusercontext(lc, pw, pw->pw_uid,
1417		    (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
1418			perror("unable to set user context");
1419			exit(1);
1420		}
1421#else
1422
1423		if (setlogin(pw->pw_name) < 0)
1424			error("setlogin failed: %s", strerror(errno));
1425		if (setgid(pw->pw_gid) < 0) {
1426			perror("setgid");
1427			exit(1);
1428		}
1429		/* Initialize the group list. */
1430		if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
1431			perror("initgroups");
1432			exit(1);
1433		}
1434		endgrent();
1435# ifdef USE_PAM
1436		/*
1437		 * PAM credentials may take the form of supplementary groups.
1438		 * These will have been wiped by the above initgroups() call.
1439		 * Reestablish them here.
1440		 */
1441		if (options.use_pam) {
1442			do_pam_setcred(use_privsep);
1443		}
1444# endif /* USE_PAM */
1445#endif
1446		if (options.chroot_directory != NULL &&
1447		    strcasecmp(options.chroot_directory, "none") != 0) {
1448                        tmp = tilde_expand_filename(options.chroot_directory,
1449			    pw->pw_uid);
1450			chroot_path = percent_expand(tmp, "h", pw->pw_dir,
1451			    "u", pw->pw_name, (char *)NULL);
1452			safely_chroot(chroot_path, pw->pw_uid);
1453			free(tmp);
1454			free(chroot_path);
1455		}
1456
1457#ifdef HAVE_LOGIN_CAP
1458		/* Set UID */
1459		if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
1460			perror("unable to set user context (setuser)");
1461			exit(1);
1462		}
1463#else
1464		/* Permanently switch to the desired uid. */
1465		permanently_set_uid(pw);
1466#endif
1467	}
1468	if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1469		fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1470}
1471
1472__dead static void
1473do_pwchange(Session *s)
1474{
1475	fflush(NULL);
1476	fprintf(stderr, "WARNING: Your password has expired.\n");
1477	if (s->ttyfd != -1) {
1478		fprintf(stderr,
1479		    "You must change your password now and login again!\n");
1480		execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
1481		perror("passwd");
1482	} else {
1483		fprintf(stderr,
1484		    "Password change required but no TTY available.\n");
1485	}
1486	exit(1);
1487}
1488
1489__dead static void
1490launch_login(struct passwd *pw, const char *hostname)
1491{
1492	/* Launch login(1). */
1493
1494	execl("/usr/bin/login", "login", "-h", hostname,
1495	    "-p", "-f", "--", pw->pw_name, (char *)NULL);
1496
1497	/* Login couldn't be executed, die. */
1498
1499	perror("login");
1500	exit(1);
1501}
1502
1503static void
1504child_close_fds(void)
1505{
1506	if (packet_get_connection_in() == packet_get_connection_out())
1507		close(packet_get_connection_in());
1508	else {
1509		close(packet_get_connection_in());
1510		close(packet_get_connection_out());
1511	}
1512	/*
1513	 * Close all descriptors related to channels.  They will still remain
1514	 * open in the parent.
1515	 */
1516	/* XXX better use close-on-exec? -markus */
1517	channel_close_all();
1518
1519	/*
1520	 * Close any extra file descriptors.  Note that there may still be
1521	 * descriptors left by system functions.  They will be closed later.
1522	 */
1523	endpwent();
1524
1525	/*
1526	 * Close any extra open file descriptors so that we don't have them
1527	 * hanging around in clients.  Note that we want to do this after
1528	 * initgroups, because at least on Solaris 2.3 it leaves file
1529	 * descriptors open.
1530	 */
1531	closefrom(STDERR_FILENO + 1);
1532}
1533
1534/*
1535 * Performs common processing for the child, such as setting up the
1536 * environment, closing extra file descriptors, setting the user and group
1537 * ids, and executing the command or shell.
1538 */
1539#define ARGV_MAX 10
1540void
1541do_child(Session *s, const char *command)
1542{
1543	extern char **environ;
1544	char **env;
1545	char *argv[ARGV_MAX];
1546	const char *shell, *shell0, *hostname = NULL;
1547	struct passwd *pw = s->pw;
1548	int r = 0;
1549
1550	/* remove hostkey from the child's memory */
1551	destroy_sensitive_data();
1552
1553	/* Force a password change */
1554	if (s->authctxt->force_pwchange) {
1555		do_setusercontext(pw);
1556		child_close_fds();
1557		do_pwchange(s);
1558	}
1559
1560	/* login(1) is only called if we execute the login shell */
1561	if (options.use_login && command != NULL)
1562		options.use_login = 0;
1563
1564	/*
1565	 * Login(1) does this as well, and it needs uid 0 for the "-h"
1566	 * switch, so we let login(1) to this for us.
1567	 */
1568	if (!options.use_login) {
1569		do_nologin(pw);
1570		do_setusercontext(pw);
1571		/*
1572		 * PAM session modules in do_setusercontext may have
1573		 * generated messages, so if this in an interactive
1574		 * login then display them too.
1575		 */
1576		if (!check_quietlogin(s, command))
1577			display_loginmsg();
1578	}
1579#ifdef USE_PAM
1580	if (options.use_pam && !is_pam_session_open()) {
1581		debug3("PAM session not opened, exiting");
1582		display_loginmsg();
1583		exit(254);
1584	}
1585#endif
1586
1587	/*
1588	 * Get the shell from the password data.  An empty shell field is
1589	 * legal, and means /bin/sh.
1590	 */
1591	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1592
1593	/*
1594	 * Make sure $SHELL points to the shell from the password file,
1595	 * even if shell is overridden from login.conf
1596	 */
1597	env = do_setup_env(s, shell);
1598
1599#ifdef HAVE_LOGIN_CAP
1600	shell = login_getcapstr(lc, "shell", __UNCONST(shell),
1601	    __UNCONST(shell));
1602#endif
1603
1604	/* we have to stash the hostname before we close our socket. */
1605	if (options.use_login)
1606		hostname = get_remote_name_or_ip(utmp_len,
1607		    options.use_dns);
1608	/*
1609	 * Close the connection descriptors; note that this is the child, and
1610	 * the server will still have the socket open, and it is important
1611	 * that we do not shutdown it.  Note that the descriptors cannot be
1612	 * closed before building the environment, as we call
1613	 * get_remote_ipaddr there.
1614	 */
1615	child_close_fds();
1616
1617	/*
1618	 * Must take new environment into use so that .ssh/rc,
1619	 * /etc/ssh/sshrc and xauth are run in the proper environment.
1620	 */
1621	environ = env;
1622
1623#ifdef KRB5
1624	/*
1625	 * At this point, we check to see if AFS is active and if we have
1626	 * a valid Kerberos 5 TGT. If so, it seems like a good idea to see
1627	 * if we can (and need to) extend the ticket into an AFS token. If
1628	 * we don't do this, we run into potential problems if the user's
1629	 * home directory is in AFS and it's not world-readable.
1630	 */
1631
1632	if (options.kerberos_get_afs_token && k_hasafs() &&
1633	    (s->authctxt->krb5_ctx != NULL)) {
1634		char cell[64];
1635
1636		debug("Getting AFS token");
1637
1638		k_setpag();
1639
1640		if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1641			krb5_afslog(s->authctxt->krb5_ctx,
1642			    s->authctxt->krb5_fwd_ccache, cell, NULL);
1643
1644		krb5_afslog_home(s->authctxt->krb5_ctx,
1645		    s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
1646	}
1647#endif
1648
1649	/* Change current directory to the user's home directory. */
1650	if (chdir(pw->pw_dir) < 0) {
1651		/* Suppress missing homedir warning for chroot case */
1652		r = login_getcapbool(lc, "requirehome", 0);
1653		if (r || options.chroot_directory == NULL ||
1654		    strcasecmp(options.chroot_directory, "none") == 0)
1655			fprintf(stderr, "Could not chdir to home "
1656			    "directory %s: %s\n", pw->pw_dir,
1657			    strerror(errno));
1658		if (r)
1659			exit(1);
1660	}
1661
1662	closefrom(STDERR_FILENO + 1);
1663
1664	if (!options.use_login)
1665		do_rc_files(s, shell);
1666
1667	/* restore SIGPIPE for child */
1668	signal(SIGPIPE, SIG_DFL);
1669
1670	if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) {
1671		printf("This service allows sftp connections only.\n");
1672		fflush(NULL);
1673		exit(1);
1674	} else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
1675		extern int optind, optreset;
1676		int i;
1677		char *p, *args;
1678
1679		setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME);
1680		args = xstrdup(command ? command : "sftp-server");
1681		for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
1682			if (i < ARGV_MAX - 1)
1683				argv[i++] = p;
1684		argv[i] = NULL;
1685		optind = optreset = 1;
1686		__progname = argv[0];
1687		exit(sftp_server_main(i, argv, s->pw));
1688	}
1689
1690	fflush(NULL);
1691
1692	if (options.use_login) {
1693		launch_login(pw, hostname);
1694		/* NEVERREACHED */
1695	}
1696
1697	/* Get the last component of the shell name. */
1698	if ((shell0 = strrchr(shell, '/')) != NULL)
1699		shell0++;
1700	else
1701		shell0 = shell;
1702
1703	/*
1704	 * If we have no command, execute the shell.  In this case, the shell
1705	 * name to be passed in argv[0] is preceded by '-' to indicate that
1706	 * this is a login shell.
1707	 */
1708	if (!command) {
1709		char argv0[256];
1710
1711		/* Start the shell.  Set initial character to '-'. */
1712		argv0[0] = '-';
1713
1714		if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
1715		    >= sizeof(argv0) - 1) {
1716			errno = EINVAL;
1717			perror(shell);
1718			exit(1);
1719		}
1720
1721		/* Execute the shell. */
1722		argv[0] = argv0;
1723		argv[1] = NULL;
1724		execve(shell, argv, env);
1725
1726		/* Executing the shell failed. */
1727		perror(shell);
1728		exit(1);
1729	}
1730	/*
1731	 * Execute the command using the user's shell.  This uses the -c
1732	 * option to execute the command.
1733	 */
1734	argv[0] = __UNCONST(shell0);
1735	argv[1] = __UNCONST("-c");
1736	argv[2] = __UNCONST(command);
1737	argv[3] = NULL;
1738	execve(shell, argv, env);
1739	perror(shell);
1740	exit(1);
1741}
1742
1743void
1744session_unused(int id)
1745{
1746	debug3("%s: session id %d unused", __func__, id);
1747	if (id >= options.max_sessions ||
1748	    id >= sessions_nalloc) {
1749		fatal("%s: insane session id %d (max %d nalloc %d)",
1750		    __func__, id, options.max_sessions, sessions_nalloc);
1751	}
1752	bzero(&sessions[id], sizeof(*sessions));
1753	sessions[id].self = id;
1754	sessions[id].used = 0;
1755	sessions[id].chanid = -1;
1756	sessions[id].ptyfd = -1;
1757	sessions[id].ttyfd = -1;
1758	sessions[id].ptymaster = -1;
1759	sessions[id].x11_chanids = NULL;
1760	sessions[id].next_unused = sessions_first_unused;
1761	sessions_first_unused = id;
1762}
1763
1764Session *
1765session_new(void)
1766{
1767	Session *s, *tmp;
1768
1769	if (sessions_first_unused == -1) {
1770		if (sessions_nalloc >= options.max_sessions)
1771			return NULL;
1772		debug2("%s: allocate (allocated %d max %d)",
1773		    __func__, sessions_nalloc, options.max_sessions);
1774		tmp = xrealloc(sessions, sessions_nalloc + 1,
1775		    sizeof(*sessions));
1776		if (tmp == NULL) {
1777			error("%s: cannot allocate %d sessions",
1778			    __func__, sessions_nalloc + 1);
1779			return NULL;
1780		}
1781		sessions = tmp;
1782		session_unused(sessions_nalloc++);
1783	}
1784
1785	if (sessions_first_unused >= sessions_nalloc ||
1786	    sessions_first_unused < 0) {
1787		fatal("%s: insane first_unused %d max %d nalloc %d",
1788		    __func__, sessions_first_unused, options.max_sessions,
1789		    sessions_nalloc);
1790	}
1791
1792	s = &sessions[sessions_first_unused];
1793	if (s->used) {
1794		fatal("%s: session %d already used",
1795		    __func__, sessions_first_unused);
1796	}
1797	sessions_first_unused = s->next_unused;
1798	s->used = 1;
1799	s->next_unused = -1;
1800	debug("session_new: session %d", s->self);
1801
1802	return s;
1803}
1804
1805static void
1806session_dump(void)
1807{
1808	int i;
1809	for (i = 0; i < sessions_nalloc; i++) {
1810		Session *s = &sessions[i];
1811
1812		debug("dump: used %d next_unused %d session %d %p "
1813		    "channel %d pid %ld",
1814		    s->used,
1815		    s->next_unused,
1816		    s->self,
1817		    s,
1818		    s->chanid,
1819		    (long)s->pid);
1820	}
1821}
1822
1823int
1824session_open(Authctxt *authctxt, int chanid)
1825{
1826	Session *s = session_new();
1827	debug("session_open: channel %d", chanid);
1828	if (s == NULL) {
1829		error("no more sessions");
1830		return 0;
1831	}
1832	s->authctxt = authctxt;
1833	s->pw = authctxt->pw;
1834	if (s->pw == NULL || !authctxt->valid)
1835		fatal("no user for session %d", s->self);
1836	debug("session_open: session %d: link with channel %d", s->self, chanid);
1837	s->chanid = chanid;
1838	return 1;
1839}
1840
1841Session *
1842session_by_tty(char *tty)
1843{
1844	int i;
1845	for (i = 0; i < sessions_nalloc; i++) {
1846		Session *s = &sessions[i];
1847		if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
1848			debug("session_by_tty: session %d tty %s", i, tty);
1849			return s;
1850		}
1851	}
1852	debug("session_by_tty: unknown tty %.100s", tty);
1853	session_dump();
1854	return NULL;
1855}
1856
1857static Session *
1858session_by_channel(int id)
1859{
1860	int i;
1861	for (i = 0; i < sessions_nalloc; i++) {
1862		Session *s = &sessions[i];
1863		if (s->used && s->chanid == id) {
1864			debug("session_by_channel: session %d channel %d",
1865			    i, id);
1866			return s;
1867		}
1868	}
1869	debug("session_by_channel: unknown channel %d", id);
1870	session_dump();
1871	return NULL;
1872}
1873
1874static Session *
1875session_by_x11_channel(int id)
1876{
1877	int i, j;
1878
1879	for (i = 0; i < sessions_nalloc; i++) {
1880		Session *s = &sessions[i];
1881
1882		if (s->x11_chanids == NULL || !s->used)
1883			continue;
1884		for (j = 0; s->x11_chanids[j] != -1; j++) {
1885			if (s->x11_chanids[j] == id) {
1886				debug("session_by_x11_channel: session %d "
1887				    "channel %d", s->self, id);
1888				return s;
1889			}
1890		}
1891	}
1892	debug("session_by_x11_channel: unknown channel %d", id);
1893	session_dump();
1894	return NULL;
1895}
1896
1897static Session *
1898session_by_pid(pid_t pid)
1899{
1900	int i;
1901	debug("session_by_pid: pid %ld", (long)pid);
1902	for (i = 0; i < sessions_nalloc; i++) {
1903		Session *s = &sessions[i];
1904		if (s->used && s->pid == pid)
1905			return s;
1906	}
1907	error("session_by_pid: unknown pid %ld", (long)pid);
1908	session_dump();
1909	return NULL;
1910}
1911
1912static int
1913session_window_change_req(Session *s)
1914{
1915	s->col = packet_get_int();
1916	s->row = packet_get_int();
1917	s->xpixel = packet_get_int();
1918	s->ypixel = packet_get_int();
1919	packet_check_eom();
1920	pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1921	return 1;
1922}
1923
1924static int
1925session_pty_req(Session *s)
1926{
1927	u_int len;
1928	int n_bytes;
1929
1930	if (no_pty_flag) {
1931		debug("Allocating a pty not permitted for this authentication.");
1932		return 0;
1933	}
1934	if (s->ttyfd != -1) {
1935		packet_disconnect("Protocol error: you already have a pty.");
1936		return 0;
1937	}
1938
1939	s->term = packet_get_string(&len);
1940
1941	if (compat20) {
1942		s->col = packet_get_int();
1943		s->row = packet_get_int();
1944	} else {
1945		s->row = packet_get_int();
1946		s->col = packet_get_int();
1947	}
1948	s->xpixel = packet_get_int();
1949	s->ypixel = packet_get_int();
1950
1951	if (strcmp(s->term, "") == 0) {
1952		xfree(s->term);
1953		s->term = NULL;
1954	}
1955
1956	/* Allocate a pty and open it. */
1957	debug("Allocating pty.");
1958	if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
1959	    sizeof(s->tty)))) {
1960		if (s->term)
1961			xfree(s->term);
1962		s->term = NULL;
1963		s->ptyfd = -1;
1964		s->ttyfd = -1;
1965		error("session_pty_req: session %d alloc failed", s->self);
1966		return 0;
1967	}
1968	debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1969
1970	/* for SSH1 the tty modes length is not given */
1971	if (!compat20)
1972		n_bytes = packet_remaining();
1973	tty_parse_modes(s->ttyfd, &n_bytes);
1974
1975	if (!use_privsep)
1976		pty_setowner(s->pw, s->tty);
1977
1978	/* Set window size from the packet. */
1979	pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1980
1981	packet_check_eom();
1982	session_proctitle(s);
1983	return 1;
1984}
1985
1986static int
1987session_subsystem_req(Session *s)
1988{
1989	struct stat st;
1990	u_int len;
1991	int success = 0;
1992	char *prog, *cmd, *subsys = packet_get_string(&len);
1993	u_int i;
1994
1995	packet_check_eom();
1996	logit("subsystem request for %.100s by user %s", subsys,
1997	    s->pw->pw_name);
1998
1999	for (i = 0; i < options.num_subsystems; i++) {
2000		if (strcmp(subsys, options.subsystem_name[i]) == 0) {
2001			prog = options.subsystem_command[i];
2002			cmd = options.subsystem_args[i];
2003			if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) {
2004				s->is_subsystem = SUBSYSTEM_INT_SFTP;
2005				debug("subsystem: %s", prog);
2006			} else {
2007				if (stat(prog, &st) < 0)
2008					debug("subsystem: cannot stat %s: %s",
2009					    prog, strerror(errno));
2010				s->is_subsystem = SUBSYSTEM_EXT;
2011				debug("subsystem: exec() %s", cmd);
2012			}
2013			success = do_exec(s, cmd) == 0;
2014			break;
2015		}
2016	}
2017
2018	if (!success)
2019		logit("subsystem request for %.100s failed, subsystem not found",
2020		    subsys);
2021
2022	xfree(subsys);
2023	return success;
2024}
2025
2026static int
2027session_x11_req(Session *s)
2028{
2029	int success;
2030
2031	if (s->auth_proto != NULL || s->auth_data != NULL) {
2032		error("session_x11_req: session %d: "
2033		    "x11 forwarding already active", s->self);
2034		return 0;
2035	}
2036	s->single_connection = packet_get_char();
2037	s->auth_proto = packet_get_string(NULL);
2038	s->auth_data = packet_get_string(NULL);
2039	s->screen = packet_get_int();
2040	packet_check_eom();
2041
2042	success = session_setup_x11fwd(s);
2043	if (!success) {
2044		xfree(s->auth_proto);
2045		xfree(s->auth_data);
2046		s->auth_proto = NULL;
2047		s->auth_data = NULL;
2048	}
2049	return success;
2050}
2051
2052static int
2053session_shell_req(Session *s)
2054{
2055	packet_check_eom();
2056	return do_exec(s, NULL) == 0;
2057}
2058
2059static int
2060session_exec_req(Session *s)
2061{
2062	u_int len, success;
2063
2064	char *command = packet_get_string(&len);
2065	packet_check_eom();
2066	success = do_exec(s, command) == 0;
2067	xfree(command);
2068	return success;
2069}
2070
2071static int
2072session_break_req(Session *s)
2073{
2074
2075	packet_get_int();	/* ignored */
2076	packet_check_eom();
2077
2078	if (s->ttyfd == -1 || tcsendbreak(s->ttyfd, 0) < 0)
2079		return 0;
2080	return 1;
2081}
2082
2083static int
2084session_env_req(Session *s)
2085{
2086	char *name, *val;
2087	u_int name_len, val_len, i;
2088
2089	name = packet_get_string(&name_len);
2090	val = packet_get_string(&val_len);
2091	packet_check_eom();
2092
2093	/* Don't set too many environment variables */
2094	if (s->num_env > 128) {
2095		debug2("Ignoring env request %s: too many env vars", name);
2096		goto fail;
2097	}
2098
2099	for (i = 0; i < options.num_accept_env; i++) {
2100		if (match_pattern(name, options.accept_env[i])) {
2101			debug2("Setting env %d: %s=%s", s->num_env, name, val);
2102			s->env = xrealloc(s->env, s->num_env + 1,
2103			    sizeof(*s->env));
2104			s->env[s->num_env].name = name;
2105			s->env[s->num_env].val = val;
2106			s->num_env++;
2107			return (1);
2108		}
2109	}
2110	debug2("Ignoring env request %s: disallowed name", name);
2111
2112 fail:
2113	xfree(name);
2114	xfree(val);
2115	return (0);
2116}
2117
2118static int
2119session_auth_agent_req(Session *s)
2120{
2121	static int called = 0;
2122	packet_check_eom();
2123	if (no_agent_forwarding_flag || !options.allow_agent_forwarding) {
2124		debug("session_auth_agent_req: no_agent_forwarding_flag");
2125		return 0;
2126	}
2127	if (called) {
2128		return 0;
2129	} else {
2130		called = 1;
2131		return auth_input_request_forwarding(s->pw);
2132	}
2133}
2134
2135int
2136session_input_channel_req(Channel *c, const char *rtype)
2137{
2138	int success = 0;
2139	Session *s;
2140
2141	if ((s = session_by_channel(c->self)) == NULL) {
2142		logit("session_input_channel_req: no session %d req %.100s",
2143		    c->self, rtype);
2144		return 0;
2145	}
2146	debug("session_input_channel_req: session %d req %s", s->self, rtype);
2147
2148	/*
2149	 * a session is in LARVAL state until a shell, a command
2150	 * or a subsystem is executed
2151	 */
2152	if (c->type == SSH_CHANNEL_LARVAL) {
2153		if (strcmp(rtype, "shell") == 0) {
2154			success = session_shell_req(s);
2155		} else if (strcmp(rtype, "exec") == 0) {
2156			success = session_exec_req(s);
2157		} else if (strcmp(rtype, "pty-req") == 0) {
2158			success = session_pty_req(s);
2159		} else if (strcmp(rtype, "x11-req") == 0) {
2160			success = session_x11_req(s);
2161		} else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
2162			success = session_auth_agent_req(s);
2163		} else if (strcmp(rtype, "subsystem") == 0) {
2164			success = session_subsystem_req(s);
2165		} else if (strcmp(rtype, "env") == 0) {
2166			success = session_env_req(s);
2167		}
2168	}
2169	if (strcmp(rtype, "window-change") == 0) {
2170		success = session_window_change_req(s);
2171	} else if (strcmp(rtype, "break") == 0) {
2172		success = session_break_req(s);
2173	}
2174
2175	return success;
2176}
2177
2178void
2179session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
2180    int is_tty)
2181{
2182	if (!compat20)
2183		fatal("session_set_fds: called for proto != 2.0");
2184	/*
2185	 * now that have a child and a pipe to the child,
2186	 * we can activate our channel and register the fd's
2187	 */
2188	if (s->chanid == -1)
2189		fatal("no channel for session %d", s->self);
2190	if(options.hpn_disabled)
2191	channel_set_fds(s->chanid,
2192	    fdout, fdin, fderr,
2193	    ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2194	    1, is_tty, CHAN_SES_WINDOW_DEFAULT);
2195	else
2196		channel_set_fds(s->chanid,
2197		    fdout, fdin, fderr,
2198	            ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2199		    1, is_tty, options.hpn_buffer_size);
2200}
2201
2202/*
2203 * Function to perform pty cleanup. Also called if we get aborted abnormally
2204 * (e.g., due to a dropped connection).
2205 */
2206void
2207session_pty_cleanup2(Session *s)
2208{
2209	if (s == NULL) {
2210		error("session_pty_cleanup: no session");
2211		return;
2212	}
2213	if (s->ttyfd == -1)
2214		return;
2215
2216	debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
2217
2218	/* Record that the user has logged out. */
2219	if (s->pid != 0)
2220		record_logout(s->pid, s->tty);
2221
2222	/* Release the pseudo-tty. */
2223	if (getuid() == 0)
2224		pty_release(s->tty);
2225
2226	/*
2227	 * Close the server side of the socket pairs.  We must do this after
2228	 * the pty cleanup, so that another process doesn't get this pty
2229	 * while we're still cleaning up.
2230	 */
2231	if (s->ptymaster != -1 && close(s->ptymaster) < 0)
2232		error("close(s->ptymaster/%d): %s",
2233		    s->ptymaster, strerror(errno));
2234
2235	/* unlink pty from session */
2236	s->ttyfd = -1;
2237}
2238
2239void
2240session_pty_cleanup(Session *s)
2241{
2242	PRIVSEP(session_pty_cleanup2(s));
2243}
2244
2245static const char *
2246sig2name(int sig)
2247{
2248#define SSH_SIG(x) if (sig == SIG ## x) return #x
2249	SSH_SIG(ABRT);
2250	SSH_SIG(ALRM);
2251	SSH_SIG(FPE);
2252	SSH_SIG(HUP);
2253	SSH_SIG(ILL);
2254	SSH_SIG(INT);
2255	SSH_SIG(KILL);
2256	SSH_SIG(PIPE);
2257	SSH_SIG(QUIT);
2258	SSH_SIG(SEGV);
2259	SSH_SIG(TERM);
2260	SSH_SIG(USR1);
2261	SSH_SIG(USR2);
2262#undef	SSH_SIG
2263	return "SIG@openssh.com";
2264}
2265
2266static void
2267session_close_x11(int id)
2268{
2269	Channel *c;
2270
2271	if ((c = channel_by_id(id)) == NULL) {
2272		debug("session_close_x11: x11 channel %d missing", id);
2273	} else {
2274		/* Detach X11 listener */
2275		debug("session_close_x11: detach x11 channel %d", id);
2276		channel_cancel_cleanup(id);
2277		if (c->ostate != CHAN_OUTPUT_CLOSED)
2278			chan_mark_dead(c);
2279	}
2280}
2281
2282static void
2283session_close_single_x11(int id, void *arg)
2284{
2285	Session *s;
2286	u_int i;
2287
2288	debug3("session_close_single_x11: channel %d", id);
2289	channel_cancel_cleanup(id);
2290	if ((s = session_by_x11_channel(id)) == NULL)
2291		fatal("session_close_single_x11: no x11 channel %d", id);
2292	for (i = 0; s->x11_chanids[i] != -1; i++) {
2293		debug("session_close_single_x11: session %d: "
2294		    "closing channel %d", s->self, s->x11_chanids[i]);
2295		/*
2296		 * The channel "id" is already closing, but make sure we
2297		 * close all of its siblings.
2298		 */
2299		if (s->x11_chanids[i] != id)
2300			session_close_x11(s->x11_chanids[i]);
2301	}
2302	xfree(s->x11_chanids);
2303	s->x11_chanids = NULL;
2304	if (s->display) {
2305		xfree(s->display);
2306		s->display = NULL;
2307	}
2308	if (s->auth_proto) {
2309		xfree(s->auth_proto);
2310		s->auth_proto = NULL;
2311	}
2312	if (s->auth_data) {
2313		xfree(s->auth_data);
2314		s->auth_data = NULL;
2315	}
2316	if (s->auth_display) {
2317		xfree(s->auth_display);
2318		s->auth_display = NULL;
2319	}
2320}
2321
2322static void
2323session_exit_message(Session *s, int status)
2324{
2325	Channel *c;
2326
2327	if ((c = channel_lookup(s->chanid)) == NULL)
2328		fatal("session_exit_message: session %d: no channel %d",
2329		    s->self, s->chanid);
2330	debug("session_exit_message: session %d channel %d pid %ld",
2331	    s->self, s->chanid, (long)s->pid);
2332
2333	if (WIFEXITED(status)) {
2334		channel_request_start(s->chanid, "exit-status", 0);
2335		packet_put_int(WEXITSTATUS(status));
2336		packet_send();
2337	} else if (WIFSIGNALED(status)) {
2338		channel_request_start(s->chanid, "exit-signal", 0);
2339		packet_put_cstring(sig2name(WTERMSIG(status)));
2340		packet_put_char(WCOREDUMP(status)? 1 : 0);
2341		packet_put_cstring("");
2342		packet_put_cstring("");
2343		packet_send();
2344	} else {
2345		/* Some weird exit cause.  Just exit. */
2346		packet_disconnect("wait returned status %04x.", status);
2347	}
2348
2349	/* disconnect channel */
2350	debug("session_exit_message: release channel %d", s->chanid);
2351
2352	/*
2353	 * Adjust cleanup callback attachment to send close messages when
2354	 * the channel gets EOF. The session will be then be closed
2355	 * by session_close_by_channel when the childs close their fds.
2356	 */
2357	channel_register_cleanup(c->self, session_close_by_channel, 1);
2358
2359	/*
2360	 * emulate a write failure with 'chan_write_failed', nobody will be
2361	 * interested in data we write.
2362	 * Note that we must not call 'chan_read_failed', since there could
2363	 * be some more data waiting in the pipe.
2364	 */
2365	if (c->ostate != CHAN_OUTPUT_CLOSED)
2366		chan_write_failed(c);
2367}
2368
2369void
2370session_close(Session *s)
2371{
2372	u_int i;
2373
2374	debug("session_close: session %d pid %ld", s->self, (long)s->pid);
2375	if (s->ttyfd != -1)
2376		session_pty_cleanup(s);
2377	if (s->term)
2378		xfree(s->term);
2379	if (s->display)
2380		xfree(s->display);
2381	if (s->x11_chanids)
2382		xfree(s->x11_chanids);
2383	if (s->auth_display)
2384		xfree(s->auth_display);
2385	if (s->auth_data)
2386		xfree(s->auth_data);
2387	if (s->auth_proto)
2388		xfree(s->auth_proto);
2389	if (s->env != NULL) {
2390		for (i = 0; i < s->num_env; i++) {
2391			xfree(s->env[i].name);
2392			xfree(s->env[i].val);
2393		}
2394		xfree(s->env);
2395	}
2396	session_proctitle(s);
2397	session_unused(s->self);
2398}
2399
2400void
2401session_close_by_pid(pid_t pid, int status)
2402{
2403	Session *s = session_by_pid(pid);
2404	if (s == NULL) {
2405		debug("session_close_by_pid: no session for pid %ld",
2406		    (long)pid);
2407		return;
2408	}
2409	if (s->chanid != -1)
2410		session_exit_message(s, status);
2411	if (s->ttyfd != -1)
2412		session_pty_cleanup(s);
2413	s->pid = 0;
2414}
2415
2416/*
2417 * this is called when a channel dies before
2418 * the session 'child' itself dies
2419 */
2420void
2421session_close_by_channel(int id, void *arg)
2422{
2423	Session *s = session_by_channel(id);
2424	u_int i;
2425
2426	if (s == NULL) {
2427		debug("session_close_by_channel: no session for id %d", id);
2428		return;
2429	}
2430	debug("session_close_by_channel: channel %d child %ld",
2431	    id, (long)s->pid);
2432	if (s->pid != 0) {
2433		debug("session_close_by_channel: channel %d: has child", id);
2434		/*
2435		 * delay detach of session, but release pty, since
2436		 * the fd's to the child are already closed
2437		 */
2438		if (s->ttyfd != -1)
2439			session_pty_cleanup(s);
2440		return;
2441	}
2442	/* detach by removing callback */
2443	channel_cancel_cleanup(s->chanid);
2444
2445	/* Close any X11 listeners associated with this session */
2446	if (s->x11_chanids != NULL) {
2447		for (i = 0; s->x11_chanids[i] != -1; i++) {
2448			session_close_x11(s->x11_chanids[i]);
2449			s->x11_chanids[i] = -1;
2450		}
2451	}
2452
2453	s->chanid = -1;
2454	session_close(s);
2455}
2456
2457void
2458session_destroy_all(void (*closefunc)(Session *))
2459{
2460	int i;
2461	for (i = 0; i < sessions_nalloc; i++) {
2462		Session *s = &sessions[i];
2463		if (s->used) {
2464			if (closefunc != NULL)
2465				closefunc(s);
2466			else
2467				session_close(s);
2468		}
2469	}
2470}
2471
2472static char *
2473session_tty_list(void)
2474{
2475	static char buf[1024];
2476	int i;
2477	buf[0] = '\0';
2478	for (i = 0; i < sessions_nalloc; i++) {
2479		Session *s = &sessions[i];
2480		if (s->used && s->ttyfd != -1) {
2481			char *p;
2482			if (buf[0] != '\0')
2483				strlcat(buf, ",", sizeof buf);
2484			if ((p = strstr(s->tty, "/pts/")) != NULL)
2485				p++;
2486			else {
2487				if ((p = strrchr(s->tty, '/')) != NULL)
2488					p++;
2489				else
2490					p = s->tty;
2491			}
2492			strlcat(buf, p, sizeof buf);
2493		}
2494	}
2495	if (buf[0] == '\0')
2496		strlcpy(buf, "notty", sizeof buf);
2497	return buf;
2498}
2499
2500void
2501session_proctitle(Session *s)
2502{
2503	if (s->pw == NULL)
2504		error("no user for session %d", s->self);
2505	else
2506		setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
2507}
2508
2509int
2510session_setup_x11fwd(Session *s)
2511{
2512	struct stat st;
2513	char display[512], auth_display[512];
2514	char hostname[MAXHOSTNAMELEN];
2515	u_int i;
2516
2517	if (no_x11_forwarding_flag) {
2518		packet_send_debug("X11 forwarding disabled in user configuration file.");
2519		return 0;
2520	}
2521	if (!options.x11_forwarding) {
2522		debug("X11 forwarding disabled in server configuration file.");
2523		return 0;
2524	}
2525	if (!options.xauth_location ||
2526	    (stat(options.xauth_location, &st) == -1)) {
2527		packet_send_debug("No xauth program; cannot forward with spoofing.");
2528		return 0;
2529	}
2530	if (options.use_login) {
2531		packet_send_debug("X11 forwarding disabled; "
2532		    "not compatible with UseLogin=yes.");
2533		return 0;
2534	}
2535	if (s->display != NULL) {
2536		debug("X11 display already set.");
2537		return 0;
2538	}
2539	if (x11_create_display_inet(options.x11_display_offset,
2540	    options.x11_use_localhost, s->single_connection,
2541	    &s->display_number, &s->x11_chanids) == -1) {
2542		debug("x11_create_display_inet failed.");
2543		return 0;
2544	}
2545	for (i = 0; s->x11_chanids[i] != -1; i++) {
2546		channel_register_cleanup(s->x11_chanids[i],
2547		    session_close_single_x11, 0);
2548	}
2549
2550	/* Set up a suitable value for the DISPLAY variable. */
2551	if (gethostname(hostname, sizeof(hostname)) < 0)
2552		fatal("gethostname: %.100s", strerror(errno));
2553	/*
2554	 * auth_display must be used as the displayname when the
2555	 * authorization entry is added with xauth(1).  This will be
2556	 * different than the DISPLAY string for localhost displays.
2557	 */
2558	if (options.x11_use_localhost) {
2559		snprintf(display, sizeof display, "localhost:%u.%u",
2560		    s->display_number, s->screen);
2561		snprintf(auth_display, sizeof auth_display, "unix:%u.%u",
2562		    s->display_number, s->screen);
2563		s->display = xstrdup(display);
2564		s->auth_display = xstrdup(auth_display);
2565	} else {
2566		snprintf(display, sizeof display, "%.400s:%u.%u", hostname,
2567		    s->display_number, s->screen);
2568		s->display = xstrdup(display);
2569		s->auth_display = xstrdup(display);
2570	}
2571
2572	return 1;
2573}
2574
2575static void
2576do_authenticated2(Authctxt *authctxt)
2577{
2578	server_loop2(authctxt);
2579}
2580
2581void
2582do_cleanup(Authctxt *authctxt)
2583{
2584	static int called = 0;
2585
2586	debug("do_cleanup");
2587
2588	/* no cleanup if we're in the child for login shell */
2589	if (is_child)
2590		return;
2591
2592	/* avoid double cleanup */
2593	if (called)
2594		return;
2595	called = 1;
2596
2597	if (authctxt == NULL || !authctxt->authenticated)
2598		return;
2599#ifdef KRB4
2600	if (options.kerberos_ticket_cleanup)
2601		krb4_cleanup_proc(authctxt);
2602#endif
2603#ifdef KRB5
2604	if (options.kerberos_ticket_cleanup &&
2605	    authctxt->krb5_ctx)
2606		krb5_cleanup_proc(authctxt);
2607#endif
2608
2609#ifdef GSSAPI
2610	if (compat20 && options.gss_cleanup_creds)
2611		ssh_gssapi_cleanup_creds();
2612#endif
2613
2614#ifdef USE_PAM
2615	if (options.use_pam) {
2616		sshpam_cleanup();
2617		sshpam_thread_cleanup();
2618	}
2619#endif
2620
2621	/* remove agent socket */
2622	auth_sock_cleanup_proc(authctxt->pw);
2623
2624	/*
2625	 * Cleanup ptys/utmp only if privsep is disabled,
2626	 * or if running in monitor.
2627	 */
2628	if (!use_privsep || mm_is_monitor())
2629		session_destroy_all(session_pty_cleanup2);
2630}
2631