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