session.c revision 76262
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 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.74 2001/04/17 19:34:25 markus Exp $");
37RCSID("$FreeBSD: head/crypto/openssh/session.c 76262 2001-05-04 04:14:23Z green $");
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 "mpaux.h"
47#include "uidswap.h"
48#include "compat.h"
49#include "channels.h"
50#include "nchan.h"
51#include "bufaux.h"
52#include "auth.h"
53#include "auth-options.h"
54#include "pathnames.h"
55#include "log.h"
56#include "servconf.h"
57#include "sshlogin.h"
58#include "serverloop.h"
59#include "canohost.h"
60#include "session.h"
61
62#ifdef __FreeBSD__
63#define _PATH_CHPASS "/usr/bin/passwd"
64#endif /* __FreeBSD__ */
65
66#ifdef HAVE_LOGIN_CAP
67#include <login_cap.h>
68#endif
69
70#ifdef KRB5
71extern krb5_context ssh_context;
72#endif
73
74/* types */
75
76#define TTYSZ 64
77typedef struct Session Session;
78struct Session {
79	int	used;
80	int	self;
81	struct	passwd *pw;
82	pid_t	pid;
83	/* tty */
84	char	*term;
85	int	ptyfd, ttyfd, ptymaster;
86	int	row, col, xpixel, ypixel;
87	char	tty[TTYSZ];
88	/* X11 */
89	char	*display;
90	int	screen;
91	char	*auth_proto;
92	char	*auth_data;
93	int	single_connection;
94	/* proto 2 */
95	int	chanid;
96	int	is_subsystem;
97};
98
99/* func */
100
101Session *session_new(void);
102void	session_set_fds(Session *s, int fdin, int fdout, int fderr);
103void	session_pty_cleanup(Session *s);
104void	session_proctitle(Session *s);
105void	do_exec_pty(Session *s, const char *command);
106void	do_exec_no_pty(Session *s, const char *command);
107void	do_login(Session *s, const char *command);
108void	do_child(Session *s, const char *command);
109void	do_motd(void);
110int	check_quietlogin(Session *s, const char *command);
111
112void	do_authenticated1(Authctxt *authctxt);
113void	do_authenticated2(Authctxt *authctxt);
114
115/* import */
116extern ServerOptions options;
117extern char *__progname;
118extern int log_stderr;
119extern int debug_flag;
120extern u_int utmp_len;
121extern int startup_pipe;
122extern void destroy_sensitive_data(void);
123
124/* Local Xauthority file. */
125static char *xauthfile;
126
127/* original command from peer. */
128char *original_command = NULL;
129
130/* data */
131#define MAX_SESSIONS 10
132Session	sessions[MAX_SESSIONS];
133
134#ifdef HAVE_LOGIN_CAP
135static login_cap_t *lc;
136#endif
137
138void
139do_authenticated(Authctxt *authctxt)
140{
141	/*
142	 * Cancel the alarm we set to limit the time taken for
143	 * authentication.
144	 */
145	alarm(0);
146	if (startup_pipe != -1) {
147		close(startup_pipe);
148		startup_pipe = -1;
149	}
150#ifdef HAVE_LOGIN_CAP
151	if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
152		error("unable to get login class");
153		return;
154	}
155#ifdef BSD_AUTH
156	if (auth_approval(NULL, lc, authctxt->pw->pw_name, "ssh") <= 0) {
157		packet_disconnect("Approval failure for %s",
158		    authctxt->pw->pw_name);
159	}
160#endif
161#endif
162	/* setup the channel layer */
163	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
164		channel_permit_all_opens();
165
166	if (compat20)
167		do_authenticated2(authctxt);
168	else
169		do_authenticated1(authctxt);
170}
171
172/*
173 * Remove local Xauthority file.
174 */
175void
176xauthfile_cleanup_proc(void *ignore)
177{
178	debug("xauthfile_cleanup_proc called");
179
180	if (xauthfile != NULL) {
181		char *p;
182		unlink(xauthfile);
183		p = strrchr(xauthfile, '/');
184		if (p != NULL) {
185			*p = '\0';
186			rmdir(xauthfile);
187		}
188		xfree(xauthfile);
189		xauthfile = NULL;
190	}
191}
192
193/*
194 * Function to perform cleanup if we get aborted abnormally (e.g., due to a
195 * dropped connection).
196 */
197void
198pty_cleanup_proc(void *session)
199{
200	Session *s=session;
201	if (s == NULL)
202		fatal("pty_cleanup_proc: no session");
203	debug("pty_cleanup_proc: %s", s->tty);
204
205	if (s->pid != 0) {
206		/* Record that the user has logged out. */
207		record_logout(s->pid, s->tty);
208	}
209
210	/* Release the pseudo-tty. */
211	pty_release(s->tty);
212}
213
214/*
215 * Prepares for an interactive session.  This is called after the user has
216 * been successfully authenticated.  During this message exchange, pseudo
217 * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
218 * are requested, etc.
219 */
220void
221do_authenticated1(Authctxt *authctxt)
222{
223	Session *s;
224	char *command;
225	int success, type, fd, n_bytes, plen, screen_flag, have_pty = 0;
226	int compression_level = 0, enable_compression_after_reply = 0;
227	u_int proto_len, data_len, dlen;
228
229	s = session_new();
230	s->pw = authctxt->pw;
231
232	/*
233	 * We stay in this loop until the client requests to execute a shell
234	 * or a command.
235	 */
236	for (;;) {
237		success = 0;
238
239		/* Get a packet from the client. */
240		type = packet_read(&plen);
241
242		/* Process the packet. */
243		switch (type) {
244		case SSH_CMSG_REQUEST_COMPRESSION:
245			packet_integrity_check(plen, 4, type);
246			compression_level = packet_get_int();
247			if (compression_level < 1 || compression_level > 9) {
248				packet_send_debug("Received illegal compression level %d.",
249				     compression_level);
250				break;
251			}
252			/* Enable compression after we have responded with SUCCESS. */
253			enable_compression_after_reply = 1;
254			success = 1;
255			break;
256
257		case SSH_CMSG_REQUEST_PTY:
258			if (no_pty_flag) {
259				debug("Allocating a pty not permitted for this authentication.");
260				break;
261			}
262			if (have_pty)
263				packet_disconnect("Protocol error: you already have a pty.");
264
265			debug("Allocating pty.");
266
267			/* Allocate a pty and open it. */
268			if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
269			    sizeof(s->tty))) {
270				error("Failed to allocate pty.");
271				break;
272			}
273			fatal_add_cleanup(pty_cleanup_proc, (void *)s);
274			pty_setowner(s->pw, s->tty);
275
276			/* Get TERM from the packet.  Note that the value may be of arbitrary length. */
277			s->term = packet_get_string(&dlen);
278			packet_integrity_check(dlen, strlen(s->term), type);
279			/* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */
280			/* Remaining bytes */
281			n_bytes = plen - (4 + dlen + 4 * 4);
282
283			if (strcmp(s->term, "") == 0) {
284				xfree(s->term);
285				s->term = NULL;
286			}
287			/* Get window size from the packet. */
288			s->row = packet_get_int();
289			s->col = packet_get_int();
290			s->xpixel = packet_get_int();
291			s->ypixel = packet_get_int();
292			pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
293
294			/* Get tty modes from the packet. */
295			tty_parse_modes(s->ttyfd, &n_bytes);
296			packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type);
297
298			session_proctitle(s);
299
300			/* Indicate that we now have a pty. */
301			success = 1;
302			have_pty = 1;
303			break;
304
305		case SSH_CMSG_X11_REQUEST_FORWARDING:
306			if (!options.x11_forwarding) {
307				packet_send_debug("X11 forwarding disabled in server configuration file.");
308				break;
309			}
310			if (!options.xauth_location) {
311				packet_send_debug("No xauth program; cannot forward with spoofing.");
312				break;
313			}
314			if (no_x11_forwarding_flag) {
315				packet_send_debug("X11 forwarding not permitted for this authentication.");
316				break;
317			}
318			debug("Received request for X11 forwarding with auth spoofing.");
319			if (s->display != NULL)
320				packet_disconnect("Protocol error: X11 display already set.");
321
322			s->auth_proto = packet_get_string(&proto_len);
323			s->auth_data = packet_get_string(&data_len);
324
325			screen_flag = packet_get_protocol_flags() &
326			    SSH_PROTOFLAG_SCREEN_NUMBER;
327			debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
328
329			if (packet_remaining() == 4) {
330				if (!screen_flag)
331					debug2("Buggy client: "
332					    "X11 screen flag missing");
333				packet_integrity_check(plen,
334				    4 + proto_len + 4 + data_len + 4, type);
335				s->screen = packet_get_int();
336			} else {
337				packet_integrity_check(plen,
338				    4 + proto_len + 4 + data_len, type);
339				s->screen = 0;
340			}
341			s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
342
343			if (s->display == NULL)
344				break;
345
346			/* Setup to always have a local .Xauthority. */
347			xauthfile = xmalloc(MAXPATHLEN);
348			strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
349			temporarily_use_uid(s->pw);
350			if (mkdtemp(xauthfile) == NULL) {
351				restore_uid();
352				error("private X11 dir: mkdtemp %s failed: %s",
353				    xauthfile, strerror(errno));
354				xfree(xauthfile);
355				xauthfile = NULL;
356				/* XXXX remove listening channels */
357				break;
358			}
359			strlcat(xauthfile, "/cookies", MAXPATHLEN);
360			fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
361			if (fd >= 0)
362				close(fd);
363			restore_uid();
364			fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
365			success = 1;
366			break;
367
368		case SSH_CMSG_AGENT_REQUEST_FORWARDING:
369			if (no_agent_forwarding_flag || compat13) {
370				debug("Authentication agent forwarding not permitted for this authentication.");
371				break;
372			}
373			debug("Received authentication agent forwarding request.");
374			success = auth_input_request_forwarding(s->pw);
375			break;
376
377		case SSH_CMSG_PORT_FORWARD_REQUEST:
378			if (no_port_forwarding_flag) {
379				debug("Port forwarding not permitted for this authentication.");
380				break;
381			}
382			if (!options.allow_tcp_forwarding) {
383				debug("Port forwarding not permitted.");
384				break;
385			}
386			debug("Received TCP/IP port forwarding request.");
387			channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
388			success = 1;
389			break;
390
391		case SSH_CMSG_MAX_PACKET_SIZE:
392			if (packet_set_maxsize(packet_get_int()) > 0)
393				success = 1;
394			break;
395
396		case SSH_CMSG_EXEC_SHELL:
397		case SSH_CMSG_EXEC_CMD:
398			if (type == SSH_CMSG_EXEC_CMD) {
399				command = packet_get_string(&dlen);
400				debug("Exec command '%.500s'", command);
401				packet_integrity_check(plen, 4 + dlen, type);
402			} else {
403				command = NULL;
404				packet_integrity_check(plen, 0, type);
405			}
406			if (forced_command != NULL) {
407				original_command = command;
408				command = forced_command;
409				debug("Forced command '%.500s'", forced_command);
410			}
411			if (have_pty)
412				do_exec_pty(s, command);
413			else
414				do_exec_no_pty(s, command);
415
416			if (command != NULL)
417				xfree(command);
418			/* Cleanup user's local Xauthority file. */
419			if (xauthfile)
420				xauthfile_cleanup_proc(NULL);
421			return;
422
423		default:
424			/*
425			 * Any unknown messages in this phase are ignored,
426			 * and a failure message is returned.
427			 */
428			log("Unknown packet type received after authentication: %d", type);
429		}
430		packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
431		packet_send();
432		packet_write_wait();
433
434		/* Enable compression now that we have replied if appropriate. */
435		if (enable_compression_after_reply) {
436			enable_compression_after_reply = 0;
437			packet_start_compression(compression_level);
438		}
439	}
440}
441
442/*
443 * This is called to fork and execute a command when we have no tty.  This
444 * will call do_child from the child, and server_loop from the parent after
445 * setting up file descriptors and such.
446 */
447void
448do_exec_no_pty(Session *s, const char *command)
449{
450	int pid;
451
452#ifdef USE_PIPES
453	int pin[2], pout[2], perr[2];
454	/* Allocate pipes for communicating with the program. */
455	if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
456		packet_disconnect("Could not create pipes: %.100s",
457				  strerror(errno));
458#else /* USE_PIPES */
459	int inout[2], err[2];
460	/* Uses socket pairs to communicate with the program. */
461	if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
462	    socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
463		packet_disconnect("Could not create socket pairs: %.100s",
464				  strerror(errno));
465#endif /* USE_PIPES */
466	if (s == NULL)
467		fatal("do_exec_no_pty: no session");
468
469	session_proctitle(s);
470
471#ifdef USE_PAM
472	do_pam_setcred();
473#endif /* USE_PAM */
474
475	/* Fork the child. */
476	if ((pid = fork()) == 0) {
477		/* Child.  Reinitialize the log since the pid has changed. */
478		log_init(__progname, options.log_level, options.log_facility, log_stderr);
479
480		/*
481		 * Create a new session and process group since the 4.4BSD
482		 * setlogin() affects the entire process group.
483		 */
484		if (setsid() < 0)
485			error("setsid failed: %.100s", strerror(errno));
486
487#ifdef USE_PIPES
488		/*
489		 * Redirect stdin.  We close the parent side of the socket
490		 * pair, and make the child side the standard input.
491		 */
492		close(pin[1]);
493		if (dup2(pin[0], 0) < 0)
494			perror("dup2 stdin");
495		close(pin[0]);
496
497		/* Redirect stdout. */
498		close(pout[0]);
499		if (dup2(pout[1], 1) < 0)
500			perror("dup2 stdout");
501		close(pout[1]);
502
503		/* Redirect stderr. */
504		close(perr[0]);
505		if (dup2(perr[1], 2) < 0)
506			perror("dup2 stderr");
507		close(perr[1]);
508#else /* USE_PIPES */
509		/*
510		 * Redirect stdin, stdout, and stderr.  Stdin and stdout will
511		 * use the same socket, as some programs (particularly rdist)
512		 * seem to depend on it.
513		 */
514		close(inout[1]);
515		close(err[1]);
516		if (dup2(inout[0], 0) < 0)	/* stdin */
517			perror("dup2 stdin");
518		if (dup2(inout[0], 1) < 0)	/* stdout.  Note: same socket as stdin. */
519			perror("dup2 stdout");
520		if (dup2(err[0], 2) < 0)	/* stderr */
521			perror("dup2 stderr");
522#endif /* USE_PIPES */
523
524		/* Do processing for the child (exec command etc). */
525		do_child(s, command);
526		/* NOTREACHED */
527	}
528	if (pid < 0)
529		packet_disconnect("fork failed: %.100s", strerror(errno));
530	s->pid = pid;
531	/* Set interactive/non-interactive mode. */
532	packet_set_interactive(s->display != NULL);
533#ifdef USE_PIPES
534	/* We are the parent.  Close the child sides of the pipes. */
535	close(pin[0]);
536	close(pout[1]);
537	close(perr[1]);
538
539	if (compat20) {
540		session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]);
541	} else {
542		/* Enter the interactive session. */
543		server_loop(pid, pin[1], pout[0], perr[0]);
544		/* server_loop has closed pin[1], pout[0], and perr[0]. */
545	}
546#else /* USE_PIPES */
547	/* We are the parent.  Close the child sides of the socket pairs. */
548	close(inout[0]);
549	close(err[0]);
550
551	/*
552	 * Enter the interactive session.  Note: server_loop must be able to
553	 * handle the case that fdin and fdout are the same.
554	 */
555	if (compat20) {
556		session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]);
557	} else {
558		server_loop(pid, inout[1], inout[1], err[1]);
559		/* server_loop has closed inout[1] and err[1]. */
560	}
561#endif /* USE_PIPES */
562}
563
564/*
565 * This is called to fork and execute a command when we have a tty.  This
566 * will call do_child from the child, and server_loop from the parent after
567 * setting up file descriptors, controlling tty, updating wtmp, utmp,
568 * lastlog, and other such operations.
569 */
570void
571do_exec_pty(Session *s, const char *command)
572{
573	int fdout, ptyfd, ttyfd, ptymaster;
574	pid_t pid;
575
576	if (s == NULL)
577		fatal("do_exec_pty: no session");
578	ptyfd = s->ptyfd;
579	ttyfd = s->ttyfd;
580
581#ifdef USE_PAM
582	do_pam_session(s->pw->pw_name, s->tty);
583	do_pam_setcred();
584#endif /* USE_PAM */
585
586	/* Fork the child. */
587	if ((pid = fork()) == 0) {
588		/* Child.  Reinitialize the log because the pid has changed. */
589		log_init(__progname, options.log_level, options.log_facility, log_stderr);
590
591		/* Close the master side of the pseudo tty. */
592		close(ptyfd);
593
594		/* Make the pseudo tty our controlling tty. */
595		pty_make_controlling_tty(&ttyfd, s->tty);
596
597		/* Redirect stdin from the pseudo tty. */
598		if (dup2(ttyfd, fileno(stdin)) < 0)
599			error("dup2 stdin failed: %.100s", strerror(errno));
600
601		/* Redirect stdout to the pseudo tty. */
602		if (dup2(ttyfd, fileno(stdout)) < 0)
603			error("dup2 stdin failed: %.100s", strerror(errno));
604
605		/* Redirect stderr to the pseudo tty. */
606		if (dup2(ttyfd, fileno(stderr)) < 0)
607			error("dup2 stdin failed: %.100s", strerror(errno));
608
609		/* Close the extra descriptor for the pseudo tty. */
610		close(ttyfd);
611
612		/* record login, etc. similar to login(1) */
613		if (!(options.use_login && command == NULL))
614			do_login(s, command);
615
616		/* Do common processing for the child, such as execing the command. */
617		do_child(s, command);
618		/* NOTREACHED */
619	}
620	if (pid < 0)
621		packet_disconnect("fork failed: %.100s", strerror(errno));
622	s->pid = pid;
623
624	/* Parent.  Close the slave side of the pseudo tty. */
625	close(ttyfd);
626
627	/*
628	 * Create another descriptor of the pty master side for use as the
629	 * standard input.  We could use the original descriptor, but this
630	 * simplifies code in server_loop.  The descriptor is bidirectional.
631	 */
632	fdout = dup(ptyfd);
633	if (fdout < 0)
634		packet_disconnect("dup #1 failed: %.100s", strerror(errno));
635
636	/* we keep a reference to the pty master */
637	ptymaster = dup(ptyfd);
638	if (ptymaster < 0)
639		packet_disconnect("dup #2 failed: %.100s", strerror(errno));
640	s->ptymaster = ptymaster;
641
642	/* Enter interactive session. */
643	packet_set_interactive(1);
644	if (compat20) {
645		session_set_fds(s, ptyfd, fdout, -1);
646	} else {
647		server_loop(pid, ptyfd, fdout, -1);
648		/* server_loop _has_ closed ptyfd and fdout. */
649		session_pty_cleanup(s);
650	}
651}
652
653/* administrative, login(1)-like work */
654void
655do_login(Session *s, const char *command)
656{
657	FILE *f;
658	char *time_string, *newcommand;
659	char buf[256];
660	char hostname[MAXHOSTNAMELEN];
661	socklen_t fromlen;
662	struct sockaddr_storage from;
663	time_t last_login_time;
664	struct passwd * pw = s->pw;
665	pid_t pid = getpid();
666#ifdef HAVE_LOGIN_CAP
667	char *fname;
668#endif /* HAVE_LOGIN_CAP */
669#ifdef __FreeBSD__
670#define DEFAULT_WARN  (2L * 7L * 86400L)  /* Two weeks */
671	struct timeval tv;
672	time_t warntime = DEFAULT_WARN;
673#endif /* __FreeBSD__ */
674
675	/*
676	 * Get IP address of client. If the connection is not a socket, let
677	 * the address be 0.0.0.0.
678	 */
679	memset(&from, 0, sizeof(from));
680	if (packet_connection_is_on_socket()) {
681		fromlen = sizeof(from);
682		if (getpeername(packet_get_connection_in(),
683		     (struct sockaddr *) & from, &fromlen) < 0) {
684			debug("getpeername: %.100s", strerror(errno));
685			fatal_cleanup();
686		}
687	}
688
689	/* Get the time and hostname when the user last logged in. */
690	if (options.print_lastlog) {
691		hostname[0] = '\0';
692		last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
693		    hostname, sizeof(hostname));
694	}
695
696	/* Record that there was a login on that tty from the remote host. */
697	record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
698	    get_remote_name_or_ip(utmp_len, options.reverse_mapping_check),
699	    (struct sockaddr *)&from);
700
701#ifdef USE_PAM
702	/*
703	 * If password change is needed, do it now.
704	 * This needs to occur before the ~/.hushlogin check.
705	 */
706	if (pam_password_change_required()) {
707		print_pam_messages();
708		do_pam_chauthtok();
709	}
710#endif
711
712#ifdef USE_PAM
713	if (!check_quietlogin(s, command) && !pam_password_change_required())
714		print_pam_messages();
715#endif /* USE_PAM */
716
717#ifdef __FreeBSD__
718	if (pw->pw_change || pw->pw_expire)
719		(void)gettimeofday(&tv, NULL);
720#ifdef HAVE_LOGIN_CAP
721	warntime = login_getcaptime(lc, "warnpassword",
722				    DEFAULT_WARN, DEFAULT_WARN);
723#endif /* HAVE_LOGIN_CAP */
724	/*
725	 * If the password change time is set and has passed, give the
726	 * user a password expiry notice and chance to change it.
727	 */
728	if (pw->pw_change != 0) {
729		if (tv.tv_sec >= pw->pw_change) {
730			(void)printf(
731			    "Sorry -- your password has expired.\n");
732			log("%s Password expired - forcing change",
733			    pw->pw_name);
734			if (newcommand != NULL)
735				xfree(newcommand);
736			newcommand = xstrdup(_PATH_CHPASS);
737		} else if (pw->pw_change - tv.tv_sec < warntime &&
738			   !check_quietlogin(s, command))
739			(void)printf(
740			    "Warning: your password expires on %s",
741			     ctime(&pw->pw_change));
742	}
743#ifdef HAVE_LOGIN_CAP
744	warntime = login_getcaptime(lc, "warnexpire",
745				    DEFAULT_WARN, DEFAULT_WARN);
746#endif /* HAVE_LOGIN_CAP */
747#ifndef USE_PAM
748	if (pw->pw_expire) {
749		if (tv.tv_sec >= pw->pw_expire) {
750			(void)printf(
751			    "Sorry -- your account has expired.\n");
752			log(
753	   "LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s",
754				pw->pw_name, get_remote_name_or_ip(utmp_len,
755				options.reverse_mapping_check), s->tty);
756			exit(254);
757		} else if (pw->pw_expire - tv.tv_sec < warntime &&
758			   !check_quietlogin(s, command))
759			(void)printf(
760			    "Warning: your account expires on %s",
761			     ctime(&pw->pw_expire));
762	}
763#endif /* !USE_PAM */
764#endif /* __FreeBSD__ */
765
766#ifdef HAVE_LOGIN_CAP
767	if (!auth_ttyok(lc, s->tty)) {
768		(void)printf("Permission denied.\n");
769		log(
770	       "LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s",
771		    pw->pw_name, get_remote_name_or_ip(utmp_len,
772			options.reverse_mapping_check), s->tty);
773		exit(254);
774	}
775#endif /* HAVE_LOGIN_CAP */
776
777	/*
778	 * If the user has logged in before, display the time of last
779	 * login. However, don't display anything extra if a command
780	 * has been specified (so that ssh can be used to execute
781	 * commands on a remote machine without users knowing they
782	 * are going to another machine). Login(1) will do this for
783	 * us as well, so check if login(1) is used
784	 */
785	if (command == NULL && options.print_lastlog &&
786	    last_login_time != 0 && !check_quietlogin(s, command) &&
787	    !options.use_login) {
788		time_string = ctime(&last_login_time);
789		/* Remove the trailing newline. */
790		if (strchr(time_string, '\n'))
791			*strchr(time_string, '\n') = 0;
792		if (strcmp(hostname, "") == 0)
793			printf("Last login: %s\r\n", time_string);
794		else
795			printf("Last login: %s from %s\r\n", time_string, hostname);
796	}
797
798#ifdef HAVE_LOGIN_CAP
799	if (command == NULL && !check_quietlogin(s, command) &&
800	    !options.use_login) {
801		fname = login_getcapstr(lc, "copyright", NULL, NULL);
802		if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
803			while (fgets(buf, sizeof(buf), f) != NULL)
804				fputs(buf, stdout);
805				fclose(f);
806		} else
807			(void)printf("%s\n\t%s %s\n",
808		"Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
809		"The Regents of the University of California. ",
810		"All rights reserved.");
811	}
812#endif /* HAVE_LOGIN_CAP */
813
814	/*
815	 * Print /etc/motd unless a command was specified or printing
816	 * it was disabled in server options or login(1) will be
817	 * used.  Note that some machines appear to print it in
818	 * /etc/profile or similar.
819	 */
820	if (command == NULL && !check_quietlogin(s, command) && !options.use_login)
821		do_motd();
822}
823
824/*
825 * Display the message of the day.
826 */
827void
828do_motd(void)
829{
830	FILE *f;
831	char buf[256];
832
833	if (options.print_motd) {
834#ifdef HAVE_LOGIN_CAP
835		f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
836		    "/etc/motd"), "r");
837#else /* !HAVE_LOGIN_CAP */
838		f = fopen("/etc/motd", "r");
839#endif /* HAVE_LOGIN_CAP */
840		if (f) {
841			while (fgets(buf, sizeof(buf), f))
842				fputs(buf, stdout);
843			fclose(f);
844		}
845	}
846}
847
848/*
849 * Check for quiet login, either .hushlogin or command given.
850 */
851int
852check_quietlogin(Session *s, const char *command)
853{
854	char buf[256];
855	struct passwd * pw = s->pw;
856	struct stat st;
857
858	/* Return 1 if .hushlogin exists or a command given. */
859	if (command != NULL)
860		return 1;
861	snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
862#ifdef HAVE_LOGIN_CAP
863	if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
864		return 1;
865#else
866	if (stat(buf, &st) >= 0)
867		return 1;
868#endif
869	return 0;
870}
871
872/*
873 * Sets the value of the given variable in the environment.  If the variable
874 * already exists, its value is overriden.
875 */
876void
877child_set_env(char ***envp, u_int *envsizep, const char *name,
878	      const char *value)
879{
880	u_int i, namelen;
881	char **env;
882
883	/*
884	 * Find the slot where the value should be stored.  If the variable
885	 * already exists, we reuse the slot; otherwise we append a new slot
886	 * at the end of the array, expanding if necessary.
887	 */
888	env = *envp;
889	namelen = strlen(name);
890	for (i = 0; env[i]; i++)
891		if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
892			break;
893	if (env[i]) {
894		/* Reuse the slot. */
895		xfree(env[i]);
896	} else {
897		/* New variable.  Expand if necessary. */
898		if (i >= (*envsizep) - 1) {
899			(*envsizep) += 50;
900			env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
901		}
902		/* Need to set the NULL pointer at end of array beyond the new slot. */
903		env[i + 1] = NULL;
904	}
905
906	/* Allocate space and format the variable in the appropriate slot. */
907	env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
908	snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
909}
910
911/*
912 * Reads environment variables from the given file and adds/overrides them
913 * into the environment.  If the file does not exist, this does nothing.
914 * Otherwise, it must consist of empty lines, comments (line starts with '#')
915 * and assignments of the form name=value.  No other forms are allowed.
916 */
917void
918read_environment_file(char ***env, u_int *envsize,
919		      const char *filename)
920{
921	FILE *f;
922	char buf[4096];
923	char *cp, *value;
924
925	f = fopen(filename, "r");
926	if (!f)
927		return;
928
929	while (fgets(buf, sizeof(buf), f)) {
930		for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
931			;
932		if (!*cp || *cp == '#' || *cp == '\n')
933			continue;
934		if (strchr(cp, '\n'))
935			*strchr(cp, '\n') = '\0';
936		value = strchr(cp, '=');
937		if (value == NULL) {
938			fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
939			continue;
940		}
941		/*
942		 * Replace the equals sign by nul, and advance value to
943		 * the value string.
944		 */
945		*value = '\0';
946		value++;
947		child_set_env(env, envsize, cp, value);
948	}
949	fclose(f);
950}
951
952#ifdef USE_PAM
953/*
954 * Sets any environment variables which have been specified by PAM
955 */
956void do_pam_environment(char ***env, int *envsize)
957{
958	char *equals, var_name[512], var_val[512];
959	char **pam_env;
960	int i;
961
962	if ((pam_env = fetch_pam_environment()) == NULL)
963		return;
964
965	for(i = 0; pam_env[i] != NULL; i++) {
966		if ((equals = strstr(pam_env[i], "=")) == NULL)
967			continue;
968
969		if (strlen(pam_env[i]) < (sizeof(var_name) - 1)) {
970			memset(var_name, '\0', sizeof(var_name));
971			memset(var_val, '\0', sizeof(var_val));
972
973			strncpy(var_name, pam_env[i], equals - pam_env[i]);
974			strcpy(var_val, equals + 1);
975
976			child_set_env(env, envsize, var_name, var_val);
977		}
978	}
979}
980#endif /* USE_PAM */
981
982
983/*
984 * Performs common processing for the child, such as setting up the
985 * environment, closing extra file descriptors, setting the user and group
986 * ids, and executing the command or shell.
987 */
988void
989do_child(Session *s, const char *command)
990{
991	const char *shell, *hostname = NULL, *cp = NULL;
992	struct passwd * pw = s->pw;
993	char buf[256];
994	char cmd[1024];
995	FILE *f = NULL;
996	u_int envsize, i;
997	char **env;
998	extern char **environ;
999	struct stat st;
1000	char *argv[10];
1001	int do_xauth = s->auth_proto != NULL && s->auth_data != NULL;
1002
1003	/* remove hostkey from the child's memory */
1004	destroy_sensitive_data();
1005
1006	/* login(1) is only called if we execute the login shell */
1007	if (options.use_login && command != NULL)
1008		options.use_login = 0;
1009
1010#ifndef USE_PAM
1011	if (!options.use_login) {
1012#ifdef HAVE_LOGIN_CAP
1013	if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
1014		f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
1015		    _PATH_NOLOGIN), "r");
1016#else
1017		if (pw->pw_uid)
1018			f = fopen(_PATH_NOLOGIN, "r");
1019#endif
1020		if (f) {
1021			/* /etc/nologin exists.  Print its contents and exit. */
1022			while (fgets(buf, sizeof(buf), f))
1023				fputs(buf, stderr);
1024			fclose(f);
1025			exit(254);
1026		}
1027	}
1028#endif /* !USE_PAM */
1029	/* Set login name, uid, gid, and groups. */
1030	/* Login(1) does this as well, and it needs uid 0 for the "-h"
1031	   switch, so we let login(1) to this for us. */
1032	if (!options.use_login) {
1033#ifdef HAVE_LOGIN_CAP
1034		char **tmpenv;
1035
1036		/* Initialize temp environment */
1037		envsize = 64;
1038		env = xmalloc(envsize * sizeof(char *));
1039		env[0] = NULL;
1040
1041		child_set_env(&env, &envsize, "PATH",
1042			      (pw->pw_uid == 0) ?
1043			      _PATH_STDPATH : _PATH_DEFPATH);
1044
1045		snprintf(buf, sizeof buf, "%.200s/%.50s",
1046			 _PATH_MAILDIR, pw->pw_name);
1047		child_set_env(&env, &envsize, "MAIL", buf);
1048
1049		if (getenv("TZ"))
1050			child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1051
1052		/* Save parent environment */
1053		tmpenv = environ;
1054		environ = env;
1055
1056		if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) < 0)
1057			fatal("setusercontext failed: %s", strerror(errno));
1058
1059		/* Restore parent environment */
1060		env = environ;
1061		environ = tmpenv;
1062
1063		for (envsize = 0; env[envsize] != NULL; ++envsize)
1064			;
1065		envsize = (envsize < 100) ? 100 : envsize + 16;
1066		env = xrealloc(env, envsize * sizeof(char *));
1067
1068#endif /* !HAVE_LOGIN_CAP */
1069		if (getuid() == 0 || geteuid() == 0) {
1070#ifdef HAVE_LOGIN_CAP
1071			if (setusercontext(lc, pw, pw->pw_uid,
1072			    (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
1073				perror("unable to set user context");
1074				exit(1);
1075			}
1076#else
1077			if (setlogin(pw->pw_name) < 0)
1078				error("setlogin failed: %s", strerror(errno));
1079			if (setgid(pw->pw_gid) < 0) {
1080				perror("setgid");
1081				exit(1);
1082			}
1083			/* Initialize the group list. */
1084			if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
1085				perror("initgroups");
1086				exit(1);
1087			}
1088			endgrent();
1089
1090			/* Permanently switch to the desired uid. */
1091			permanently_set_uid(pw);
1092#endif /* HAVE_LOGIN_CAP */
1093		}
1094		if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1095			fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1096	}
1097	/*
1098	 * Get the shell from the password data.  An empty shell field is
1099	 * legal, and means /bin/sh.
1100	 */
1101	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1102#ifdef HAVE_LOGIN_CAP
1103	shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
1104#endif
1105
1106#ifdef AFS
1107	/* Try to get AFS tokens for the local cell. */
1108	if (k_hasafs()) {
1109		char cell[64];
1110
1111		if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1112			krb_afslog(cell, 0);
1113
1114		krb_afslog(0, 0);
1115	}
1116#endif /* AFS */
1117
1118	/* Initialize the environment. */
1119	if (env == NULL) {
1120		envsize = 100;
1121		env = xmalloc(envsize * sizeof(char *));
1122		env[0] = NULL;
1123	}
1124
1125	if (!options.use_login) {
1126		/* Set basic environment. */
1127		child_set_env(&env, &envsize, "USER", pw->pw_name);
1128		child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
1129		child_set_env(&env, &envsize, "HOME", pw->pw_dir);
1130#ifdef HAVE_LOGIN_CAP
1131		(void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
1132		child_set_env(&env, &envsize, "PATH", getenv("PATH"));
1133#else
1134		child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1135#endif
1136
1137		snprintf(buf, sizeof buf, "%.200s/%.50s",
1138			 _PATH_MAILDIR, pw->pw_name);
1139		child_set_env(&env, &envsize, "MAIL", buf);
1140
1141		/* Normal systems set SHELL by default. */
1142		child_set_env(&env, &envsize, "SHELL", shell);
1143	}
1144	if (getenv("TZ"))
1145		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1146
1147	/* Set custom environment options from RSA authentication. */
1148	while (custom_environment) {
1149		struct envstring *ce = custom_environment;
1150		char *s = ce->s;
1151		int i;
1152		for (i = 0; s[i] != '=' && s[i]; i++);
1153		if (s[i] == '=') {
1154			s[i] = 0;
1155			child_set_env(&env, &envsize, s, s + i + 1);
1156		}
1157		custom_environment = ce->next;
1158		xfree(ce->s);
1159		xfree(ce);
1160	}
1161
1162	snprintf(buf, sizeof buf, "%.50s %d %d",
1163		 get_remote_ipaddr(), get_remote_port(), get_local_port());
1164	child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1165
1166	if (s->ttyfd != -1)
1167		child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1168	if (s->term)
1169		child_set_env(&env, &envsize, "TERM", s->term);
1170	if (s->display)
1171		child_set_env(&env, &envsize, "DISPLAY", s->display);
1172	if (original_command)
1173		child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1174		    original_command);
1175
1176#ifdef KRB4
1177	{
1178		extern char *ticket;
1179
1180		if (ticket)
1181			child_set_env(&env, &envsize, "KRBTKFILE", ticket);
1182	}
1183#endif /* KRB4 */
1184#ifdef KRB5
1185{
1186	  extern krb5_ccache mem_ccache;
1187
1188	   if (mem_ccache) {
1189	     krb5_error_code problem;
1190	      krb5_ccache ccache;
1191#ifdef AFS
1192	      if (k_hasafs())
1193		krb5_afslog(ssh_context, mem_ccache, NULL, NULL);
1194#endif /* AFS */
1195
1196	      problem = krb5_cc_default(ssh_context, &ccache);
1197	      if (problem) {}
1198	      else {
1199		problem = krb5_cc_copy_cache(ssh_context, mem_ccache, ccache);
1200		 if (problem) {}
1201	      }
1202
1203	      krb5_cc_close(ssh_context, ccache);
1204	   }
1205
1206	   krb5_cleanup_proc(NULL);
1207	}
1208#endif /* KRB5 */
1209
1210#ifdef USE_PAM
1211	/* Pull in any environment variables that may have been set by PAM. */
1212	do_pam_environment(&env, &envsize);
1213#endif /* USE_PAM */
1214
1215	if (xauthfile)
1216		child_set_env(&env, &envsize, "XAUTHORITY", xauthfile);
1217	if (auth_get_socket_name() != NULL)
1218		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1219			      auth_get_socket_name());
1220
1221	/* read $HOME/.ssh/environment. */
1222	if (!options.use_login) {
1223		snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
1224		    pw->pw_dir);
1225		read_environment_file(&env, &envsize, buf);
1226	}
1227	if (debug_flag) {
1228		/* dump the environment */
1229		fprintf(stderr, "Environment:\n");
1230		for (i = 0; env[i]; i++)
1231			fprintf(stderr, "  %.200s\n", env[i]);
1232	}
1233	/* we have to stash the hostname before we close our socket. */
1234	if (options.use_login)
1235		hostname = get_remote_name_or_ip(utmp_len,
1236		    options.reverse_mapping_check);
1237	/*
1238	 * Close the connection descriptors; note that this is the child, and
1239	 * the server will still have the socket open, and it is important
1240	 * that we do not shutdown it.  Note that the descriptors cannot be
1241	 * closed before building the environment, as we call
1242	 * get_remote_ipaddr there.
1243	 */
1244	if (packet_get_connection_in() == packet_get_connection_out())
1245		close(packet_get_connection_in());
1246	else {
1247		close(packet_get_connection_in());
1248		close(packet_get_connection_out());
1249	}
1250	/*
1251	 * Close all descriptors related to channels.  They will still remain
1252	 * open in the parent.
1253	 */
1254	/* XXX better use close-on-exec? -markus */
1255	channel_close_all();
1256
1257	/*
1258	 * Close any extra file descriptors.  Note that there may still be
1259	 * descriptors left by system functions.  They will be closed later.
1260	 */
1261	endpwent();
1262
1263	/*
1264	 * Restore any signal handlers set by sshd previously that should
1265	 * be restored to their initial state.
1266	 */
1267	signal(SIGPIPE, SIG_DFL);
1268
1269	/* Change current directory to the user\'s home directory. */
1270	if (
1271#ifdef __FreeBSD__
1272		!*pw->pw_dir ||
1273#endif /* __FreeBSD__ */
1274		chdir(pw->pw_dir) < 0
1275	   ) {
1276#ifdef HAVE_LOGIN_CAP
1277		if (login_getcapbool(lc, "requirehome", 0)) {
1278			(void)printf("Home directory not available\n");
1279			log("LOGIN %.200s REFUSED (HOMEDIR) ON TTY %.200s",
1280				pw->pw_name, ttyname);
1281			exit(254);
1282		}
1283#endif /* HAVE_LOGIN_CAP */
1284#ifdef __FreeBSD__
1285		if (chdir("/") < 0) {
1286			(void)printf("Cannot find root directory\n");
1287			log("LOGIN %.200s REFUSED (ROOTDIR) ON TTY %.200s",
1288				pw->pw_name, ttyname);
1289			exit(254);
1290		}
1291		if (!check_quietlogin(s, command) || *pw->pw_dir)
1292			(void)printf(
1293		       "No home directory.\nLogging in with home = \"/\".\n");
1294
1295#else /* !__FreeBSD__ */
1296
1297		fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1298			pw->pw_dir, strerror(errno));
1299#endif /* __FreeBSD__ */
1300	}
1301
1302	/*
1303	 * Close any extra open file descriptors so that we don\'t have them
1304	 * hanging around in clients.  Note that we want to do this after
1305	 * initgroups, because at least on Solaris 2.3 it leaves file
1306	 * descriptors open.
1307	 */
1308	for (i = 3; i < getdtablesize(); i++)
1309		close(i);
1310
1311	/*
1312	 * Must take new environment into use so that .ssh/rc, /etc/sshrc and
1313	 * xauth are run in the proper environment.
1314	 */
1315	environ = env;
1316
1317	/*
1318	 * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
1319	 * in this order).
1320	 */
1321	if (!options.use_login) {
1322		/* ignore _PATH_SSH_USER_RC for subsystems */
1323		if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
1324			if (debug_flag)
1325				fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
1326				    _PATH_SSH_USER_RC);
1327			f = popen(_PATH_BSHELL " " _PATH_SSH_USER_RC, "w");
1328			if (f) {
1329				if (do_xauth)
1330					fprintf(f, "%s %s\n", s->auth_proto,
1331					    s->auth_data);
1332				pclose(f);
1333			} else
1334				fprintf(stderr, "Could not run %s\n",
1335				    _PATH_SSH_USER_RC);
1336		} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
1337			if (debug_flag)
1338				fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
1339				    _PATH_SSH_SYSTEM_RC);
1340			f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
1341			if (f) {
1342				if (do_xauth)
1343					fprintf(f, "%s %s\n", s->auth_proto,
1344					    s->auth_data);
1345				pclose(f);
1346			} else
1347				fprintf(stderr, "Could not run %s\n",
1348				    _PATH_SSH_SYSTEM_RC);
1349		} else if (do_xauth && options.xauth_location != NULL) {
1350			/* Add authority data to .Xauthority if appropriate. */
1351			char *screen = strchr(s->display, ':');
1352
1353			if (debug_flag) {
1354				fprintf(stderr,
1355				    "Running %.100s add "
1356				    "%.100s %.100s %.100s\n",
1357				    options.xauth_location, s->display,
1358				    s->auth_proto, s->auth_data);
1359				if (screen != NULL)
1360					fprintf(stderr,
1361					    "Adding %.*s/unix%s %s %s\n",
1362					    (int)(screen - s->display),
1363					    s->display, screen,
1364					    s->auth_proto, s->auth_data);
1365			}
1366			snprintf(cmd, sizeof cmd, "%s -q -",
1367			    options.xauth_location);
1368			f = popen(cmd, "w");
1369			if (f) {
1370				fprintf(f, "add %s %s %s\n", s->display,
1371				    s->auth_proto, s->auth_data);
1372				if (screen != NULL)
1373					fprintf(f, "add %.*s/unix%s %s %s\n",
1374					    (int)(screen - s->display),
1375					    s->display, screen,
1376					    s->auth_proto,
1377					    s->auth_data);
1378				pclose(f);
1379			} else {
1380				fprintf(stderr, "Could not run %s\n",
1381				    cmd);
1382			}
1383		}
1384		/* Get the last component of the shell name. */
1385		cp = strrchr(shell, '/');
1386		if (cp)
1387			cp++;
1388		else
1389			cp = shell;
1390	}
1391
1392	/* restore SIGPIPE for child */
1393	signal(SIGPIPE,  SIG_DFL);
1394
1395	/*
1396	 * If we have no command, execute the shell.  In this case, the shell
1397	 * name to be passed in argv[0] is preceded by '-' to indicate that
1398	 * this is a login shell.
1399	 */
1400	if (!command) {
1401		if (!options.use_login) {
1402			char buf[256];
1403
1404			/*
1405			 * Check for mail if we have a tty and it was enabled
1406			 * in server options.
1407			 */
1408			if (s->ttyfd != -1 && options.check_mail) {
1409				char *mailbox;
1410				struct stat mailstat;
1411
1412				mailbox = getenv("MAIL");
1413				if (mailbox != NULL) {
1414					if (stat(mailbox, &mailstat) != 0 ||
1415					    mailstat.st_size == 0)
1416#ifdef __FreeBSD__
1417						;
1418#else /* !__FreeBSD__ */
1419						printf("No mail.\n");
1420#endif /* __FreeBSD__ */
1421					else if (mailstat.st_mtime < mailstat.st_atime)
1422						printf("You have mail.\n");
1423					else
1424						printf("You have new mail.\n");
1425				}
1426			}
1427			/* Start the shell.  Set initial character to '-'. */
1428			buf[0] = '-';
1429			strncpy(buf + 1, cp, sizeof(buf) - 1);
1430			buf[sizeof(buf) - 1] = 0;
1431
1432			/* Execute the shell. */
1433			argv[0] = buf;
1434			argv[1] = NULL;
1435			execve(shell, argv, env);
1436
1437			/* Executing the shell failed. */
1438			perror(shell);
1439			exit(1);
1440
1441		} else {
1442			/* Launch login(1). */
1443
1444			execl("/usr/bin/login", "login", "-h", hostname,
1445			     "-p", "-f", "--", pw->pw_name, NULL);
1446
1447			/* Login couldn't be executed, die. */
1448
1449			perror("login");
1450			exit(1);
1451		}
1452	}
1453	/*
1454	 * Execute the command using the user's shell.  This uses the -c
1455	 * option to execute the command.
1456	 */
1457	argv[0] = (char *) cp;
1458	argv[1] = "-c";
1459	argv[2] = (char *) command;
1460	argv[3] = NULL;
1461	execve(shell, argv, env);
1462	perror(shell);
1463	exit(1);
1464}
1465
1466Session *
1467session_new(void)
1468{
1469	int i;
1470	static int did_init = 0;
1471	if (!did_init) {
1472		debug("session_new: init");
1473		for(i = 0; i < MAX_SESSIONS; i++) {
1474			sessions[i].used = 0;
1475			sessions[i].self = i;
1476		}
1477		did_init = 1;
1478	}
1479	for(i = 0; i < MAX_SESSIONS; i++) {
1480		Session *s = &sessions[i];
1481		if (! s->used) {
1482			memset(s, 0, sizeof(*s));
1483			s->chanid = -1;
1484			s->ptyfd = -1;
1485			s->ttyfd = -1;
1486			s->used = 1;
1487			debug("session_new: session %d", i);
1488			return s;
1489		}
1490	}
1491	return NULL;
1492}
1493
1494void
1495session_dump(void)
1496{
1497	int i;
1498	for(i = 0; i < MAX_SESSIONS; i++) {
1499		Session *s = &sessions[i];
1500		debug("dump: used %d session %d %p channel %d pid %d",
1501		    s->used,
1502		    s->self,
1503		    s,
1504		    s->chanid,
1505		    s->pid);
1506	}
1507}
1508
1509int
1510session_open(int chanid)
1511{
1512	Session *s = session_new();
1513	debug("session_open: channel %d", chanid);
1514	if (s == NULL) {
1515		error("no more sessions");
1516		return 0;
1517	}
1518	s->pw = auth_get_user();
1519	if (s->pw == NULL)
1520		fatal("no user for session %d", s->self);
1521	debug("session_open: session %d: link with channel %d", s->self, chanid);
1522	s->chanid = chanid;
1523	return 1;
1524}
1525
1526Session *
1527session_by_channel(int id)
1528{
1529	int i;
1530	for(i = 0; i < MAX_SESSIONS; i++) {
1531		Session *s = &sessions[i];
1532		if (s->used && s->chanid == id) {
1533			debug("session_by_channel: session %d channel %d", i, id);
1534			return s;
1535		}
1536	}
1537	debug("session_by_channel: unknown channel %d", id);
1538	session_dump();
1539	return NULL;
1540}
1541
1542Session *
1543session_by_pid(pid_t pid)
1544{
1545	int i;
1546	debug("session_by_pid: pid %d", pid);
1547	for(i = 0; i < MAX_SESSIONS; i++) {
1548		Session *s = &sessions[i];
1549		if (s->used && s->pid == pid)
1550			return s;
1551	}
1552	error("session_by_pid: unknown pid %d", pid);
1553	session_dump();
1554	return NULL;
1555}
1556
1557int
1558session_window_change_req(Session *s)
1559{
1560	s->col = packet_get_int();
1561	s->row = packet_get_int();
1562	s->xpixel = packet_get_int();
1563	s->ypixel = packet_get_int();
1564	packet_done();
1565	pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1566	return 1;
1567}
1568
1569int
1570session_pty_req(Session *s)
1571{
1572	u_int len;
1573	int n_bytes;
1574
1575	if (no_pty_flag)
1576		return 0;
1577	if (s->ttyfd != -1)
1578		return 0;
1579	s->term = packet_get_string(&len);
1580	s->col = packet_get_int();
1581	s->row = packet_get_int();
1582	s->xpixel = packet_get_int();
1583	s->ypixel = packet_get_int();
1584
1585	if (strcmp(s->term, "") == 0) {
1586		xfree(s->term);
1587		s->term = NULL;
1588	}
1589	/* Allocate a pty and open it. */
1590	if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) {
1591		xfree(s->term);
1592		s->term = NULL;
1593		s->ptyfd = -1;
1594		s->ttyfd = -1;
1595		error("session_pty_req: session %d alloc failed", s->self);
1596		return 0;
1597	}
1598	debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1599	/*
1600	 * Add a cleanup function to clear the utmp entry and record logout
1601	 * time in case we call fatal() (e.g., the connection gets closed).
1602	 */
1603	fatal_add_cleanup(pty_cleanup_proc, (void *)s);
1604	pty_setowner(s->pw, s->tty);
1605	/* Get window size from the packet. */
1606	pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1607
1608	/* Get tty modes from the packet. */
1609	tty_parse_modes(s->ttyfd, &n_bytes);
1610	packet_done();
1611
1612	session_proctitle(s);
1613
1614	return 1;
1615}
1616
1617int
1618session_subsystem_req(Session *s)
1619{
1620	u_int len;
1621	int success = 0;
1622	char *subsys = packet_get_string(&len);
1623	int i;
1624
1625	packet_done();
1626	log("subsystem request for %s", subsys);
1627
1628	for (i = 0; i < options.num_subsystems; i++) {
1629		if(strcmp(subsys, options.subsystem_name[i]) == 0) {
1630			debug("subsystem: exec() %s", options.subsystem_command[i]);
1631			s->is_subsystem = 1;
1632			do_exec_no_pty(s, options.subsystem_command[i]);
1633			success = 1;
1634		}
1635	}
1636
1637	if (!success)
1638		log("subsystem request for %s failed, subsystem not found", subsys);
1639
1640	xfree(subsys);
1641	return success;
1642}
1643
1644int
1645session_x11_req(Session *s)
1646{
1647	int fd;
1648	if (no_x11_forwarding_flag) {
1649		debug("X11 forwarding disabled in user configuration file.");
1650		return 0;
1651	}
1652	if (!options.x11_forwarding) {
1653		debug("X11 forwarding disabled in server configuration file.");
1654		return 0;
1655	}
1656	if (xauthfile != NULL) {
1657		debug("X11 fwd already started.");
1658		return 0;
1659	}
1660
1661	debug("Received request for X11 forwarding with auth spoofing.");
1662	if (s->display != NULL)
1663		packet_disconnect("Protocol error: X11 display already set.");
1664
1665	s->single_connection = packet_get_char();
1666	s->auth_proto = packet_get_string(NULL);
1667	s->auth_data = packet_get_string(NULL);
1668	s->screen = packet_get_int();
1669	packet_done();
1670
1671	s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
1672	if (s->display == NULL) {
1673		xfree(s->auth_proto);
1674		xfree(s->auth_data);
1675		return 0;
1676	}
1677	xauthfile = xmalloc(MAXPATHLEN);
1678	strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
1679	temporarily_use_uid(s->pw);
1680	if (mkdtemp(xauthfile) == NULL) {
1681		restore_uid();
1682		error("private X11 dir: mkdtemp %s failed: %s",
1683		    xauthfile, strerror(errno));
1684		xfree(xauthfile);
1685		xauthfile = NULL;
1686		xfree(s->auth_proto);
1687		xfree(s->auth_data);
1688		/* XXXX remove listening channels */
1689		return 0;
1690	}
1691	strlcat(xauthfile, "/cookies", MAXPATHLEN);
1692	fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
1693	if (fd >= 0)
1694		close(fd);
1695	restore_uid();
1696	fatal_add_cleanup(xauthfile_cleanup_proc, s);
1697	return 1;
1698}
1699
1700int
1701session_shell_req(Session *s)
1702{
1703	/* if forced_command == NULL, the shell is execed */
1704	char *shell = forced_command;
1705	packet_done();
1706	if (s->ttyfd == -1)
1707		do_exec_no_pty(s, shell);
1708	else
1709		do_exec_pty(s, shell);
1710	return 1;
1711}
1712
1713int
1714session_exec_req(Session *s)
1715{
1716	u_int len;
1717	char *command = packet_get_string(&len);
1718	packet_done();
1719	if (forced_command) {
1720		original_command = command;
1721		command = forced_command;
1722		debug("Forced command '%.500s'", forced_command);
1723	}
1724	if (s->ttyfd == -1)
1725		do_exec_no_pty(s, command);
1726	else
1727		do_exec_pty(s, command);
1728	if (forced_command == NULL)
1729		xfree(command);
1730	return 1;
1731}
1732
1733int
1734session_auth_agent_req(Session *s)
1735{
1736	static int called = 0;
1737	packet_done();
1738	if (no_agent_forwarding_flag) {
1739		debug("session_auth_agent_req: no_agent_forwarding_flag");
1740		return 0;
1741	}
1742	if (called) {
1743		return 0;
1744	} else {
1745		called = 1;
1746		return auth_input_request_forwarding(s->pw);
1747	}
1748}
1749
1750void
1751session_input_channel_req(int id, void *arg)
1752{
1753	u_int len;
1754	int reply;
1755	int success = 0;
1756	char *rtype;
1757	Session *s;
1758	Channel *c;
1759
1760	rtype = packet_get_string(&len);
1761	reply = packet_get_char();
1762
1763	s = session_by_channel(id);
1764	if (s == NULL)
1765		fatal("session_input_channel_req: channel %d: no session", id);
1766	c = channel_lookup(id);
1767	if (c == NULL)
1768		fatal("session_input_channel_req: channel %d: bad channel", id);
1769
1770	debug("session_input_channel_req: session %d channel %d request %s reply %d",
1771	    s->self, id, rtype, reply);
1772
1773	/*
1774	 * a session is in LARVAL state until a shell, a command
1775	 * or a subsystem is executed
1776	 */
1777	if (c->type == SSH_CHANNEL_LARVAL) {
1778		if (strcmp(rtype, "shell") == 0) {
1779			success = session_shell_req(s);
1780		} else if (strcmp(rtype, "exec") == 0) {
1781			success = session_exec_req(s);
1782		} else if (strcmp(rtype, "pty-req") == 0) {
1783			success =  session_pty_req(s);
1784		} else if (strcmp(rtype, "x11-req") == 0) {
1785			success = session_x11_req(s);
1786		} else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
1787			success = session_auth_agent_req(s);
1788		} else if (strcmp(rtype, "subsystem") == 0) {
1789			success = session_subsystem_req(s);
1790		}
1791	}
1792	if (strcmp(rtype, "window-change") == 0) {
1793		success = session_window_change_req(s);
1794	}
1795
1796	if (reply) {
1797		packet_start(success ?
1798		    SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
1799		packet_put_int(c->remote_id);
1800		packet_send();
1801	}
1802	xfree(rtype);
1803}
1804
1805void
1806session_set_fds(Session *s, int fdin, int fdout, int fderr)
1807{
1808	if (!compat20)
1809		fatal("session_set_fds: called for proto != 2.0");
1810	/*
1811	 * now that have a child and a pipe to the child,
1812	 * we can activate our channel and register the fd's
1813	 */
1814	if (s->chanid == -1)
1815		fatal("no channel for session %d", s->self);
1816	channel_set_fds(s->chanid,
1817	    fdout, fdin, fderr,
1818	    fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1819	    1);
1820}
1821
1822void
1823session_pty_cleanup(Session *s)
1824{
1825	if (s == NULL || s->ttyfd == -1)
1826		return;
1827
1828	debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
1829
1830	/* Cancel the cleanup function. */
1831	fatal_remove_cleanup(pty_cleanup_proc, (void *)s);
1832
1833	/* Record that the user has logged out. */
1834	record_logout(s->pid, s->tty);
1835
1836	/* Release the pseudo-tty. */
1837	pty_release(s->tty);
1838
1839	/*
1840	 * Close the server side of the socket pairs.  We must do this after
1841	 * the pty cleanup, so that another process doesn't get this pty
1842	 * while we're still cleaning up.
1843	 */
1844	if (close(s->ptymaster) < 0)
1845		error("close(s->ptymaster): %s", strerror(errno));
1846}
1847
1848void
1849session_exit_message(Session *s, int status)
1850{
1851	Channel *c;
1852	if (s == NULL)
1853		fatal("session_close: no session");
1854	c = channel_lookup(s->chanid);
1855	if (c == NULL)
1856		fatal("session_close: session %d: no channel %d",
1857		    s->self, s->chanid);
1858	debug("session_exit_message: session %d channel %d pid %d",
1859	    s->self, s->chanid, s->pid);
1860
1861	if (WIFEXITED(status)) {
1862		channel_request_start(s->chanid,
1863		    "exit-status", 0);
1864		packet_put_int(WEXITSTATUS(status));
1865		packet_send();
1866	} else if (WIFSIGNALED(status)) {
1867		channel_request_start(s->chanid,
1868		    "exit-signal", 0);
1869		packet_put_int(WTERMSIG(status));
1870		packet_put_char(WCOREDUMP(status));
1871		packet_put_cstring("");
1872		packet_put_cstring("");
1873		packet_send();
1874	} else {
1875		/* Some weird exit cause.  Just exit. */
1876		packet_disconnect("wait returned status %04x.", status);
1877	}
1878
1879	/* disconnect channel */
1880	debug("session_exit_message: release channel %d", s->chanid);
1881	channel_cancel_cleanup(s->chanid);
1882	/*
1883	 * emulate a write failure with 'chan_write_failed', nobody will be
1884	 * interested in data we write.
1885	 * Note that we must not call 'chan_read_failed', since there could
1886	 * be some more data waiting in the pipe.
1887	 */
1888	if (c->ostate != CHAN_OUTPUT_CLOSED)
1889		chan_write_failed(c);
1890	s->chanid = -1;
1891}
1892
1893void
1894session_free(Session *s)
1895{
1896	debug("session_free: session %d pid %d", s->self, s->pid);
1897	if (s->term)
1898		xfree(s->term);
1899	if (s->display)
1900		xfree(s->display);
1901	if (s->auth_data)
1902		xfree(s->auth_data);
1903	if (s->auth_proto)
1904		xfree(s->auth_proto);
1905	s->used = 0;
1906}
1907
1908void
1909session_close(Session *s)
1910{
1911	session_pty_cleanup(s);
1912	session_free(s);
1913	session_proctitle(s);
1914}
1915
1916void
1917session_close_by_pid(pid_t pid, int status)
1918{
1919	Session *s = session_by_pid(pid);
1920	if (s == NULL) {
1921		debug("session_close_by_pid: no session for pid %d", s->pid);
1922		return;
1923	}
1924	if (s->chanid != -1)
1925		session_exit_message(s, status);
1926	session_close(s);
1927}
1928
1929/*
1930 * this is called when a channel dies before
1931 * the session 'child' itself dies
1932 */
1933void
1934session_close_by_channel(int id, void *arg)
1935{
1936	Session *s = session_by_channel(id);
1937	if (s == NULL) {
1938		debug("session_close_by_channel: no session for channel %d", id);
1939		return;
1940	}
1941	/* disconnect channel */
1942	channel_cancel_cleanup(s->chanid);
1943	s->chanid = -1;
1944
1945	debug("session_close_by_channel: channel %d kill %d", id, s->pid);
1946	if (s->pid == 0) {
1947		/* close session immediately */
1948		session_close(s);
1949	} else {
1950		/* notify child, delay session cleanup */
1951		if (s->pid <= 1)
1952			fatal("session_close_by_channel: Unsafe s->pid = %d", s->pid);
1953		if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0)
1954			error("session_close_by_channel: kill %d: %s",
1955			    s->pid, strerror(errno));
1956	}
1957}
1958
1959char *
1960session_tty_list(void)
1961{
1962	static char buf[1024];
1963	int i;
1964	buf[0] = '\0';
1965	for(i = 0; i < MAX_SESSIONS; i++) {
1966		Session *s = &sessions[i];
1967		if (s->used && s->ttyfd != -1) {
1968			if (buf[0] != '\0')
1969				strlcat(buf, ",", sizeof buf);
1970			strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
1971		}
1972	}
1973	if (buf[0] == '\0')
1974		strlcpy(buf, "notty", sizeof buf);
1975	return buf;
1976}
1977
1978void
1979session_proctitle(Session *s)
1980{
1981	if (s->pw == NULL)
1982		error("no user for session %d", s->self);
1983	else
1984		setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
1985}
1986
1987void
1988do_authenticated2(Authctxt *authctxt)
1989{
1990
1991	server_loop2();
1992	if (xauthfile)
1993		xauthfile_cleanup_proc(NULL);
1994}
1995