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