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