Home | History | Annotate | Download | only in sshd
      1 /*
      2  * Copyright (c) 1995 Tatu Ylonen <ylo (at) 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  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     36  * Use is subject to license terms.
     37  */
     38 
     39 #include "includes.h"
     40 RCSID("$OpenBSD: session.c,v 1.150 2002/09/16 19:55:33 stevesk Exp $");
     41 
     42 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     43 
     44 #ifdef HAVE_DEFOPEN
     45 #include <deflt.h>
     46 #include <ulimit.h>
     47 #endif /* HAVE_DEFOPEN */
     48 
     49 #ifdef HAVE_LIBGEN_H
     50 #include <libgen.h>
     51 #endif
     52 
     53 #include "ssh.h"
     54 #include "ssh1.h"
     55 #include "ssh2.h"
     56 #include "xmalloc.h"
     57 #include "sshpty.h"
     58 #include "packet.h"
     59 #include "buffer.h"
     60 #include "mpaux.h"
     61 #include "uidswap.h"
     62 #include "compat.h"
     63 #include "channels.h"
     64 #include "bufaux.h"
     65 #include "auth.h"
     66 #include "auth-options.h"
     67 #include "pathnames.h"
     68 #include "log.h"
     69 #include "servconf.h"
     70 #include "sshlogin.h"
     71 #include "serverloop.h"
     72 #include "canohost.h"
     73 #include "session.h"
     74 
     75 #ifdef USE_PAM
     76 #include <security/pam_appl.h>
     77 #endif /* USE_PAM */
     78 
     79 #ifdef GSSAPI
     80 #include "ssh-gss.h"
     81 #endif
     82 
     83 #ifdef ALTPRIVSEP
     84 #include "altprivsep.h"
     85 #endif /* ALTPRIVSEP */
     86 
     87 #ifdef HAVE_CYGWIN
     88 #include <windows.h>
     89 #include <sys/cygwin.h>
     90 #define is_winnt       (GetVersion() < 0x80000000)
     91 #endif
     92 
     93 /* func */
     94 
     95 Session *session_new(void);
     96 void	session_set_fds(Session *, int, int, int);
     97 void	session_pty_cleanup(void *);
     98 void	session_xauthfile_cleanup(void *s);
     99 void	session_proctitle(Session *);
    100 int	session_setup_x11fwd(Session *);
    101 void	do_exec_pty(Session *, const char *);
    102 void	do_exec_no_pty(Session *, const char *);
    103 void	do_exec(Session *, const char *);
    104 void	do_login(Session *, const char *);
    105 #ifdef LOGIN_NEEDS_UTMPX
    106 static void	do_pre_login(Session *s);
    107 #endif
    108 void	do_child(Session *, const char *);
    109 void	do_motd(void);
    110 int	check_quietlogin(Session *, const char *);
    111 
    112 static void do_authenticated1(Authctxt *);
    113 static void do_authenticated2(Authctxt *);
    114 
    115 static int  session_pty_req(Session *);
    116 static int  session_env_req(Session *s);
    117 static void session_free_env(char ***envp);
    118 
    119 #ifdef USE_PAM
    120 static void session_do_pam(Session *, int);
    121 #endif /* USE_PAM */
    122 
    123 /* import */
    124 extern ServerOptions options;
    125 extern char *__progname;
    126 extern int log_stderr;
    127 extern int debug_flag;
    128 extern u_int utmp_len;
    129 extern void destroy_sensitive_data(void);
    130 
    131 #ifdef GSSAPI
    132 extern Gssctxt *xxx_gssctxt;
    133 #endif /* GSSAPI */
    134 
    135 /* original command from peer. */
    136 const char *original_command = NULL;
    137 
    138 /* data */
    139 #define MAX_SESSIONS 10
    140 Session	sessions[MAX_SESSIONS];
    141 
    142 #ifdef WITH_AIXAUTHENTICATE
    143 char *aixloginmsg;
    144 #endif /* WITH_AIXAUTHENTICATE */
    145 
    146 #ifdef HAVE_LOGIN_CAP
    147 login_cap_t *lc;
    148 #endif
    149 
    150 /* Name and directory of socket for authentication agent forwarding. */
    151 static char *auth_sock_name = NULL;
    152 static char *auth_sock_dir = NULL;
    153 
    154 /* removes the agent forwarding socket */
    155 
    156 static void
    157 auth_sock_cleanup_proc(void *_pw)
    158 {
    159 	struct passwd *pw = _pw;
    160 
    161 	if (auth_sock_name != NULL) {
    162 		temporarily_use_uid(pw);
    163 		unlink(auth_sock_name);
    164 		rmdir(auth_sock_dir);
    165 		auth_sock_name = NULL;
    166 		restore_uid();
    167 	}
    168 }
    169 
    170 static int
    171 auth_input_request_forwarding(struct passwd * pw)
    172 {
    173 	Channel *nc;
    174 	int sock;
    175 	struct sockaddr_un sunaddr;
    176 
    177 	if (auth_sock_name != NULL) {
    178 		error("authentication forwarding requested twice.");
    179 		return 0;
    180 	}
    181 
    182 	/* Temporarily drop privileged uid for mkdir/bind. */
    183 	temporarily_use_uid(pw);
    184 
    185 	/* Allocate a buffer for the socket name, and format the name. */
    186 	auth_sock_name = xmalloc(MAXPATHLEN);
    187 	auth_sock_dir = xmalloc(MAXPATHLEN);
    188 	strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
    189 
    190 	/* Create private directory for socket */
    191 	if (mkdtemp(auth_sock_dir) == NULL) {
    192 		packet_send_debug("Agent forwarding disabled: "
    193 		    "mkdtemp() failed: %.100s", strerror(errno));
    194 		restore_uid();
    195 		xfree(auth_sock_name);
    196 		xfree(auth_sock_dir);
    197 		auth_sock_name = NULL;
    198 		auth_sock_dir = NULL;
    199 		return 0;
    200 	}
    201 	snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
    202 		 auth_sock_dir, (long) getpid());
    203 
    204 	/* delete agent socket on fatal() */
    205 	fatal_add_cleanup(auth_sock_cleanup_proc, pw);
    206 
    207 	/* Create the socket. */
    208 	sock = socket(AF_UNIX, SOCK_STREAM, 0);
    209 	if (sock < 0)
    210 		packet_disconnect("socket: %.100s", strerror(errno));
    211 
    212 	/* Bind it to the name. */
    213 	memset(&sunaddr, 0, sizeof(sunaddr));
    214 	sunaddr.sun_family = AF_UNIX;
    215 	strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
    216 
    217 	if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)
    218 		packet_disconnect("bind: %.100s", strerror(errno));
    219 
    220 	/* Restore the privileged uid. */
    221 	restore_uid();
    222 
    223 	/* Start listening on the socket. */
    224 	if (listen(sock, 5) < 0)
    225 		packet_disconnect("listen: %.100s", strerror(errno));
    226 
    227 	/* Allocate a channel for the authentication agent socket. */
    228 	nc = channel_new("auth socket",
    229 	    SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
    230 	    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
    231 	    0, xstrdup("auth socket"), 1);
    232 	strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
    233 	return 1;
    234 }
    235 
    236 
    237 void
    238 do_authenticated(Authctxt *authctxt)
    239 {
    240 	/* setup the channel layer */
    241 	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
    242 		channel_permit_all_opens();
    243 
    244 	if (compat20)
    245 		do_authenticated2(authctxt);
    246 	else
    247 		do_authenticated1(authctxt);
    248 
    249 	/* remove agent socket */
    250 	if (auth_sock_name != NULL)
    251 		auth_sock_cleanup_proc(authctxt->pw);
    252 #ifdef KRB4
    253 	if (options.kerberos_ticket_cleanup)
    254 		krb4_cleanup_proc(authctxt);
    255 #endif
    256 #ifdef KRB5
    257 	if (options.kerberos_ticket_cleanup)
    258 		krb5_cleanup_proc(authctxt);
    259 #endif
    260 }
    261 
    262 /*
    263  * Prepares for an interactive session.  This is called after the user has
    264  * been successfully authenticated.  During this message exchange, pseudo
    265  * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
    266  * are requested, etc.
    267  */
    268 static void
    269 do_authenticated1(Authctxt *authctxt)
    270 {
    271 	Session *s;
    272 	char *command;
    273 	int success, type, screen_flag;
    274 	int enable_compression_after_reply = 0;
    275 	u_int proto_len, data_len, dlen, compression_level = 0;
    276 
    277 	s = session_new();
    278 	s->authctxt = authctxt;
    279 	s->pw = authctxt->pw;
    280 
    281 	/*
    282 	 * We stay in this loop until the client requests to execute a shell
    283 	 * or a command.
    284 	 */
    285 	for (;;) {
    286 		success = 0;
    287 
    288 		/* Get a packet from the client. */
    289 		type = packet_read();
    290 
    291 		/* Process the packet. */
    292 		switch (type) {
    293 		case SSH_CMSG_REQUEST_COMPRESSION:
    294 			compression_level = packet_get_int();
    295 			packet_check_eom();
    296 			if (compression_level < 1 || compression_level > 9) {
    297 				packet_send_debug("Received illegal compression level %d.",
    298 				    compression_level);
    299 				break;
    300 			}
    301 			if (!options.compression) {
    302 				debug2("compression disabled");
    303 				break;
    304 			}
    305 			/* Enable compression after we have responded with SUCCESS. */
    306 			enable_compression_after_reply = 1;
    307 			success = 1;
    308 			break;
    309 
    310 		case SSH_CMSG_REQUEST_PTY:
    311 			success = session_pty_req(s);
    312 			break;
    313 
    314 		case SSH_CMSG_X11_REQUEST_FORWARDING:
    315 			s->auth_proto = packet_get_string(&proto_len);
    316 			s->auth_data = packet_get_string(&data_len);
    317 
    318 			screen_flag = packet_get_protocol_flags() &
    319 			    SSH_PROTOFLAG_SCREEN_NUMBER;
    320 			debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
    321 
    322 			if (packet_remaining() == 4) {
    323 				if (!screen_flag)
    324 					debug2("Buggy client: "
    325 					    "X11 screen flag missing");
    326 				s->screen = packet_get_int();
    327 			} else {
    328 				s->screen = 0;
    329 			}
    330 			packet_check_eom();
    331 			success = session_setup_x11fwd(s);
    332 			if (!success) {
    333 				xfree(s->auth_proto);
    334 				xfree(s->auth_data);
    335 				s->auth_proto = NULL;
    336 				s->auth_data = NULL;
    337 			}
    338 			break;
    339 
    340 		case SSH_CMSG_AGENT_REQUEST_FORWARDING:
    341 			if (no_agent_forwarding_flag || compat13) {
    342 				debug("Authentication agent forwarding not permitted for this authentication.");
    343 				break;
    344 			}
    345 			debug("Received authentication agent forwarding request.");
    346 			success = auth_input_request_forwarding(s->pw);
    347 			break;
    348 
    349 		case SSH_CMSG_PORT_FORWARD_REQUEST:
    350 			if (no_port_forwarding_flag) {
    351 				debug("Port forwarding not permitted for this authentication.");
    352 				break;
    353 			}
    354 			if (!options.allow_tcp_forwarding) {
    355 				debug("Port forwarding not permitted.");
    356 				break;
    357 			}
    358 			debug("Received TCP/IP port forwarding request.");
    359 			channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
    360 			success = 1;
    361 			break;
    362 
    363 		case SSH_CMSG_MAX_PACKET_SIZE:
    364 			if (packet_set_maxsize(packet_get_int()) > 0)
    365 				success = 1;
    366 			break;
    367 
    368 #if defined(AFS) || defined(KRB5)
    369 		case SSH_CMSG_HAVE_KERBEROS_TGT:
    370 			if (!options.kerberos_tgt_passing) {
    371 				verbose("Kerberos TGT passing disabled.");
    372 			} else {
    373 				char *kdata = packet_get_string(&dlen);
    374 				packet_check_eom();
    375 
    376 				/* XXX - 0x41, see creds_to_radix version */
    377 				if (kdata[0] != 0x41) {
    378 #ifdef KRB5
    379 					krb5_data tgt;
    380 					tgt.data = kdata;
    381 					tgt.length = dlen;
    382 
    383 					if (auth_krb5_tgt(s->authctxt, &tgt))
    384 						success = 1;
    385 					else
    386 						verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);
    387 #endif /* KRB5 */
    388 				} else {
    389 #ifdef AFS
    390 					if (auth_krb4_tgt(s->authctxt, kdata))
    391 						success = 1;
    392 					else
    393 						verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);
    394 #endif /* AFS */
    395 				}
    396 				xfree(kdata);
    397 			}
    398 			break;
    399 #endif /* AFS || KRB5 */
    400 
    401 #ifdef AFS
    402 		case SSH_CMSG_HAVE_AFS_TOKEN:
    403 			if (!options.afs_token_passing || !k_hasafs()) {
    404 				verbose("AFS token passing disabled.");
    405 			} else {
    406 				/* Accept AFS token. */
    407 				char *token = packet_get_string(&dlen);
    408 				packet_check_eom();
    409 
    410 				if (auth_afs_token(s->authctxt, token))
    411 					success = 1;
    412 				else
    413 					verbose("AFS token refused for %.100s",
    414 					    s->authctxt->user);
    415 				xfree(token);
    416 			}
    417 			break;
    418 #endif /* AFS */
    419 
    420 		case SSH_CMSG_EXEC_SHELL:
    421 		case SSH_CMSG_EXEC_CMD:
    422 			if (type == SSH_CMSG_EXEC_CMD) {
    423 				command = packet_get_string(&dlen);
    424 				debug("Exec command '%.500s'", command);
    425 				do_exec(s, command);
    426 				xfree(command);
    427 			} else {
    428 				do_exec(s, NULL);
    429 			}
    430 			packet_check_eom();
    431 			session_close(s);
    432 			return;
    433 
    434 		default:
    435 			/*
    436 			 * Any unknown messages in this phase are ignored,
    437 			 * and a failure message is returned.
    438 			 */
    439 			log("Unknown packet type received after authentication: %d", type);
    440 		}
    441 		packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
    442 		packet_send();
    443 		packet_write_wait();
    444 
    445 		/* Enable compression now that we have replied if appropriate. */
    446 		if (enable_compression_after_reply) {
    447 			enable_compression_after_reply = 0;
    448 			packet_start_compression(compression_level);
    449 		}
    450 	}
    451 }
    452 
    453 /*
    454  * This is called to fork and execute a command when we have no tty.  This
    455  * will call do_child from the child, and server_loop from the parent after
    456  * setting up file descriptors and such.
    457  */
    458 void
    459 do_exec_no_pty(Session *s, const char *command)
    460 {
    461 	pid_t pid;
    462 
    463 #ifdef USE_PIPES
    464 	int pin[2], pout[2], perr[2];
    465 	/* Allocate pipes for communicating with the program. */
    466 	if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
    467 		packet_disconnect("Could not create pipes: %.100s",
    468 				  strerror(errno));
    469 #else /* USE_PIPES */
    470 	int inout[2], err[2];
    471 	/* Uses socket pairs to communicate with the program. */
    472 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
    473 	    socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
    474 		packet_disconnect("Could not create socket pairs: %.100s",
    475 				  strerror(errno));
    476 #endif /* USE_PIPES */
    477 	if (s == NULL)
    478 		fatal("do_exec_no_pty: no session");
    479 
    480 	session_proctitle(s);
    481 
    482 	/* Fork the child. */
    483 	if ((pid = fork()) == 0) {
    484 		fatal_remove_all_cleanups();
    485 
    486 		/* Child.  Reinitialize the log since the pid has changed. */
    487 		log_init(__progname, options.log_level, options.log_facility, log_stderr);
    488 
    489 		/*
    490 		 * Create a new session and process group since the 4.4BSD
    491 		 * setlogin() affects the entire process group.
    492 		 */
    493 		if (setsid() < 0)
    494 			error("setsid failed: %.100s", strerror(errno));
    495 
    496 #ifdef USE_PIPES
    497 		/*
    498 		 * Redirect stdin.  We close the parent side of the socket
    499 		 * pair, and make the child side the standard input.
    500 		 */
    501 		close(pin[1]);
    502 		if (dup2(pin[0], 0) < 0)
    503 			perror("dup2 stdin");
    504 		close(pin[0]);
    505 
    506 		/* Redirect stdout. */
    507 		close(pout[0]);
    508 		if (dup2(pout[1], 1) < 0)
    509 			perror("dup2 stdout");
    510 		close(pout[1]);
    511 
    512 		/* Redirect stderr. */
    513 		close(perr[0]);
    514 		if (dup2(perr[1], 2) < 0)
    515 			perror("dup2 stderr");
    516 		close(perr[1]);
    517 #else /* USE_PIPES */
    518 		/*
    519 		 * Redirect stdin, stdout, and stderr.  Stdin and stdout will
    520 		 * use the same socket, as some programs (particularly rdist)
    521 		 * seem to depend on it.
    522 		 */
    523 		close(inout[1]);
    524 		close(err[1]);
    525 		if (dup2(inout[0], 0) < 0)	/* stdin */
    526 			perror("dup2 stdin");
    527 		if (dup2(inout[0], 1) < 0)	/* stdout.  Note: same socket as stdin. */
    528 			perror("dup2 stdout");
    529 		if (dup2(err[0], 2) < 0)	/* stderr */
    530 			perror("dup2 stderr");
    531 #endif /* USE_PIPES */
    532 
    533 #ifdef _UNICOS
    534 		cray_init_job(s->pw); /* set up cray jid and tmpdir */
    535 #endif
    536 
    537 		/* Do processing for the child (exec command etc). */
    538 		do_child(s, command);
    539 		/* NOTREACHED */
    540 	}
    541 #ifdef _UNICOS
    542 	signal(WJSIGNAL, cray_job_termination_handler);
    543 #endif /* _UNICOS */
    544 #ifdef HAVE_CYGWIN
    545 	if (is_winnt)
    546 		cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
    547 #endif
    548 	if (pid < 0)
    549 		packet_disconnect("fork failed: %.100s", strerror(errno));
    550 	s->pid = pid;
    551 	/* Set interactive/non-interactive mode. */
    552 	packet_set_interactive(s->display != NULL);
    553 #ifdef USE_PIPES
    554 	/* We are the parent.  Close the child sides of the pipes. */
    555 	close(pin[0]);
    556 	close(pout[1]);
    557 	close(perr[1]);
    558 
    559 	if (compat20) {
    560 		session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]);
    561 		/* Don't close channel before sending exit-status! */
    562 		channel_set_wait_for_exit(s->chanid, 1);
    563 	} else {
    564 		/* Enter the interactive session. */
    565 		server_loop(pid, pin[1], pout[0], perr[0]);
    566 		/* server_loop has closed pin[1], pout[0], and perr[0]. */
    567 	}
    568 #else /* USE_PIPES */
    569 	/* We are the parent.  Close the child sides of the socket pairs. */
    570 	close(inout[0]);
    571 	close(err[0]);
    572 
    573 	/*
    574 	 * Enter the interactive session.  Note: server_loop must be able to
    575 	 * handle the case that fdin and fdout are the same.
    576 	 */
    577 	if (compat20) {
    578 		session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]);
    579 		/* Don't close channel before sending exit-status! */
    580 		channel_set_wait_for_exit(s->chanid, 1);
    581 	} else {
    582 		server_loop(pid, inout[1], inout[1], err[1]);
    583 		/* server_loop has closed inout[1] and err[1]. */
    584 	}
    585 #endif /* USE_PIPES */
    586 }
    587 
    588 /*
    589  * This is called to fork and execute a command when we have a tty.  This
    590  * will call do_child from the child, and server_loop from the parent after
    591  * setting up file descriptors, controlling tty, updating wtmp, utmp,
    592  * lastlog, and other such operations.
    593  */
    594 void
    595 do_exec_pty(Session *s, const char *command)
    596 {
    597 	int fdout, ptyfd, ttyfd, ptymaster, pipe_fds[2];
    598 	pid_t pid;
    599 
    600 	if (s == NULL)
    601 		fatal("do_exec_pty: no session");
    602 	ptyfd = s->ptyfd;
    603 	ttyfd = s->ttyfd;
    604 
    605 #ifdef USE_PAM
    606 	session_do_pam(s, 1);	/* pam_open_session() */
    607 #endif /* USE_PAM */
    608 
    609 	/*
    610 	 * This pipe lets sshd wait for child to exec or exit.  This is
    611 	 * particularly important for ALTPRIVSEP because the child is
    612 	 * the one to call the monitor to request a record_login() and
    613 	 * we don't want the child and the parent to compete for the
    614 	 * monitor's attention.  But this is generic code and doesn't
    615 	 * hurt to have here even if ALTPRIVSEP is not used.
    616 	 */
    617 	if (pipe(pipe_fds) != 0)
    618 		packet_disconnect("pipe failed: %.100s", strerror(errno));
    619 
    620 	(void) fcntl(pipe_fds[0], F_SETFD, FD_CLOEXEC);
    621 	(void) fcntl(pipe_fds[1], F_SETFD, FD_CLOEXEC);
    622 
    623 	/* Fork the child. */
    624 	if ((pid = fork()) == 0) {
    625 		(void) close(pipe_fds[0]);
    626 
    627 		fatal_remove_all_cleanups();
    628 
    629 		/* Child.  Reinitialize the log because the pid has changed. */
    630 		log_init(__progname, options.log_level, options.log_facility, log_stderr);
    631 		/* Close the master side of the pseudo tty. */
    632 		close(ptyfd);
    633 
    634 		/* Make the pseudo tty our controlling tty. */
    635 		pty_make_controlling_tty(&ttyfd, s->tty);
    636 
    637 		/* Redirect stdin/stdout/stderr from the pseudo tty. */
    638 		if (dup2(ttyfd, 0) < 0)
    639 			error("dup2 stdin: %s", strerror(errno));
    640 		if (dup2(ttyfd, 1) < 0)
    641 			error("dup2 stdout: %s", strerror(errno));
    642 		if (dup2(ttyfd, 2) < 0)
    643 			error("dup2 stderr: %s", strerror(errno));
    644 
    645 		/* Close the extra descriptor for the pseudo tty. */
    646 		close(ttyfd);
    647 
    648 		/* record login, etc. similar to login(1) */
    649 #if !defined(HAVE_OSF_SIA)
    650 		if (!(options.use_login && command == NULL)) {
    651 #ifdef _UNICOS
    652 			cray_init_job(s->pw); /* set up cray jid and tmpdir */
    653 #endif /* _UNICOS */
    654 			do_login(s, command);
    655 		}
    656 # ifdef LOGIN_NEEDS_UTMPX
    657 		else
    658 			do_pre_login(s);
    659 # endif
    660 #endif /* !HAVE_OSF_SIA */
    661 
    662 		/*
    663 		 * do_pre_login() will have completed the record_login(), so
    664 		 * close the pipe to the parent so it can re-enter its event
    665 		 * loop and service the ptm; if enough debug messages get
    666 		 * written to the pty before this happens there will be a
    667 		 * deadlock.
    668 		 */
    669 		close(pipe_fds[1]);
    670 
    671 		/* Do common processing for the child, such as execing the command. */
    672 		do_child(s, command);
    673 		/* NOTREACHED */
    674 	}
    675 
    676 	/* Wait for child to exec() or exit() */
    677 	(void) close(pipe_fds[1]);
    678 	(void) read(pipe_fds[0], &pipe_fds[1], sizeof(int));
    679 
    680 #ifdef _UNICOS
    681 	signal(WJSIGNAL, cray_job_termination_handler);
    682 #endif /* _UNICOS */
    683 #ifdef HAVE_CYGWIN
    684 	if (is_winnt)
    685 		cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
    686 #endif
    687 	if (pid < 0)
    688 		packet_disconnect("fork failed: %.100s", strerror(errno));
    689 	s->pid = pid;
    690 
    691 	/* Parent.  Close the slave side of the pseudo tty. */
    692 	close(ttyfd);
    693 
    694 	/*
    695 	 * Create another descriptor of the pty master side for use as the
    696 	 * standard input.  We could use the original descriptor, but this
    697 	 * simplifies code in server_loop.  The descriptor is bidirectional.
    698 	 */
    699 	fdout = dup(ptyfd);
    700 	if (fdout < 0)
    701 		packet_disconnect("dup #1 failed: %.100s", strerror(errno));
    702 
    703 	/* we keep a reference to the pty master */
    704 	ptymaster = dup(ptyfd);
    705 	if (ptymaster < 0)
    706 		packet_disconnect("dup #2 failed: %.100s", strerror(errno));
    707 	s->ptymaster = ptymaster;
    708 
    709 	/* Enter interactive session. */
    710 	packet_set_interactive(1);
    711 	if (compat20) {
    712 		session_set_fds(s, ptyfd, fdout, -1);
    713 		/* Don't close channel before sending exit-status! */
    714 		channel_set_wait_for_exit(s->chanid, 1);
    715 	} else {
    716 		server_loop(pid, ptyfd, fdout, -1);
    717 		/* server_loop _has_ closed ptyfd and fdout. */
    718 	}
    719 }
    720 
    721 #ifdef LOGIN_NEEDS_UTMPX
    722 static void
    723 do_pre_login(Session *s)
    724 {
    725 	socklen_t fromlen;
    726 	struct sockaddr_storage from;
    727 	pid_t pid = getpid();
    728 
    729 	/*
    730 	 * Get IP address of client. If the connection is not a socket, let
    731 	 * the address be 0.0.0.0.
    732 	 */
    733 	memset(&from, 0, sizeof(from));
    734 	fromlen = sizeof(from);
    735 	if (packet_connection_is_on_socket()) {
    736 		if (getpeername(packet_get_connection_in(),
    737 		    (struct sockaddr *) & from, &fromlen) < 0) {
    738 			debug("getpeername: %.100s", strerror(errno));
    739 			fatal_cleanup();
    740 		}
    741 	}
    742 
    743 	record_utmp_only(pid, s->tty, s->pw->pw_name,
    744 	    get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
    745 	    (struct sockaddr *)&from);
    746 }
    747 #endif
    748 
    749 /*
    750  * This is called to fork and execute a command.  If another command is
    751  * to be forced, execute that instead.
    752  */
    753 void
    754 do_exec(Session *s, const char *command)
    755 {
    756 	if (command)
    757 		s->command = xstrdup(command);
    758 
    759 	if (forced_command) {
    760 		original_command = command;
    761 		command = forced_command;
    762 		debug("Forced command '%.900s'", command);
    763 	}
    764 
    765 	if (s->ttyfd != -1)
    766 		do_exec_pty(s, command);
    767 	else
    768 		do_exec_no_pty(s, command);
    769 
    770 	original_command = NULL;
    771 }
    772 
    773 
    774 /* administrative, login(1)-like work */
    775 void
    776 do_login(Session *s, const char *command)
    777 {
    778 	char *time_string;
    779 #ifndef ALTPRIVSEP
    780 	struct passwd * pw = s->pw;
    781 #endif /* ALTPRIVSEP*/
    782 	pid_t pid = getpid();
    783 
    784 	/* Record that there was a login on that tty from the remote host. */
    785 #ifdef ALTPRIVSEP
    786 	debug3("Recording SSHv2 channel login in utmpx/wtmpx");
    787 	altprivsep_record_login(pid, s->tty);
    788 #endif /* ALTPRIVSEP*/
    789 
    790 	if (check_quietlogin(s, command))
    791 		return;
    792 
    793 #ifdef USE_PAM
    794 		print_pam_messages();
    795 #endif /* USE_PAM */
    796 #ifdef WITH_AIXAUTHENTICATE
    797 	if (aixloginmsg && *aixloginmsg)
    798 		printf("%s\n", aixloginmsg);
    799 #endif /* WITH_AIXAUTHENTICATE */
    800 
    801 #ifndef NO_SSH_LASTLOG
    802 	if (options.print_lastlog && s->last_login_time != 0) {
    803 		time_string = ctime(&s->last_login_time);
    804 		if (strchr(time_string, '\n'))
    805 			*strchr(time_string, '\n') = 0;
    806 		if (strcmp(s->hostname, "") == 0)
    807 			printf("Last login: %s\r\n", time_string);
    808 		else
    809 			printf("Last login: %s from %s\r\n", time_string,
    810 			    s->hostname);
    811 	}
    812 #endif /* NO_SSH_LASTLOG */
    813 
    814 	do_motd();
    815 }
    816 
    817 /*
    818  * Display the message of the day.
    819  */
    820 void
    821 do_motd(void)
    822 {
    823 	FILE *f;
    824 	char buf[256];
    825 
    826 	if (options.print_motd) {
    827 #ifdef HAVE_LOGIN_CAP
    828 		f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
    829 		    "/etc/motd"), "r");
    830 #else
    831 		f = fopen("/etc/motd", "r");
    832 #endif
    833 		if (f) {
    834 			while (fgets(buf, sizeof(buf), f))
    835 				fputs(buf, stdout);
    836 			fclose(f);
    837 		}
    838 	}
    839 }
    840 
    841 
    842 /*
    843  * Check for quiet login, either .hushlogin or command given.
    844  */
    845 int
    846 check_quietlogin(Session *s, const char *command)
    847 {
    848 	char buf[256];
    849 	struct passwd *pw = s->pw;
    850 	struct stat st;
    851 
    852 	/* Return 1 if .hushlogin exists or a command given. */
    853 	if (command != NULL)
    854 		return 1;
    855 	snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
    856 #ifdef HAVE_LOGIN_CAP
    857 	if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
    858 		return 1;
    859 #else
    860 	if (stat(buf, &st) >= 0)
    861 		return 1;
    862 #endif
    863 	return 0;
    864 }
    865 
    866 /*
    867  * Sets the value of the given variable in the environment.  If the variable
    868  * already exists, its value is overriden.
    869  */
    870 void
    871 child_set_env(char ***envp, u_int *envsizep, const char *name,
    872 	const char *value)
    873 {
    874 	u_int i, namelen;
    875 	char **env;
    876 
    877 	debug3("child_set_env(%s, %s)", name, value);
    878 	/*
    879 	 * Find the slot where the value should be stored.  If the variable
    880 	 * already exists, we reuse the slot; otherwise we append a new slot
    881 	 * at the end of the array, expanding if necessary.
    882 	 */
    883 	env = *envp;
    884 	namelen = strlen(name);
    885 	for (i = 0; env[i]; i++)
    886 		if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
    887 			break;
    888 	if (env[i]) {
    889 		/* Reuse the slot. */
    890 		xfree(env[i]);
    891 	} else {
    892 		/* New variable.  Expand if necessary. */
    893 		if (i >= (*envsizep) - 1) {
    894 			if (*envsizep >= 1000)
    895 				fatal("child_set_env: too many env vars,"
    896 				    " skipping: %.100s", name);
    897 			(*envsizep) += 50;
    898 			env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
    899 		}
    900 		/* Need to set the NULL pointer at end of array beyond the new slot. */
    901 		env[i + 1] = NULL;
    902 	}
    903 
    904 	/* Allocate space and format the variable in the appropriate slot. */
    905 	env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
    906 	snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
    907 }
    908 
    909 /*
    910  * Reads environment variables from the given file and adds/overrides them
    911  * into the environment.  If the file does not exist, this does nothing.
    912  * Otherwise, it must consist of empty lines, comments (line starts with '#')
    913  * and assignments of the form name=value.  No other forms are allowed.
    914  */
    915 static void
    916 read_environment_file(char ***env, u_int *envsize,
    917 	const char *filename)
    918 {
    919 	FILE *f;
    920 	char buf[4096];
    921 	char *cp, *value;
    922 	u_int lineno = 0;
    923 
    924 	f = fopen(filename, "r");
    925 	if (!f)
    926 		return;
    927 
    928 	while (fgets(buf, sizeof(buf), f)) {
    929 		if (++lineno > 1000)
    930 			fatal("Too many lines in environment file %s", filename);
    931 		for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
    932 			;
    933 		if (!*cp || *cp == '#' || *cp == '\n')
    934 			continue;
    935 		if (strchr(cp, '\n'))
    936 			*strchr(cp, '\n') = '\0';
    937 		value = strchr(cp, '=');
    938 		if (value == NULL) {
    939 			fprintf(stderr, gettext("Bad line %u in %.100s\n"),
    940 				lineno, filename);
    941 			continue;
    942 		}
    943 		/*
    944 		 * Replace the equals sign by nul, and advance value to
    945 		 * the value string.
    946 		 */
    947 		*value = '\0';
    948 		value++;
    949 		child_set_env(env, envsize, cp, value);
    950 	}
    951 	fclose(f);
    952 }
    953 
    954 void copy_environment(char **source, char ***env, u_int *envsize)
    955 {
    956 	char *var_name, *var_val;
    957 	int i;
    958 
    959 	if (source == NULL)
    960 		return;
    961 
    962 	for(i = 0; source[i] != NULL; i++) {
    963 		var_name = xstrdup(source[i]);
    964 		if ((var_val = strstr(var_name, "=")) == NULL) {
    965 			xfree(var_name);
    966 			continue;
    967 		}
    968 		*var_val++ = '\0';
    969 
    970 		debug3("Copy environment: %s=%s", var_name, var_val);
    971 		child_set_env(env, envsize, var_name, var_val);
    972 
    973 		xfree(var_name);
    974 	}
    975 }
    976 
    977 #ifdef HAVE_DEFOPEN
    978 static
    979 void
    980 deflt_do_setup_env(Session *s, const char *shell, char ***env, u_int *envsize)
    981 {
    982 	int	flags;
    983 	char	*ptr;
    984 	mode_t	Umask = 022;
    985 
    986 	if (defopen(_PATH_DEFAULT_LOGIN))
    987 		return;
    988 
    989 	/* Ignore case */
    990 	flags = defcntl(DC_GETFLAGS, 0);
    991 	TURNOFF(flags, DC_CASE);
    992 	(void) defcntl(DC_SETFLAGS, flags);
    993 
    994 	/* TZ & HZ */
    995 	if ((ptr = defread("TIMEZONE=")) != NULL)
    996 		child_set_env(env, envsize, "TZ", ptr);
    997 	if ((ptr = defread("HZ=")) != NULL)
    998 		child_set_env(env, envsize, "HZ", ptr);
    999 
   1000 	/* PATH */
   1001 	if (s->pw->pw_uid != 0 && (ptr = defread("PATH=")) != NULL)
   1002 		child_set_env(env, envsize, "PATH", ptr);
   1003 	if (s->pw->pw_uid == 0 && (ptr = defread("SUPATH=")) != NULL)
   1004 		child_set_env(env, envsize, "PATH", ptr);
   1005 
   1006 	/* SHELL */
   1007 	if ((ptr = defread("ALTSHELL=")) != NULL) {
   1008 		if (strcasecmp("YES", ptr) == 0)
   1009 			child_set_env(env, envsize, "SHELL", shell);
   1010 		else
   1011 			child_set_env(env, envsize, "SHELL", "");
   1012 	}
   1013 
   1014 	/* UMASK */
   1015 	if ((ptr = defread("UMASK=")) != NULL &&
   1016 	    sscanf(ptr, "%lo", &Umask) == 1 &&
   1017 	    Umask <= (mode_t)0777)
   1018 		(void) umask(Umask);
   1019 	else
   1020 		(void) umask(022);
   1021 
   1022 	/* ULIMIT */
   1023 	if ((ptr = defread("ULIMIT=")) != NULL && atol(ptr) > 0L &&
   1024 	    ulimit(UL_SETFSIZE, atol(ptr)) < 0L)
   1025 		error("Could not set ULIMIT to %ld from %s\n", atol(ptr),
   1026 			_PATH_DEFAULT_LOGIN);
   1027 
   1028 	(void) defopen(NULL);
   1029 }
   1030 #endif /* HAVE_DEFOPEN */
   1031 
   1032 static char **
   1033 do_setup_env(Session *s, const char *shell)
   1034 {
   1035 	char buf[256];
   1036 	char path_maildir[] = _PATH_MAILDIR;
   1037 	u_int i, envsize, pm_len;
   1038 	char **env;
   1039 	struct passwd *pw = s->pw;
   1040 
   1041 	/* Initialize the environment. */
   1042 	envsize = 100;
   1043 	env = xmalloc(envsize * sizeof(char *));
   1044 	env[0] = NULL;
   1045 
   1046 #ifdef HAVE_CYGWIN
   1047 	/*
   1048 	 * The Windows environment contains some setting which are
   1049 	 * important for a running system. They must not be dropped.
   1050 	 */
   1051 	copy_environment(environ, &env, &envsize);
   1052 #endif
   1053 
   1054 #ifdef GSSAPI
   1055 	/* Allow any GSSAPI methods that we've used to alter
   1056 	 * the childs environment as they see fit
   1057 	 */
   1058 	ssh_gssapi_do_child(xxx_gssctxt, &env,&envsize);
   1059 #endif
   1060 
   1061 	if (!options.use_login) {
   1062 		/* Set basic environment. */
   1063 		child_set_env(&env, &envsize, "USER", pw->pw_name);
   1064 		child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
   1065 		child_set_env(&env, &envsize, "HOME", pw->pw_dir);
   1066 #ifdef HAVE_LOGIN_CAP
   1067 		if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)
   1068 			child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
   1069 		else
   1070 			child_set_env(&env, &envsize, "PATH", getenv("PATH"));
   1071 #else /* HAVE_LOGIN_CAP */
   1072 # ifndef HAVE_CYGWIN
   1073 		/*
   1074 		 * There's no standard path on Windows. The path contains
   1075 		 * important components pointing to the system directories,
   1076 		 * needed for loading shared libraries. So the path better
   1077 		 * remains intact here.
   1078 		 */
   1079 #  ifdef SUPERUSER_PATH
   1080 		child_set_env(&env, &envsize, "PATH",
   1081 		    s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH);
   1082 #  else
   1083 		child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
   1084 #  endif /* SUPERUSER_PATH */
   1085 # endif /* HAVE_CYGWIN */
   1086 #endif /* HAVE_LOGIN_CAP */
   1087 
   1088 		pm_len = strlen(path_maildir);
   1089 		if (path_maildir[pm_len - 1] == '/' && pm_len > 1)
   1090 			path_maildir[pm_len -