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