]> andersk Git - gssapi-openssh.git/blob - openssh/session.c
merged OpenSSH 3.4p1 to trunk
[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.142 2002/06/26 13:49:26 deraadt 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 enable_compression_after_reply = 0;
260         u_int proto_len, data_len, dlen, compression_level = 0;
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                         if (*envsizep >= 1000)
869                                 fatal("child_set_env: too many env vars,"
870                                     " skipping: %.100s", name);
871                         (*envsizep) += 50;
872                         env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
873                 }
874                 /* Need to set the NULL pointer at end of array beyond the new slot. */
875                 env[i + 1] = NULL;
876         }
877
878         /* Allocate space and format the variable in the appropriate slot. */
879         env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
880         snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
881 }
882
883 /*
884  * Reads environment variables from the given file and adds/overrides them
885  * into the environment.  If the file does not exist, this does nothing.
886  * Otherwise, it must consist of empty lines, comments (line starts with '#')
887  * and assignments of the form name=value.  No other forms are allowed.
888  */
889 static void
890 read_environment_file(char ***env, u_int *envsize,
891         const char *filename)
892 {
893         FILE *f;
894         char buf[4096];
895         char *cp, *value;
896         u_int lineno = 0;
897
898         f = fopen(filename, "r");
899         if (!f)
900                 return;
901
902         while (fgets(buf, sizeof(buf), f)) {
903                 if (++lineno > 1000)
904                         fatal("Too many lines in environment file %s", filename);
905                 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
906                         ;
907                 if (!*cp || *cp == '#' || *cp == '\n')
908                         continue;
909                 if (strchr(cp, '\n'))
910                         *strchr(cp, '\n') = '\0';
911                 value = strchr(cp, '=');
912                 if (value == NULL) {
913                         fprintf(stderr, "Bad line %u in %.100s\n", lineno,
914                             filename);
915                         continue;
916                 }
917                 /*
918                  * Replace the equals sign by nul, and advance value to
919                  * the value string.
920                  */
921                 *value = '\0';
922                 value++;
923                 child_set_env(env, envsize, cp, value);
924         }
925         fclose(f);
926 }
927
928 void copy_environment(char **source, char ***env, u_int *envsize)
929 {
930         char *var_name, *var_val;
931         int i;
932
933         if (source == NULL)
934                 return;
935
936         for(i = 0; source[i] != NULL; i++) {
937                 var_name = xstrdup(source[i]);
938                 if ((var_val = strstr(var_name, "=")) == NULL) {
939                         xfree(var_name);
940                         continue;
941                 }
942                 *var_val++ = '\0';
943
944                 debug3("Copy environment: %s=%s", var_name, var_val);
945                 child_set_env(env, envsize, var_name, var_val);
946                 
947                 xfree(var_name);
948         }
949 }
950
951 static char **
952 do_setup_env(Session *s, const char *shell)
953 {
954         char buf[256];
955         u_int i, envsize;
956         char **env;
957         struct passwd *pw = s->pw;
958
959         /* Initialize the environment. */
960         envsize = 100;
961         env = xmalloc(envsize * sizeof(char *));
962         env[0] = NULL;
963
964 #ifdef HAVE_CYGWIN
965         /*
966          * The Windows environment contains some setting which are
967          * important for a running system. They must not be dropped.
968          */
969         copy_environment(environ, &env, &envsize);
970 #endif
971
972 #ifdef GSSAPI
973         /* Allow any GSSAPI methods that we've used to alter 
974          * the childs environment as they see fit
975          */
976         ssh_gssapi_do_child(&env,&envsize);
977 #endif
978
979         if (!options.use_login) {
980                 /* Set basic environment. */
981                 child_set_env(&env, &envsize, "USER", pw->pw_name);
982                 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
983                 child_set_env(&env, &envsize, "HOME", pw->pw_dir);
984 #ifdef HAVE_LOGIN_CAP
985                 (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
986                 child_set_env(&env, &envsize, "PATH", getenv("PATH"));
987 #else /* HAVE_LOGIN_CAP */
988 # ifndef HAVE_CYGWIN
989                 /*
990                  * There's no standard path on Windows. The path contains
991                  * important components pointing to the system directories,
992                  * needed for loading shared libraries. So the path better
993                  * remains intact here.
994                  */
995 #  ifdef SUPERUSER_PATH
996                 child_set_env(&env, &envsize, "PATH", 
997                     s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH);
998 #  else 
999                 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1000 #  endif /* SUPERUSER_PATH */
1001 # endif /* HAVE_CYGWIN */
1002 #endif /* HAVE_LOGIN_CAP */
1003
1004                 snprintf(buf, sizeof buf, "%.200s/%.50s",
1005                          _PATH_MAILDIR, pw->pw_name);
1006                 child_set_env(&env, &envsize, "MAIL", buf);
1007
1008                 /* Normal systems set SHELL by default. */
1009                 child_set_env(&env, &envsize, "SHELL", shell);
1010         }
1011         if (getenv("TZ"))
1012                 child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1013
1014         /* Set custom environment options from RSA authentication. */
1015         if (!options.use_login) {
1016                 while (custom_environment) {
1017                         struct envstring *ce = custom_environment;
1018                         char *s = ce->s;
1019
1020                         for (i = 0; s[i] != '=' && s[i]; i++)
1021                                 ;
1022                         if (s[i] == '=') {
1023                                 s[i] = 0;
1024                                 child_set_env(&env, &envsize, s, s + i + 1);
1025                         }
1026                         custom_environment = ce->next;
1027                         xfree(ce->s);
1028                         xfree(ce);
1029                 }
1030         }
1031
1032         snprintf(buf, sizeof buf, "%.50s %d %d",
1033             get_remote_ipaddr(), get_remote_port(), get_local_port());
1034         child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1035
1036         if (s->ttyfd != -1)
1037                 child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1038         if (s->term)
1039                 child_set_env(&env, &envsize, "TERM", s->term);
1040         if (s->display)
1041                 child_set_env(&env, &envsize, "DISPLAY", s->display);
1042         if (original_command)
1043                 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1044                     original_command);
1045
1046 #ifdef _AIX
1047         {
1048                 char *cp;
1049
1050                 if ((cp = getenv("AUTHSTATE")) != NULL)
1051                         child_set_env(&env, &envsize, "AUTHSTATE", cp);
1052                 if ((cp = getenv("KRB5CCNAME")) != NULL)
1053                         child_set_env(&env, &envsize, "KRB5CCNAME", cp);
1054                 read_environment_file(&env, &envsize, "/etc/environment");
1055         }
1056 #endif
1057 #ifdef KRB4
1058         if (s->authctxt->krb4_ticket_file)
1059                 child_set_env(&env, &envsize, "KRBTKFILE",
1060                     s->authctxt->krb4_ticket_file);
1061 #endif
1062 #ifdef KRB5
1063         if (s->authctxt->krb5_ticket_file)
1064                 child_set_env(&env, &envsize, "KRB5CCNAME",
1065                     s->authctxt->krb5_ticket_file);
1066 #endif
1067 #ifdef USE_PAM
1068         /* Pull in any environment variables that may have been set by PAM. */
1069         copy_environment(fetch_pam_environment(), &env, &envsize);
1070 #endif /* USE_PAM */
1071
1072         if (auth_sock_name != NULL)
1073                 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1074                     auth_sock_name);
1075
1076         /* read $HOME/.ssh/environment. */
1077         if (!options.use_login) {
1078                 snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
1079                     pw->pw_dir);
1080                 read_environment_file(&env, &envsize, buf);
1081         }
1082         if (debug_flag) {
1083                 /* dump the environment */
1084                 fprintf(stderr, "Environment:\n");
1085                 for (i = 0; env[i]; i++)
1086                         fprintf(stderr, "  %.200s\n", env[i]);
1087         }
1088         return env;
1089 }
1090
1091 /*
1092  * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
1093  * first in this order).
1094  */
1095 static void
1096 do_rc_files(Session *s, const char *shell)
1097 {
1098         FILE *f = NULL;
1099         char cmd[1024];
1100         int do_xauth;
1101         struct stat st;
1102
1103         do_xauth =
1104             s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
1105
1106         /* ignore _PATH_SSH_USER_RC for subsystems */
1107         if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
1108                 snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
1109                     shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
1110                 if (debug_flag)
1111                         fprintf(stderr, "Running %s\n", cmd);
1112                 f = popen(cmd, "w");
1113                 if (f) {
1114                         if (do_xauth)
1115                                 fprintf(f, "%s %s\n", s->auth_proto,
1116                                     s->auth_data);
1117                         pclose(f);
1118                 } else
1119                         fprintf(stderr, "Could not run %s\n",
1120                             _PATH_SSH_USER_RC);
1121         } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
1122                 if (debug_flag)
1123                         fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
1124                             _PATH_SSH_SYSTEM_RC);
1125                 f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
1126                 if (f) {
1127                         if (do_xauth)
1128                                 fprintf(f, "%s %s\n", s->auth_proto,
1129                                     s->auth_data);
1130                         pclose(f);
1131                 } else
1132                         fprintf(stderr, "Could not run %s\n",
1133                             _PATH_SSH_SYSTEM_RC);
1134         } else if (do_xauth && options.xauth_location != NULL) {
1135                 /* Add authority data to .Xauthority if appropriate. */
1136                 if (debug_flag) {
1137                         fprintf(stderr,
1138                             "Running %.500s add "
1139                             "%.100s %.100s %.100s\n",
1140                             options.xauth_location, s->auth_display,
1141                             s->auth_proto, s->auth_data);
1142                 }
1143                 snprintf(cmd, sizeof cmd, "%s -q -",
1144                     options.xauth_location);
1145                 f = popen(cmd, "w");
1146                 if (f) {
1147                         fprintf(f, "add %s %s %s\n",
1148                             s->auth_display, s->auth_proto,
1149                             s->auth_data);
1150                         pclose(f);
1151                 } else {
1152                         fprintf(stderr, "Could not run %s\n",
1153                             cmd);
1154                 }
1155         }
1156 }
1157
1158 static void
1159 do_nologin(struct passwd *pw)
1160 {
1161         FILE *f = NULL;
1162         char buf[1024];
1163
1164 #ifdef HAVE_LOGIN_CAP
1165         if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
1166                 f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
1167                     _PATH_NOLOGIN), "r");
1168 #else
1169         if (pw->pw_uid)
1170                 f = fopen(_PATH_NOLOGIN, "r");
1171 #endif
1172         if (f) {
1173                 /* /etc/nologin exists.  Print its contents and exit. */
1174                 while (fgets(buf, sizeof(buf), f))
1175                         fputs(buf, stderr);
1176                 fclose(f);
1177                 exit(254);
1178         }
1179 }
1180
1181 /* Set login name, uid, gid, and groups. */
1182 void
1183 do_setusercontext(struct passwd *pw)
1184 {
1185         char tty='\0';
1186
1187 #ifdef HAVE_CYGWIN
1188         if (is_winnt) {
1189 #else /* HAVE_CYGWIN */
1190         if (getuid() == 0 || geteuid() == 0) {
1191 #endif /* HAVE_CYGWIN */
1192 #ifdef HAVE_SETPCRED
1193                 setpcred(pw->pw_name);
1194 #endif /* HAVE_SETPCRED */
1195 #ifdef HAVE_LOGIN_CAP
1196 #ifdef __bsdi__
1197                 setpgid(0, 0);
1198 #endif
1199                 if (setusercontext(lc, pw, pw->pw_uid,
1200                     (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
1201                         perror("unable to set user context");
1202                         exit(1);
1203                 }
1204 #else
1205 # if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
1206                 /* Sets login uid for accounting */
1207                 if (getluid() == -1 && setluid(pw->pw_uid) == -1)
1208                         error("setluid: %s", strerror(errno));
1209 # endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
1210
1211                 if (setlogin(pw->pw_name) < 0)
1212                         error("setlogin failed: %s", strerror(errno));
1213                 if (setgid(pw->pw_gid) < 0) {
1214                         perror("setgid");
1215                         exit(1);
1216                 }
1217                 /* Initialize the group list. */
1218                 if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
1219                         perror("initgroups");
1220                         exit(1);
1221                 }
1222                 endgrent();
1223 # ifdef USE_PAM
1224                 /*
1225                  * PAM credentials may take the form of supplementary groups. 
1226                  * These will have been wiped by the above initgroups() call.
1227                  * Reestablish them here.
1228                  */
1229                 do_pam_setcred(0);
1230 # endif /* USE_PAM */
1231 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
1232                 irix_setusercontext(pw);
1233 #  endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1234 # ifdef _AIX
1235                 /* XXX: Disable tty setting.  Enabled if required later */
1236                 aix_usrinfo(pw, &tty, -1);
1237 # endif /* _AIX */
1238                 /* Permanently switch to the desired uid. */
1239                 permanently_set_uid(pw);
1240 #endif
1241         }
1242         if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1243                 fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1244 }
1245
1246 static void
1247 launch_login(struct passwd *pw, const char *hostname)
1248 {
1249         /* Launch login(1). */
1250
1251         execl(LOGIN_PROGRAM, "login", "-h", hostname,
1252 #ifdef xxxLOGIN_NEEDS_TERM
1253                     (s->term ? s->term : "unknown"),
1254 #endif /* LOGIN_NEEDS_TERM */
1255 #ifdef LOGIN_NO_ENDOPT
1256             "-p", "-f", pw->pw_name, (char *)NULL);
1257 #else
1258             "-p", "-f", "--", pw->pw_name, (char *)NULL);
1259 #endif
1260
1261         /* Login couldn't be executed, die. */
1262
1263         perror("login");
1264         exit(1);
1265 }
1266
1267 /*
1268  * Performs common processing for the child, such as setting up the
1269  * environment, closing extra file descriptors, setting the user and group
1270  * ids, and executing the command or shell.
1271  */
1272 void
1273 do_child(Session *s, const char *command)
1274 {
1275         extern char **environ;
1276         char **env;
1277         char *argv[10];
1278         const char *shell, *shell0, *hostname = NULL;
1279         struct passwd *pw = s->pw;
1280         u_int i;
1281
1282         /* remove hostkey from the child's memory */
1283         destroy_sensitive_data();
1284
1285         /* login(1) is only called if we execute the login shell */
1286         if (options.use_login && command != NULL)
1287                 options.use_login = 0;
1288
1289         /*
1290          * Login(1) does this as well, and it needs uid 0 for the "-h"
1291          * switch, so we let login(1) to this for us.
1292          */
1293         if (!options.use_login) {
1294 #ifdef HAVE_OSF_SIA
1295                 session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty);
1296                 if (!check_quietlogin(s, command))
1297                         do_motd();
1298 #else /* HAVE_OSF_SIA */
1299                 do_nologin(pw);
1300                 do_setusercontext(pw);
1301 #endif /* HAVE_OSF_SIA */
1302         }
1303
1304         /*
1305          * Get the shell from the password data.  An empty shell field is
1306          * legal, and means /bin/sh.
1307          */
1308         shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1309 #ifdef HAVE_LOGIN_CAP
1310         shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
1311 #endif
1312
1313         env = do_setup_env(s, shell);
1314
1315         /* we have to stash the hostname before we close our socket. */
1316         if (options.use_login)
1317                 hostname = get_remote_name_or_ip(utmp_len,
1318                     options.verify_reverse_mapping);
1319         /*
1320          * Close the connection descriptors; note that this is the child, and
1321          * the server will still have the socket open, and it is important
1322          * that we do not shutdown it.  Note that the descriptors cannot be
1323          * closed before building the environment, as we call
1324          * get_remote_ipaddr there.
1325          */
1326         if (packet_get_connection_in() == packet_get_connection_out())
1327                 close(packet_get_connection_in());
1328         else {
1329                 close(packet_get_connection_in());
1330                 close(packet_get_connection_out());
1331         }
1332         /*
1333          * Close all descriptors related to channels.  They will still remain
1334          * open in the parent.
1335          */
1336         /* XXX better use close-on-exec? -markus */
1337         channel_close_all();
1338
1339         /*
1340          * Close any extra file descriptors.  Note that there may still be
1341          * descriptors left by system functions.  They will be closed later.
1342          */
1343         endpwent();
1344
1345         /*
1346          * Close any extra open file descriptors so that we don\'t have them
1347          * hanging around in clients.  Note that we want to do this after
1348          * initgroups, because at least on Solaris 2.3 it leaves file
1349          * descriptors open.
1350          */
1351         for (i = 3; i < 64; i++)
1352                 close(i);
1353
1354         /*
1355          * Must take new environment into use so that .ssh/rc,
1356          * /etc/ssh/sshrc and xauth are run in the proper environment.
1357          */
1358         environ = env;
1359
1360 #ifdef AFS
1361         /* Try to get AFS tokens for the local cell. */
1362         if (k_hasafs()) {
1363                 char cell[64];
1364
1365                 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1366                         krb_afslog(cell, 0);
1367
1368                 krb_afslog(0, 0);
1369         }
1370 #endif /* AFS */
1371
1372         /* Change current directory to the user\'s home directory. */
1373         if (chdir(pw->pw_dir) < 0) {
1374                 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1375                     pw->pw_dir, strerror(errno));
1376 #ifdef HAVE_LOGIN_CAP
1377                 if (login_getcapbool(lc, "requirehome", 0))
1378                         exit(1);
1379 #endif
1380         }
1381
1382         if (!options.use_login)
1383                 do_rc_files(s, shell);
1384
1385         /* restore SIGPIPE for child */
1386         signal(SIGPIPE,  SIG_DFL);
1387
1388         if (options.use_login) {
1389                 launch_login(pw, hostname);
1390                 /* NEVERREACHED */
1391         }
1392
1393         /* Get the last component of the shell name. */
1394         if ((shell0 = strrchr(shell, '/')) != NULL)
1395                 shell0++;
1396         else
1397                 shell0 = shell;
1398
1399         /*
1400          * If we have no command, execute the shell.  In this case, the shell
1401          * name to be passed in argv[0] is preceded by '-' to indicate that
1402          * this is a login shell.
1403          */
1404         if (!command) {
1405                 char argv0[256];
1406
1407                 /* Start the shell.  Set initial character to '-'. */
1408                 argv0[0] = '-';
1409
1410                 if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
1411                     >= sizeof(argv0) - 1) {
1412                         errno = EINVAL;
1413                         perror(shell);
1414                         exit(1);
1415                 }
1416
1417                 /* Execute the shell. */
1418                 argv[0] = argv0;
1419                 argv[1] = NULL;
1420                 execve(shell, argv, env);
1421
1422                 /* Executing the shell failed. */
1423                 perror(shell);
1424                 exit(1);
1425         }
1426         /*
1427          * Execute the command using the user's shell.  This uses the -c
1428          * option to execute the command.
1429          */
1430         argv[0] = (char *) shell0;
1431         argv[1] = "-c";
1432         argv[2] = (char *) command;
1433         argv[3] = NULL;
1434         execve(shell, argv, env);
1435         perror(shell);
1436         exit(1);
1437 }
1438
1439 Session *
1440 session_new(void)
1441 {
1442         int i;
1443         static int did_init = 0;
1444         if (!did_init) {
1445                 debug("session_new: init");
1446                 for (i = 0; i < MAX_SESSIONS; i++) {
1447                         sessions[i].used = 0;
1448                 }
1449                 did_init = 1;
1450         }
1451         for (i = 0; i < MAX_SESSIONS; i++) {
1452                 Session *s = &sessions[i];
1453                 if (! s->used) {
1454                         memset(s, 0, sizeof(*s));
1455                         s->chanid = -1;
1456                         s->ptyfd = -1;
1457                         s->ttyfd = -1;
1458                         s->used = 1;
1459                         s->self = i;
1460                         debug("session_new: session %d", i);
1461                         return s;
1462                 }
1463         }
1464         return NULL;
1465 }
1466
1467 static void
1468 session_dump(void)
1469 {
1470         int i;
1471         for (i = 0; i < MAX_SESSIONS; i++) {
1472                 Session *s = &sessions[i];
1473                 debug("dump: used %d session %d %p channel %d pid %ld",
1474                     s->used,
1475                     s->self,
1476                     s,
1477                     s->chanid,
1478                     (long)s->pid);
1479         }
1480 }
1481
1482 int
1483 session_open(Authctxt *authctxt, int chanid)
1484 {
1485         Session *s = session_new();
1486         debug("session_open: channel %d", chanid);
1487         if (s == NULL) {
1488                 error("no more sessions");
1489                 return 0;
1490         }
1491         s->authctxt = authctxt;
1492         s->pw = authctxt->pw;
1493         if (s->pw == NULL)
1494                 fatal("no user for session %d", s->self);
1495         debug("session_open: session %d: link with channel %d", s->self, chanid);
1496         s->chanid = chanid;
1497         return 1;
1498 }
1499
1500 Session *
1501 session_by_tty(char *tty)
1502 {
1503         int i;
1504         for (i = 0; i < MAX_SESSIONS; i++) {
1505                 Session *s = &sessions[i];
1506                 if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
1507                         debug("session_by_tty: session %d tty %s", i, tty);
1508                         return s;
1509                 }
1510         }
1511         debug("session_by_tty: unknown tty %.100s", tty);
1512         session_dump();
1513         return NULL;
1514 }
1515
1516 static Session *
1517 session_by_channel(int id)
1518 {
1519         int i;
1520         for (i = 0; i < MAX_SESSIONS; i++) {
1521                 Session *s = &sessions[i];
1522                 if (s->used && s->chanid == id) {
1523                         debug("session_by_channel: session %d channel %d", i, id);
1524                         return s;
1525                 }
1526         }
1527         debug("session_by_channel: unknown channel %d", id);
1528         session_dump();
1529         return NULL;
1530 }
1531
1532 static Session *
1533 session_by_pid(pid_t pid)
1534 {
1535         int i;
1536         debug("session_by_pid: pid %ld", (long)pid);
1537         for (i = 0; i < MAX_SESSIONS; i++) {
1538                 Session *s = &sessions[i];
1539                 if (s->used && s->pid == pid)
1540                         return s;
1541         }
1542         error("session_by_pid: unknown pid %ld", (long)pid);
1543         session_dump();
1544         return NULL;
1545 }
1546
1547 static int
1548 session_window_change_req(Session *s)
1549 {
1550         s->col = packet_get_int();
1551         s->row = packet_get_int();
1552         s->xpixel = packet_get_int();
1553         s->ypixel = packet_get_int();
1554         packet_check_eom();
1555         pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1556         return 1;
1557 }
1558
1559 static int
1560 session_pty_req(Session *s)
1561 {
1562         u_int len;
1563         int n_bytes;
1564
1565         if (no_pty_flag) {
1566                 debug("Allocating a pty not permitted for this authentication.");
1567                 return 0;
1568         }
1569         if (s->ttyfd != -1) {
1570                 packet_disconnect("Protocol error: you already have a pty.");
1571                 return 0;
1572         }
1573         /* Get the time and hostname when the user last logged in. */
1574         if (options.print_lastlog) {
1575                 s->hostname[0] = '\0';
1576                 s->last_login_time = get_last_login_time(s->pw->pw_uid,
1577                     s->pw->pw_name, s->hostname, sizeof(s->hostname));
1578         }
1579
1580         s->term = packet_get_string(&len);
1581
1582         if (compat20) {
1583                 s->col = packet_get_int();
1584                 s->row = packet_get_int();
1585         } else {
1586                 s->row = packet_get_int();
1587                 s->col = packet_get_int();
1588         }
1589         s->xpixel = packet_get_int();
1590         s->ypixel = packet_get_int();
1591
1592         if (strcmp(s->term, "") == 0) {
1593                 xfree(s->term);
1594                 s->term = NULL;
1595         }
1596
1597         /* Allocate a pty and open it. */
1598         debug("Allocating pty.");
1599         if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) {
1600                 if (s->term)
1601                         xfree(s->term);
1602                 s->term = NULL;
1603                 s->ptyfd = -1;
1604                 s->ttyfd = -1;
1605                 error("session_pty_req: session %d alloc failed", s->self);
1606                 return 0;
1607         }
1608         debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1609
1610         /* for SSH1 the tty modes length is not given */
1611         if (!compat20)
1612                 n_bytes = packet_remaining();
1613         tty_parse_modes(s->ttyfd, &n_bytes);
1614
1615         /*
1616          * Add a cleanup function to clear the utmp entry and record logout
1617          * time in case we call fatal() (e.g., the connection gets closed).
1618          */
1619         fatal_add_cleanup(session_pty_cleanup, (void *)s);
1620         if (!use_privsep)
1621                 pty_setowner(s->pw, s->tty);
1622
1623         /* Set window size from the packet. */
1624         pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1625
1626         packet_check_eom();
1627         session_proctitle(s);
1628         return 1;
1629 }
1630
1631 static int
1632 session_subsystem_req(Session *s)
1633 {
1634         struct stat st;
1635         u_int len;
1636         int success = 0;
1637         char *cmd, *subsys = packet_get_string(&len);
1638         int i;
1639
1640         packet_check_eom();
1641         log("subsystem request for %.100s", subsys);
1642
1643         for (i = 0; i < options.num_subsystems; i++) {
1644                 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
1645                         cmd = options.subsystem_command[i];
1646                         if (stat(cmd, &st) < 0) {
1647                                 error("subsystem: cannot stat %s: %s", cmd,
1648                                     strerror(errno));
1649                                 break;
1650                         }
1651                         debug("subsystem: exec() %s", cmd);
1652                         s->is_subsystem = 1;
1653                         do_exec(s, cmd);
1654                         success = 1;
1655                         break;
1656                 }
1657         }
1658
1659         if (!success)
1660                 log("subsystem request for %.100s failed, subsystem not found",
1661                     subsys);
1662
1663         xfree(subsys);
1664         return success;
1665 }
1666
1667 static int
1668 session_x11_req(Session *s)
1669 {
1670         int success;
1671
1672         s->single_connection = packet_get_char();
1673         s->auth_proto = packet_get_string(NULL);
1674         s->auth_data = packet_get_string(NULL);
1675         s->screen = packet_get_int();
1676         packet_check_eom();
1677
1678         success = session_setup_x11fwd(s);
1679         if (!success) {
1680                 xfree(s->auth_proto);
1681                 xfree(s->auth_data);
1682                 s->auth_proto = NULL;
1683                 s->auth_data = NULL;
1684         }
1685         return success;
1686 }
1687
1688 static int
1689 session_shell_req(Session *s)
1690 {
1691         packet_check_eom();
1692         do_exec(s, NULL);
1693         return 1;
1694 }
1695
1696 static int
1697 session_exec_req(Session *s)
1698 {
1699         u_int len;
1700         char *command = packet_get_string(&len);
1701         packet_check_eom();
1702         do_exec(s, command);
1703         xfree(command);
1704         return 1;
1705 }
1706
1707 static int
1708 session_auth_agent_req(Session *s)
1709 {
1710         static int called = 0;
1711         packet_check_eom();
1712         if (no_agent_forwarding_flag) {
1713                 debug("session_auth_agent_req: no_agent_forwarding_flag");
1714                 return 0;
1715         }
1716         if (called) {
1717                 return 0;
1718         } else {
1719                 called = 1;
1720                 return auth_input_request_forwarding(s->pw);
1721         }
1722 }
1723
1724 int
1725 session_input_channel_req(Channel *c, const char *rtype)
1726 {
1727         int success = 0;
1728         Session *s;
1729
1730         if ((s = session_by_channel(c->self)) == NULL) {
1731                 log("session_input_channel_req: no session %d req %.100s",
1732                     c->self, rtype);
1733                 return 0;
1734         }
1735         debug("session_input_channel_req: session %d req %s", s->self, rtype);
1736
1737         /*
1738          * a session is in LARVAL state until a shell, a command
1739          * or a subsystem is executed
1740          */
1741         if (c->type == SSH_CHANNEL_LARVAL) {
1742                 if (strcmp(rtype, "shell") == 0) {
1743                         success = session_shell_req(s);
1744                 } else if (strcmp(rtype, "exec") == 0) {
1745                         success = session_exec_req(s);
1746                 } else if (strcmp(rtype, "pty-req") == 0) {
1747                         success =  session_pty_req(s);
1748                 } else if (strcmp(rtype, "x11-req") == 0) {
1749                         success = session_x11_req(s);
1750                 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
1751                         success = session_auth_agent_req(s);
1752                 } else if (strcmp(rtype, "subsystem") == 0) {
1753                         success = session_subsystem_req(s);
1754                 }
1755         }
1756         if (strcmp(rtype, "window-change") == 0) {
1757                 success = session_window_change_req(s);
1758         }
1759         return success;
1760 }
1761
1762 void
1763 session_set_fds(Session *s, int fdin, int fdout, int fderr)
1764 {
1765         if (!compat20)
1766                 fatal("session_set_fds: called for proto != 2.0");
1767         /*
1768          * now that have a child and a pipe to the child,
1769          * we can activate our channel and register the fd's
1770          */
1771         if (s->chanid == -1)
1772                 fatal("no channel for session %d", s->self);
1773         channel_set_fds(s->chanid,
1774             fdout, fdin, fderr,
1775             fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1776             1,
1777             CHAN_SES_WINDOW_DEFAULT);
1778 }
1779
1780 /*
1781  * Function to perform pty cleanup. Also called if we get aborted abnormally
1782  * (e.g., due to a dropped connection).
1783  */
1784 void
1785 session_pty_cleanup2(void *session)
1786 {
1787         Session *s = session;
1788
1789         if (s == NULL) {
1790                 error("session_pty_cleanup: no session");
1791                 return;
1792         }
1793         if (s->ttyfd == -1)
1794                 return;
1795
1796         debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
1797
1798         /* Record that the user has logged out. */
1799         if (s->pid != 0)
1800                 record_logout(s->pid, s->tty, s->pw->pw_name);
1801
1802         /* Release the pseudo-tty. */
1803         if (getuid() == 0)
1804                 pty_release(s->tty);
1805
1806         /*
1807          * Close the server side of the socket pairs.  We must do this after
1808          * the pty cleanup, so that another process doesn't get this pty
1809          * while we're still cleaning up.
1810          */
1811         if (close(s->ptymaster) < 0)
1812                 error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno));
1813
1814         /* unlink pty from session */
1815         s->ttyfd = -1;
1816 }
1817
1818 void
1819 session_pty_cleanup(void *session)
1820 {
1821         PRIVSEP(session_pty_cleanup2(session));
1822 }
1823
1824 static void
1825 session_exit_message(Session *s, int status)
1826 {
1827         Channel *c;
1828
1829         if ((c = channel_lookup(s->chanid)) == NULL)
1830                 fatal("session_exit_message: session %d: no channel %d",
1831                     s->self, s->chanid);
1832         debug("session_exit_message: session %d channel %d pid %ld",
1833             s->self, s->chanid, (long)s->pid);
1834
1835         if (WIFEXITED(status)) {
1836                 channel_request_start(s->chanid, "exit-status", 0);
1837                 packet_put_int(WEXITSTATUS(status));
1838                 packet_send();
1839         } else if (WIFSIGNALED(status)) {
1840                 channel_request_start(s->chanid, "exit-signal", 0);
1841                 packet_put_int(WTERMSIG(status));
1842 #ifdef WCOREDUMP
1843                 packet_put_char(WCOREDUMP(status));
1844 #else /* WCOREDUMP */
1845                 packet_put_char(0);
1846 #endif /* WCOREDUMP */
1847                 packet_put_cstring("");
1848                 packet_put_cstring("");
1849                 packet_send();
1850         } else {
1851                 /* Some weird exit cause.  Just exit. */
1852                 packet_disconnect("wait returned status %04x.", status);
1853         }
1854
1855         /* disconnect channel */
1856         debug("session_exit_message: release channel %d", s->chanid);
1857         channel_cancel_cleanup(s->chanid);
1858         /*
1859          * emulate a write failure with 'chan_write_failed', nobody will be
1860          * interested in data we write.
1861          * Note that we must not call 'chan_read_failed', since there could
1862          * be some more data waiting in the pipe.
1863          */
1864         if (c->ostate != CHAN_OUTPUT_CLOSED)
1865                 chan_write_failed(c);
1866         s->chanid = -1;
1867 }
1868
1869 void
1870 session_close(Session *s)
1871 {
1872         debug("session_close: session %d pid %ld", s->self, (long)s->pid);
1873         if (s->ttyfd != -1) {
1874                 fatal_remove_cleanup(session_pty_cleanup, (void *)s);
1875                 session_pty_cleanup(s);
1876         }
1877         if (s->term)
1878                 xfree(s->term);
1879         if (s->display)
1880                 xfree(s->display);
1881         if (s->auth_display)
1882                 xfree(s->auth_display);
1883         if (s->auth_data)
1884                 xfree(s->auth_data);
1885         if (s->auth_proto)
1886                 xfree(s->auth_proto);
1887         s->used = 0;
1888         session_proctitle(s);
1889 }
1890
1891 void
1892 session_close_by_pid(pid_t pid, int status)
1893 {
1894         Session *s = session_by_pid(pid);
1895         if (s == NULL) {
1896                 debug("session_close_by_pid: no session for pid %ld",
1897                     (long)pid);
1898                 return;
1899         }
1900         if (s->chanid != -1)
1901                 session_exit_message(s, status);
1902         session_close(s);
1903 }
1904
1905 /*
1906  * this is called when a channel dies before
1907  * the session 'child' itself dies
1908  */
1909 void
1910 session_close_by_channel(int id, void *arg)
1911 {
1912         Session *s = session_by_channel(id);
1913         if (s == NULL) {
1914                 debug("session_close_by_channel: no session for id %d", id);
1915                 return;
1916         }
1917         debug("session_close_by_channel: channel %d child %ld",
1918             id, (long)s->pid);
1919         if (s->pid != 0) {
1920                 debug("session_close_by_channel: channel %d: has child", id);
1921                 /*
1922                  * delay detach of session, but release pty, since
1923                  * the fd's to the child are already closed
1924                  */
1925                 if (s->ttyfd != -1) {
1926                         fatal_remove_cleanup(session_pty_cleanup, (void *)s);
1927                         session_pty_cleanup(s);
1928                 }
1929                 return;
1930         }
1931         /* detach by removing callback */
1932         channel_cancel_cleanup(s->chanid);
1933         s->chanid = -1;
1934         session_close(s);
1935 }
1936
1937 void
1938 session_destroy_all(void (*closefunc)(Session *))
1939 {
1940         int i;
1941         for (i = 0; i < MAX_SESSIONS; i++) {
1942                 Session *s = &sessions[i];
1943                 if (s->used) {
1944                         if (closefunc != NULL)
1945                                 closefunc(s);
1946                         else
1947                                 session_close(s);
1948                 }
1949         }
1950 }
1951
1952 static char *
1953 session_tty_list(void)
1954 {
1955         static char buf[1024];
1956         int i;
1957         buf[0] = '\0';
1958         for (i = 0; i < MAX_SESSIONS; i++) {
1959                 Session *s = &sessions[i];
1960                 if (s->used && s->ttyfd != -1) {
1961                         if (buf[0] != '\0')
1962                                 strlcat(buf, ",", sizeof buf);
1963                         strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
1964                 }
1965         }
1966         if (buf[0] == '\0')
1967                 strlcpy(buf, "notty", sizeof buf);
1968         return buf;
1969 }
1970
1971 void
1972 session_proctitle(Session *s)
1973 {
1974         if (s->pw == NULL)
1975                 error("no user for session %d", s->self);
1976         else
1977                 setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
1978 }
1979
1980 int
1981 session_setup_x11fwd(Session *s)
1982 {
1983         struct stat st;
1984         char display[512], auth_display[512];
1985         char hostname[MAXHOSTNAMELEN];
1986
1987         if (no_x11_forwarding_flag) {
1988                 packet_send_debug("X11 forwarding disabled in user configuration file.");
1989                 return 0;
1990         }
1991         if (!options.x11_forwarding) {
1992                 debug("X11 forwarding disabled in server configuration file.");
1993                 return 0;
1994         }
1995         if (!options.xauth_location ||
1996             (stat(options.xauth_location, &st) == -1)) {
1997                 packet_send_debug("No xauth program; cannot forward with spoofing.");
1998                 return 0;
1999         }
2000         if (options.use_login) {
2001                 packet_send_debug("X11 forwarding disabled; "
2002                     "not compatible with UseLogin=yes.");
2003                 return 0;
2004         }
2005         if (s->display != NULL) {
2006                 debug("X11 display already set.");
2007                 return 0;
2008         }
2009         if (x11_create_display_inet(options.x11_display_offset,
2010             options.x11_use_localhost, s->single_connection,
2011             &s->display_number) == -1) {
2012                 debug("x11_create_display_inet failed.");
2013                 return 0;
2014         }
2015
2016         /* Set up a suitable value for the DISPLAY variable. */
2017         if (gethostname(hostname, sizeof(hostname)) < 0)
2018                 fatal("gethostname: %.100s", strerror(errno));
2019         /*
2020          * auth_display must be used as the displayname when the
2021          * authorization entry is added with xauth(1).  This will be
2022          * different than the DISPLAY string for localhost displays.
2023          */
2024         if (options.x11_use_localhost) {
2025                 snprintf(display, sizeof display, "localhost:%u.%u",
2026                     s->display_number, s->screen);
2027                 snprintf(auth_display, sizeof auth_display, "unix:%u.%u",
2028                     s->display_number, s->screen);
2029                 s->display = xstrdup(display);
2030                 s->auth_display = xstrdup(auth_display);
2031         } else {
2032 #ifdef IPADDR_IN_DISPLAY
2033                 struct hostent *he;
2034                 struct in_addr my_addr;
2035
2036                 he = gethostbyname(hostname);
2037                 if (he == NULL) {
2038                         error("Can't get IP address for X11 DISPLAY.");
2039                         packet_send_debug("Can't get IP address for X11 DISPLAY.");
2040                         return 0;
2041                 }
2042                 memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
2043                 snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr),
2044                     s->display_number, s->screen);
2045 #else
2046                 snprintf(display, sizeof display, "%.400s:%u.%u", hostname,
2047                     s->display_number, s->screen);
2048 #endif
2049                 s->display = xstrdup(display);
2050                 s->auth_display = xstrdup(display);
2051         }
2052
2053         return 1;
2054 }
2055
2056 static void
2057 do_authenticated2(Authctxt *authctxt)
2058 {
2059         server_loop2(authctxt);
2060 #if defined(GSSAPI)
2061         ssh_gssapi_cleanup_creds(NULL);
2062 #endif
2063 }
This page took 0.616275 seconds and 5 git commands to generate.