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