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