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