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