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