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