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