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