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