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