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