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