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