]> andersk Git - gssapi-openssh.git/blob - openssh/session.c
36b67180c3a3b2627158f4a37a82f06c70d80a57
[gssapi-openssh.git] / openssh / session.c
1 /* $OpenBSD: session.c,v 1.221 2007/01/21 01:41:54 stevesk Exp $ */
2 /*
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  *
6  * As far as I am concerned, the code I have written for this software
7  * can be used freely for any purpose.  Any derived versions of this
8  * software must be clearly marked as such, and if the derived work is
9  * incompatible with the protocol description in the RFC file, it must be
10  * called by a name other than "ssh" or "Secure Shell".
11  *
12  * SSH2 support by Markus Friedl.
13  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include "includes.h"
37
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #ifdef HAVE_SYS_STAT_H
41 # include <sys/stat.h>
42 #endif
43 #include <sys/socket.h>
44 #include <sys/un.h>
45 #include <sys/wait.h>
46
47 #include <arpa/inet.h>
48
49 #include <errno.h>
50 #include <grp.h>
51 #ifdef HAVE_PATHS_H
52 #include <paths.h>
53 #endif
54 #include <pwd.h>
55 #include <signal.h>
56 #include <stdarg.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <unistd.h>
61
62 #include "xmalloc.h"
63 #include "ssh.h"
64 #include "ssh1.h"
65 #include "ssh2.h"
66 #include "sshpty.h"
67 #include "packet.h"
68 #include "buffer.h"
69 #include "match.h"
70 #include "uidswap.h"
71 #include "compat.h"
72 #include "channels.h"
73 #include "key.h"
74 #include "cipher.h"
75 #ifdef GSSAPI
76 #include "ssh-gss.h"
77 #endif
78 #include "hostfile.h"
79 #include "auth.h"
80 #include "auth-options.h"
81 #include "pathnames.h"
82 #include "log.h"
83 #include "servconf.h"
84 #include "sshlogin.h"
85 #include "serverloop.h"
86 #include "canohost.h"
87 #include "session.h"
88 #include "kex.h"
89 #include "monitor_wrap.h"
90
91 #if defined(KRB5) && defined(USE_AFS)
92 #include <kafs.h>
93 #endif
94
95 /* func */
96
97 Session *session_new(void);
98 void    session_set_fds(Session *, int, int, int);
99 void    session_pty_cleanup(Session *);
100 void    session_proctitle(Session *);
101 int     session_setup_x11fwd(Session *);
102 void    do_exec_pty(Session *, const char *);
103 void    do_exec_no_pty(Session *, const char *);
104 void    do_exec(Session *, const char *);
105 void    do_login(Session *, const char *);
106 #ifdef LOGIN_NEEDS_UTMPX
107 static void     do_pre_login(Session *s);
108 #endif
109 void    do_child(Session *, const char *);
110 void    do_motd(void);
111 int     check_quietlogin(Session *, const char *);
112
113 static void do_authenticated1(Authctxt *);
114 static void do_authenticated2(Authctxt *);
115
116 static int session_pty_req(Session *);
117
118 #ifdef SESSION_HOOKS
119 static void execute_session_hook(char* prog, Authctxt *authctxt,
120                                  int startup, int save);
121 #endif
122
123 /* import */
124 extern ServerOptions options;
125 extern char *__progname;
126 extern int log_stderr;
127 extern int debug_flag;
128 extern u_int utmp_len;
129 extern int startup_pipe;
130 extern void destroy_sensitive_data(void);
131 extern Buffer loginmsg;
132
133 /* original command from peer. */
134 const char *original_command = NULL;
135
136 /* data */
137 #define MAX_SESSIONS 10
138 Session sessions[MAX_SESSIONS];
139
140 #ifdef HAVE_LOGIN_CAP
141 login_cap_t *lc;
142 #endif
143
144 static int is_child = 0;
145
146 /* Name and directory of socket for authentication agent forwarding. */
147 static char *auth_sock_name = NULL;
148 static char *auth_sock_dir = NULL;
149
150 /* removes the agent forwarding socket */
151
152 static void
153 auth_sock_cleanup_proc(struct passwd *pw)
154 {
155         if (auth_sock_name != NULL) {
156                 temporarily_use_uid(pw);
157                 unlink(auth_sock_name);
158                 rmdir(auth_sock_dir);
159                 auth_sock_name = NULL;
160                 restore_uid();
161         }
162 }
163
164 static int
165 auth_input_request_forwarding(struct passwd * pw)
166 {
167         Channel *nc;
168         int sock;
169         struct sockaddr_un sunaddr;
170
171         if (auth_sock_name != NULL) {
172                 error("authentication forwarding requested twice.");
173                 return 0;
174         }
175
176         /* Temporarily drop privileged uid for mkdir/bind. */
177         temporarily_use_uid(pw);
178
179         /* Allocate a buffer for the socket name, and format the name. */
180         auth_sock_name = xmalloc(MAXPATHLEN);
181         auth_sock_dir = xmalloc(MAXPATHLEN);
182         strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
183
184         /* Create private directory for socket */
185         if (mkdtemp(auth_sock_dir) == NULL) {
186                 packet_send_debug("Agent forwarding disabled: "
187                     "mkdtemp() failed: %.100s", strerror(errno));
188                 restore_uid();
189                 xfree(auth_sock_name);
190                 xfree(auth_sock_dir);
191                 auth_sock_name = NULL;
192                 auth_sock_dir = NULL;
193                 return 0;
194         }
195         snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
196                  auth_sock_dir, (long) getpid());
197
198         /* Create the socket. */
199         sock = socket(AF_UNIX, SOCK_STREAM, 0);
200         if (sock < 0)
201                 packet_disconnect("socket: %.100s", strerror(errno));
202
203         /* Bind it to the name. */
204         memset(&sunaddr, 0, sizeof(sunaddr));
205         sunaddr.sun_family = AF_UNIX;
206         strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
207
208         if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
209                 packet_disconnect("bind: %.100s", strerror(errno));
210
211         /* Restore the privileged uid. */
212         restore_uid();
213
214         /* Start listening on the socket. */
215         if (listen(sock, SSH_LISTEN_BACKLOG) < 0)
216                 packet_disconnect("listen: %.100s", strerror(errno));
217
218         /* Allocate a channel for the authentication agent socket. */
219         /* this shouldn't matter if its hpn or not - cjr */
220         nc = channel_new("auth socket",
221             SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
222             CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
223             0, "auth socket", 1);
224         strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
225         return 1;
226 }
227
228 static void
229 display_loginmsg(void)
230 {
231         if (buffer_len(&loginmsg) > 0) {
232                 buffer_append(&loginmsg, "\0", 1);
233                 printf("%s", (char *)buffer_ptr(&loginmsg));
234                 buffer_clear(&loginmsg);
235         }
236 }
237
238 void
239 do_authenticated(Authctxt *authctxt)
240 {
241         setproctitle("%s", authctxt->pw->pw_name);
242
243         /* setup the channel layer */
244         if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
245                 channel_permit_all_opens();
246
247         if (compat20)
248                 do_authenticated2(authctxt);
249         else
250                 do_authenticated1(authctxt);
251
252 #ifdef SESSION_HOOKS
253         if (options.session_hooks_allow &&
254             options.session_hooks_shutdown_cmd)
255         {
256             execute_session_hook(options.session_hooks_shutdown_cmd,
257                                  authctxt,
258                                  /* startup = */ 0, /* save = */ 0);
259
260             if (authctxt->session_env_file)
261             {
262                 free(authctxt->session_env_file);
263             }
264         }
265 #endif
266
267         do_cleanup(authctxt);
268 }
269
270 /*
271  * Prepares for an interactive session.  This is called after the user has
272  * been successfully authenticated.  During this message exchange, pseudo
273  * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
274  * are requested, etc.
275  */
276 static void
277 do_authenticated1(Authctxt *authctxt)
278 {
279         Session *s;
280         char *command;
281         int success, type, screen_flag;
282         int enable_compression_after_reply = 0;
283         u_int proto_len, data_len, dlen, compression_level = 0;
284
285         s = session_new();
286         if (s == NULL) {
287                 error("no more sessions");
288                 return;
289         }
290         s->authctxt = authctxt;
291         s->pw = authctxt->pw;
292
293         /*
294          * We stay in this loop until the client requests to execute a shell
295          * or a command.
296          */
297         for (;;) {
298                 success = 0;
299
300                 /* Get a packet from the client. */
301                 type = packet_read();
302
303                 /* Process the packet. */
304                 switch (type) {
305                 case SSH_CMSG_REQUEST_COMPRESSION:
306                         compression_level = packet_get_int();
307                         packet_check_eom();
308                         if (compression_level < 1 || compression_level > 9) {
309                                 packet_send_debug("Received invalid compression level %d.",
310                                     compression_level);
311                                 break;
312                         }
313                         if (options.compression == COMP_NONE) {
314                                 debug2("compression disabled");
315                                 break;
316                         }
317                         /* Enable compression after we have responded with SUCCESS. */
318                         enable_compression_after_reply = 1;
319                         success = 1;
320                         break;
321
322                 case SSH_CMSG_REQUEST_PTY:
323                         success = session_pty_req(s);
324                         break;
325
326                 case SSH_CMSG_X11_REQUEST_FORWARDING:
327                         s->auth_proto = packet_get_string(&proto_len);
328                         s->auth_data = packet_get_string(&data_len);
329
330                         screen_flag = packet_get_protocol_flags() &
331                             SSH_PROTOFLAG_SCREEN_NUMBER;
332                         debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
333
334                         if (packet_remaining() == 4) {
335                                 if (!screen_flag)
336                                         debug2("Buggy client: "
337                                             "X11 screen flag missing");
338                                 s->screen = packet_get_int();
339                         } else {
340                                 s->screen = 0;
341                         }
342                         packet_check_eom();
343                         success = session_setup_x11fwd(s);
344                         if (!success) {
345                                 xfree(s->auth_proto);
346                                 xfree(s->auth_data);
347                                 s->auth_proto = NULL;
348                                 s->auth_data = NULL;
349                         }
350                         break;
351
352                 case SSH_CMSG_AGENT_REQUEST_FORWARDING:
353                         if (no_agent_forwarding_flag || compat13) {
354                                 debug("Authentication agent forwarding not permitted for this authentication.");
355                                 break;
356                         }
357                         debug("Received authentication agent forwarding request.");
358                         success = auth_input_request_forwarding(s->pw);
359                         break;
360
361                 case SSH_CMSG_PORT_FORWARD_REQUEST:
362                         if (no_port_forwarding_flag) {
363                                 debug("Port forwarding not permitted for this authentication.");
364                                 break;
365                         }
366                         if (!options.allow_tcp_forwarding) {
367                                 debug("Port forwarding not permitted.");
368                                 break;
369                         }
370                         debug("Received TCP/IP port forwarding request.");
371                         if (channel_input_port_forward_request(s->pw->pw_uid == 0,
372                               options.gateway_ports, options.hpn_disabled,
373                               options.hpn_buffer_size) < 0) {
374                                 debug("Port forwarding failed.");
375                                 break;
376                         }
377                         success = 1;
378                         break;
379
380                 case SSH_CMSG_MAX_PACKET_SIZE:
381                         if (packet_set_maxsize(packet_get_int()) > 0)
382                                 success = 1;
383                         break;
384
385                 case SSH_CMSG_EXEC_SHELL:
386                 case SSH_CMSG_EXEC_CMD:
387                         if (type == SSH_CMSG_EXEC_CMD) {
388                                 command = packet_get_string(&dlen);
389                                 debug("Exec command '%.500s'", command);
390                                 do_exec(s, command);
391                                 xfree(command);
392                         } else {
393                                 do_exec(s, NULL);
394                         }
395                         packet_check_eom();
396                         session_close(s);
397                         return;
398
399                 default:
400                         /*
401                          * Any unknown messages in this phase are ignored,
402                          * and a failure message is returned.
403                          */
404                         logit("Unknown packet type received after authentication: %d", type);
405                 }
406                 packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
407                 packet_send();
408                 packet_write_wait();
409
410                 /* Enable compression now that we have replied if appropriate. */
411                 if (enable_compression_after_reply) {
412                         enable_compression_after_reply = 0;
413                         packet_start_compression(compression_level);
414                 }
415         }
416 }
417
418 /*
419  * This is called to fork and execute a command when we have no tty.  This
420  * will call do_child from the child, and server_loop from the parent after
421  * setting up file descriptors and such.
422  */
423 void
424 do_exec_no_pty(Session *s, const char *command)
425 {
426         pid_t pid;
427
428 #ifdef USE_PIPES
429         int pin[2], pout[2], perr[2];
430         /* Allocate pipes for communicating with the program. */
431         if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
432                 packet_disconnect("Could not create pipes: %.100s",
433                                   strerror(errno));
434 #else /* USE_PIPES */
435         int inout[2], err[2];
436         /* Uses socket pairs to communicate with the program. */
437         if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
438             socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
439                 packet_disconnect("Could not create socket pairs: %.100s",
440                                   strerror(errno));
441 #endif /* USE_PIPES */
442         if (s == NULL)
443                 fatal("do_exec_no_pty: no session");
444
445         session_proctitle(s);
446
447 #if defined(USE_PAM)
448         if (options.use_pam && !use_privsep)
449                 do_pam_setcred(1);
450 #endif /* USE_PAM */
451
452         /* Fork the child. */
453         if ((pid = fork()) == 0) {
454                 is_child = 1;
455
456                 /* Child.  Reinitialize the log since the pid has changed. */
457                 log_init(__progname, options.log_level, options.log_facility, log_stderr);
458
459                 /*
460                  * Create a new session and process group since the 4.4BSD
461                  * setlogin() affects the entire process group.
462                  */
463                 if (setsid() < 0)
464                         error("setsid failed: %.100s", strerror(errno));
465
466 #ifdef USE_PIPES
467                 /*
468                  * Redirect stdin.  We close the parent side of the socket
469                  * pair, and make the child side the standard input.
470                  */
471                 close(pin[1]);
472                 if (dup2(pin[0], 0) < 0)
473                         perror("dup2 stdin");
474                 close(pin[0]);
475
476                 /* Redirect stdout. */
477                 close(pout[0]);
478                 if (dup2(pout[1], 1) < 0)
479                         perror("dup2 stdout");
480                 close(pout[1]);
481
482                 /* Redirect stderr. */
483                 close(perr[0]);
484                 if (dup2(perr[1], 2) < 0)
485                         perror("dup2 stderr");
486                 close(perr[1]);
487 #else /* USE_PIPES */
488                 /*
489                  * Redirect stdin, stdout, and stderr.  Stdin and stdout will
490                  * use the same socket, as some programs (particularly rdist)
491                  * seem to depend on it.
492                  */
493                 close(inout[1]);
494                 close(err[1]);
495                 if (dup2(inout[0], 0) < 0)      /* stdin */
496                         perror("dup2 stdin");
497                 if (dup2(inout[0], 1) < 0)      /* stdout.  Note: same socket as stdin. */
498                         perror("dup2 stdout");
499                 if (dup2(err[0], 2) < 0)        /* stderr */
500                         perror("dup2 stderr");
501 #endif /* USE_PIPES */
502
503 #ifdef _UNICOS
504                 cray_init_job(s->pw); /* set up cray jid and tmpdir */
505 #endif
506
507                 /* Do processing for the child (exec command etc). */
508                 do_child(s, command);
509                 /* NOTREACHED */
510         }
511 #ifdef _UNICOS
512         signal(WJSIGNAL, cray_job_termination_handler);
513 #endif /* _UNICOS */
514 #ifdef HAVE_CYGWIN
515         if (is_winnt)
516                 cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
517 #endif
518         if (pid < 0)
519                 packet_disconnect("fork failed: %.100s", strerror(errno));
520         s->pid = pid;
521         /* Set interactive/non-interactive mode. */
522         packet_set_interactive(s->display != NULL);
523 #ifdef USE_PIPES
524         /* We are the parent.  Close the child sides of the pipes. */
525         close(pin[0]);
526         close(pout[1]);
527         close(perr[1]);
528
529         if (compat20) {
530                 if (s->is_subsystem) {
531                         close(perr[0]);
532                         perr[0] = -1;
533                 }
534                 session_set_fds(s, pin[1], pout[0], perr[0]);
535         } else {
536                 /* Enter the interactive session. */
537                 server_loop(pid, pin[1], pout[0], perr[0]);
538                 /* server_loop has closed pin[1], pout[0], and perr[0]. */
539         }
540 #else /* USE_PIPES */
541         /* We are the parent.  Close the child sides of the socket pairs. */
542         close(inout[0]);
543         close(err[0]);
544
545         /*
546          * Clear loginmsg, since it's the child's responsibility to display
547          * it to the user, otherwise multiple sessions may accumulate
548          * multiple copies of the login messages.
549          */
550         buffer_clear(&loginmsg);
551
552         /*
553          * Enter the interactive session.  Note: server_loop must be able to
554          * handle the case that fdin and fdout are the same.
555          */
556         if (compat20) {
557                 session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]);
558         } else {
559                 server_loop(pid, inout[1], inout[1], err[1]);
560                 /* server_loop has closed inout[1] and err[1]. */
561         }
562 #endif /* USE_PIPES */
563 }
564
565 /*
566  * This is called to fork and execute a command when we have a tty.  This
567  * will call do_child from the child, and server_loop from the parent after
568  * setting up file descriptors, controlling tty, updating wtmp, utmp,
569  * lastlog, and other such operations.
570  */
571 void
572 do_exec_pty(Session *s, const char *command)
573 {
574         int fdout, ptyfd, ttyfd, ptymaster;
575         pid_t pid;
576
577         if (s == NULL)
578                 fatal("do_exec_pty: no session");
579         ptyfd = s->ptyfd;
580         ttyfd = s->ttyfd;
581
582 #if defined(USE_PAM)
583         if (options.use_pam) {
584                 do_pam_set_tty(s->tty);
585                 if (!use_privsep)
586                         do_pam_setcred(1);
587         }
588 #endif
589
590         /* Fork the child. */
591         if ((pid = fork()) == 0) {
592                 is_child = 1;
593
594                 /* Child.  Reinitialize the log because the pid has changed. */
595                 log_init(__progname, options.log_level, options.log_facility, log_stderr);
596                 /* Close the master side of the pseudo tty. */
597                 close(ptyfd);
598
599                 /* Make the pseudo tty our controlling tty. */
600                 pty_make_controlling_tty(&ttyfd, s->tty);
601
602                 /* Redirect stdin/stdout/stderr from the pseudo tty. */
603                 if (dup2(ttyfd, 0) < 0)
604                         error("dup2 stdin: %s", strerror(errno));
605                 if (dup2(ttyfd, 1) < 0)
606                         error("dup2 stdout: %s", strerror(errno));
607                 if (dup2(ttyfd, 2) < 0)
608                         error("dup2 stderr: %s", strerror(errno));
609
610                 /* Close the extra descriptor for the pseudo tty. */
611                 close(ttyfd);
612
613                 /* record login, etc. similar to login(1) */
614 #ifndef HAVE_OSF_SIA
615                 if (!(options.use_login && command == NULL)) {
616 #ifdef _UNICOS
617                         cray_init_job(s->pw); /* set up cray jid and tmpdir */
618 #endif /* _UNICOS */
619                         do_login(s, command);
620                 }
621 # ifdef LOGIN_NEEDS_UTMPX
622                 else
623                         do_pre_login(s);
624 # endif
625 #endif
626
627                 /* Do common processing for the child, such as execing the command. */
628                 do_child(s, command);
629                 /* NOTREACHED */
630         }
631 #ifdef _UNICOS
632         signal(WJSIGNAL, cray_job_termination_handler);
633 #endif /* _UNICOS */
634 #ifdef HAVE_CYGWIN
635         if (is_winnt)
636                 cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
637 #endif
638         if (pid < 0)
639                 packet_disconnect("fork failed: %.100s", strerror(errno));
640         s->pid = pid;
641
642         /* Parent.  Close the slave side of the pseudo tty. */
643         close(ttyfd);
644
645         /*
646          * Create another descriptor of the pty master side for use as the
647          * standard input.  We could use the original descriptor, but this
648          * simplifies code in server_loop.  The descriptor is bidirectional.
649          */
650         fdout = dup(ptyfd);
651         if (fdout < 0)
652                 packet_disconnect("dup #1 failed: %.100s", strerror(errno));
653
654         /* we keep a reference to the pty master */
655         ptymaster = dup(ptyfd);
656         if (ptymaster < 0)
657                 packet_disconnect("dup #2 failed: %.100s", strerror(errno));
658         s->ptymaster = ptymaster;
659
660         /* Enter interactive session. */
661         packet_set_interactive(1);
662         if (compat20) {
663                 session_set_fds(s, ptyfd, fdout, -1);
664         } else {
665                 server_loop(pid, ptyfd, fdout, -1);
666                 /* server_loop _has_ closed ptyfd and fdout. */
667         }
668 }
669
670 #ifdef LOGIN_NEEDS_UTMPX
671 static void
672 do_pre_login(Session *s)
673 {
674         socklen_t fromlen;
675         struct sockaddr_storage from;
676         pid_t pid = getpid();
677
678         /*
679          * Get IP address of client. If the connection is not a socket, let
680          * the address be 0.0.0.0.
681          */
682         memset(&from, 0, sizeof(from));
683         fromlen = sizeof(from);
684         if (packet_connection_is_on_socket()) {
685                 if (getpeername(packet_get_connection_in(),
686                     (struct sockaddr *)&from, &fromlen) < 0) {
687                         debug("getpeername: %.100s", strerror(errno));
688                         cleanup_exit(255);
689                 }
690         }
691
692         record_utmp_only(pid, s->tty, s->pw->pw_name,
693             get_remote_name_or_ip(utmp_len, options.use_dns),
694             (struct sockaddr *)&from, fromlen);
695 }
696 #endif
697
698 /*
699  * This is called to fork and execute a command.  If another command is
700  * to be forced, execute that instead.
701  */
702 void
703 do_exec(Session *s, const char *command)
704 {
705         if (options.adm_forced_command) {
706                 original_command = command;
707                 command = options.adm_forced_command;
708                 debug("Forced command (config) '%.900s'", command);
709         } else if (forced_command) {
710                 original_command = command;
711                 command = forced_command;
712                 debug("Forced command (key option) '%.900s'", command);
713         }
714
715 #if defined(SESSION_HOOKS)
716         if (options.session_hooks_allow &&
717             (options.session_hooks_startup_cmd ||
718              options.session_hooks_shutdown_cmd))
719         {
720                 char env_file[1000];
721                 struct stat st;
722                 do
723                 {
724                         snprintf(env_file,
725                                  sizeof(env_file),
726                                  "/tmp/ssh_env_%d%d%d",
727                                  getuid(),
728                                  getpid(),
729                                  rand());
730                 } while (stat(env_file, &st)==0);
731                 s->authctxt->session_env_file = strdup(env_file);
732         }
733 #endif
734
735 #ifdef SSH_AUDIT_EVENTS
736         if (command != NULL)
737                 PRIVSEP(audit_run_command(command));
738         else if (s->ttyfd == -1) {
739                 char *shell = s->pw->pw_shell;
740
741                 if (shell[0] == '\0')   /* empty shell means /bin/sh */
742                         shell =_PATH_BSHELL;
743                 PRIVSEP(audit_run_command(shell));
744         }
745 #endif
746
747         if (s->ttyfd != -1)
748                 do_exec_pty(s, command);
749         else
750                 do_exec_no_pty(s, command);
751
752         original_command = NULL;
753
754         /*
755          * Clear loginmsg: it's the child's responsibility to display
756          * it to the user, otherwise multiple sessions may accumulate
757          * multiple copies of the login messages.
758          */
759         buffer_clear(&loginmsg);
760 }
761
762 /* administrative, login(1)-like work */
763 void
764 do_login(Session *s, const char *command)
765 {
766         socklen_t fromlen;
767         struct sockaddr_storage from;
768         struct passwd * pw = s->pw;
769         pid_t pid = getpid();
770
771         /*
772          * Get IP address of client. If the connection is not a socket, let
773          * the address be 0.0.0.0.
774          */
775         memset(&from, 0, sizeof(from));
776         fromlen = sizeof(from);
777         if (packet_connection_is_on_socket()) {
778                 if (getpeername(packet_get_connection_in(),
779                     (struct sockaddr *) & from, &fromlen) < 0) {
780                         debug("getpeername: %.100s", strerror(errno));
781                         cleanup_exit(255);
782                 }
783         }
784
785         /* Record that there was a login on that tty from the remote host. */
786         if (!use_privsep)
787                 record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
788                     get_remote_name_or_ip(utmp_len,
789                     options.use_dns),
790                     (struct sockaddr *)&from, fromlen);
791
792 #ifdef USE_PAM
793         /*
794          * If password change is needed, do it now.
795          * This needs to occur before the ~/.hushlogin check.
796          */
797         if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) {
798                 display_loginmsg();
799                 do_pam_chauthtok();
800                 s->authctxt->force_pwchange = 0;
801                 /* XXX - signal [net] parent to enable forwardings */
802         }
803 #endif
804
805         if (check_quietlogin(s, command))
806                 return;
807
808         display_loginmsg();
809
810         do_motd();
811 }
812
813 /*
814  * Display the message of the day.
815  */
816 void
817 do_motd(void)
818 {
819         FILE *f;
820         char buf[256];
821
822         if (options.print_motd) {
823 #ifdef HAVE_LOGIN_CAP
824                 f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
825                     "/etc/motd"), "r");
826 #else
827                 f = fopen("/etc/motd", "r");
828 #endif
829                 if (f) {
830                         while (fgets(buf, sizeof(buf), f))
831                                 fputs(buf, stdout);
832                         fclose(f);
833                 }
834         }
835 }
836
837
838 /*
839  * Check for quiet login, either .hushlogin or command given.
840  */
841 int
842 check_quietlogin(Session *s, const char *command)
843 {
844         char buf[256];
845         struct passwd *pw = s->pw;
846         struct stat st;
847
848         /* Return 1 if .hushlogin exists or a command given. */
849         if (command != NULL)
850                 return 1;
851         snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
852 #ifdef HAVE_LOGIN_CAP
853         if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
854                 return 1;
855 #else
856         if (stat(buf, &st) >= 0)
857                 return 1;
858 #endif
859         return 0;
860 }
861
862 /*
863  * Sets the value of the given variable in the environment.  If the variable
864  * already exists, its value is overriden.
865  */
866 void
867 child_set_env(char ***envp, u_int *envsizep, const char *name,
868         const char *value)
869 {
870         char **env;
871         u_int envsize;
872         u_int i, namelen;
873
874         /*
875          * If we're passed an uninitialized list, allocate a single null
876          * entry before continuing.
877          */
878         if (*envp == NULL && *envsizep == 0) {
879                 *envp = xmalloc(sizeof(char *));
880                 *envp[0] = NULL;
881                 *envsizep = 1;
882         }
883
884         /*
885          * Find the slot where the value should be stored.  If the variable
886          * already exists, we reuse the slot; otherwise we append a new slot
887          * at the end of the array, expanding if necessary.
888          */
889         env = *envp;
890         namelen = strlen(name);
891         for (i = 0; env[i]; i++)
892                 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
893                         break;
894         if (env[i]) {
895                 /* Reuse the slot. */
896                 xfree(env[i]);
897         } else {
898                 /* New variable.  Expand if necessary. */
899                 envsize = *envsizep;
900                 if (i >= envsize - 1) {
901                         if (envsize >= 1000)
902                                 fatal("child_set_env: too many env vars");
903                         envsize += 50;
904                         env = (*envp) = xrealloc(env, envsize, sizeof(char *));
905                         *envsizep = envsize;
906                 }
907                 /* Need to set the NULL pointer at end of array beyond the new slot. */
908                 env[i + 1] = NULL;
909         }
910
911         /* Allocate space and format the variable in the appropriate slot. */
912         env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
913         snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
914 }
915
916 /*
917  * Reads environment variables from the given file and adds/overrides them
918  * into the environment.  If the file does not exist, this does nothing.
919  * Otherwise, it must consist of empty lines, comments (line starts with '#')
920  * and assignments of the form name=value.  No other forms are allowed.
921  */
922 static void
923 read_environment_file(char ***env, u_int *envsize,
924         const char *filename)
925 {
926         FILE *f;
927         char buf[4096];
928         char *cp, *value;
929         u_int lineno = 0;
930
931         f = fopen(filename, "r");
932         if (!f)
933                 return;
934
935         while (fgets(buf, sizeof(buf), f)) {
936                 if (++lineno > 1000)
937                         fatal("Too many lines in environment file %s", filename);
938                 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
939                         ;
940                 if (!*cp || *cp == '#' || *cp == '\n')
941                         continue;
942                 if (strchr(cp, '\n'))
943                         *strchr(cp, '\n') = '\0';
944                 value = strchr(cp, '=');
945                 if (value == NULL) {
946                         fprintf(stderr, "Bad line %u in %.100s\n", lineno,
947                             filename);
948                         continue;
949                 }
950                 /*
951                  * Replace the equals sign by nul, and advance value to
952                  * the value string.
953                  */
954                 *value = '\0';
955                 value++;
956                 child_set_env(env, envsize, cp, value);
957         }
958         fclose(f);
959 }
960
961 #ifdef SESSION_HOOKS
962 #define SSH_SESSION_ENV_FILE "SSH_SESSION_ENV_FILE"
963
964 typedef enum { no_op, execute, clear_env, restore_env,
965                read_env, save_or_rm_env } session_action_t;
966
967 static session_action_t action_order[2][5] = {
968     { clear_env, read_env, execute, save_or_rm_env, restore_env }, /*shutdown*/
969     { execute, read_env, save_or_rm_env, no_op, no_op }            /*startup */
970 };
971
972 static
973 void execute_session_hook(char* prog, Authctxt *authctxt,
974                           int startup, int save)
975 {
976     extern char **environ;
977
978     struct stat  st;
979     char         **saved_env, **tmpenv;
980     char         *env_file = authctxt->session_env_file;
981     int          i, status = 0;
982
983     for (i=0; i<5; i++)
984     {
985         switch (action_order[startup][i])
986         {
987           case no_op:
988             break;
989
990           case execute:
991             {
992                 FILE* fp;
993                 char  buf[1000];
994
995                 snprintf(buf,
996                          sizeof(buf),
997                          "%s -c '%s'",
998                          authctxt->pw->pw_shell,
999                          prog);
1000
1001                 debug("executing session hook: [%s]", buf);
1002                 setenv(SSH_SESSION_ENV_FILE, env_file, /* overwrite = */ 1);
1003
1004                 /* flusing is recommended in the popen(3) man page, to avoid
1005                    intermingling of output */
1006                 fflush(stdout);
1007                 fflush(stderr);
1008                 if ((fp=popen(buf, "w")) == NULL)
1009                 {
1010                     perror("Unable to run session hook");
1011                     return;
1012                 }
1013                 status = pclose(fp);
1014                 debug2("session hook executed, status=%d", status);
1015                 unsetenv(SSH_SESSION_ENV_FILE);
1016             }
1017             break;
1018
1019           case clear_env:
1020             saved_env = environ;
1021             tmpenv = (char**) malloc(sizeof(char*));
1022             tmpenv[0] = NULL;
1023             environ = tmpenv;
1024             break;
1025
1026           case restore_env:
1027             environ = saved_env;
1028             free(tmpenv);
1029             break;
1030
1031           case read_env:
1032             if (status==0 && stat(env_file, &st)==0)
1033             {
1034                 int envsize = 0;
1035
1036                 debug("reading environment from %s", env_file);
1037                 while (environ[envsize++]) ;
1038                 read_environment_file(&environ, &envsize, env_file);
1039             }
1040             break;
1041
1042           case save_or_rm_env:
1043             if (status==0 && save)
1044             {
1045                 FILE* fp;
1046                 int    envcount=0;
1047
1048                 debug2("saving environment to %s", env_file);
1049                 if ((fp = fopen(env_file, "w")) == NULL) /* hmm: file perms? */
1050                 {
1051                     perror("Unable to save session hook info");
1052                 }
1053                 while (environ[envcount])
1054                 {
1055                     fprintf(fp, "%s\n", environ[envcount++]);
1056                 }
1057                 fflush(fp);
1058                 fclose(fp);
1059             }
1060             else if (stat(env_file, &st)==0)
1061             {
1062                 debug2("removing environment file %s", env_file);
1063                 remove(env_file);
1064             }
1065             break;
1066         }
1067     }
1068
1069 }
1070 #endif
1071
1072 #ifdef HAVE_ETC_DEFAULT_LOGIN
1073 /*
1074  * Return named variable from specified environment, or NULL if not present.
1075  */
1076 static char *
1077 child_get_env(char **env, const char *name)
1078 {
1079         int i;
1080         size_t len;
1081
1082         len = strlen(name);
1083         for (i=0; env[i] != NULL; i++)
1084                 if (strncmp(name, env[i], len) == 0 && env[i][len] == '=')
1085                         return(env[i] + len + 1);
1086         return NULL;
1087 }
1088
1089 /*
1090  * Read /etc/default/login.
1091  * We pick up the PATH (or SUPATH for root) and UMASK.
1092  */
1093 static void
1094 read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
1095 {
1096         char **tmpenv = NULL, *var;
1097         u_int i, tmpenvsize = 0;
1098         u_long mask;
1099
1100         /*
1101          * We don't want to copy the whole file to the child's environment,
1102          * so we use a temporary environment and copy the variables we're
1103          * interested in.
1104          */
1105         read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login");
1106
1107         if (tmpenv == NULL)
1108                 return;
1109
1110         if (uid == 0)
1111                 var = child_get_env(tmpenv, "SUPATH");
1112         else
1113                 var = child_get_env(tmpenv, "PATH");
1114         if (var != NULL)
1115                 child_set_env(env, envsize, "PATH", var);
1116
1117         if ((var = child_get_env(tmpenv, "UMASK")) != NULL)
1118                 if (sscanf(var, "%5lo", &mask) == 1)
1119                         umask((mode_t)mask);
1120
1121         for (i = 0; tmpenv[i] != NULL; i++)
1122                 xfree(tmpenv[i]);
1123         xfree(tmpenv);
1124 }
1125 #endif /* HAVE_ETC_DEFAULT_LOGIN */
1126
1127 void
1128 copy_environment(char **source, char ***env, u_int *envsize)
1129 {
1130         char *var_name, *var_val;
1131         int i;
1132
1133         if (source == NULL)
1134                 return;
1135
1136         for(i = 0; source[i] != NULL; i++) {
1137                 var_name = xstrdup(source[i]);
1138                 if ((var_val = strstr(var_name, "=")) == NULL) {
1139                         xfree(var_name);
1140                         continue;
1141                 }
1142                 *var_val++ = '\0';
1143
1144                 debug3("Copy environment: %s=%s", var_name, var_val);
1145                 child_set_env(env, envsize, var_name, var_val);
1146
1147                 xfree(var_name);
1148         }
1149 }
1150
1151 static char **
1152 do_setup_env(Session *s, const char *shell)
1153 {
1154         char buf[256];
1155         u_int i, envsize;
1156         char **env, *laddr;
1157         struct passwd *pw = s->pw;
1158 #ifndef HAVE_LOGIN_CAP
1159         char *path = NULL;
1160 #endif
1161
1162         /* Initialize the environment. */
1163         envsize = 100;
1164         env = xcalloc(envsize, sizeof(char *));
1165         env[0] = NULL;
1166
1167 #ifdef HAVE_CYGWIN
1168         /*
1169          * The Windows environment contains some setting which are
1170          * important for a running system. They must not be dropped.
1171          */
1172         {
1173                 char **p;
1174
1175                 p = fetch_windows_environment();
1176                 copy_environment(p, &env, &envsize);
1177                 free_windows_environment(p);
1178         }
1179 #endif
1180
1181 #ifdef GSSAPI
1182         /* Allow any GSSAPI methods that we've used to alter
1183          * the childs environment as they see fit
1184          */
1185         ssh_gssapi_do_child(&env, &envsize);
1186 #endif
1187
1188         if (!options.use_login) {
1189                 /* Set basic environment. */
1190                 for (i = 0; i < s->num_env; i++)
1191                         child_set_env(&env, &envsize, s->env[i].name,
1192                             s->env[i].val);
1193
1194                 child_set_env(&env, &envsize, "USER", pw->pw_name);
1195                 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
1196 #ifdef _AIX
1197                 child_set_env(&env, &envsize, "LOGIN", pw->pw_name);
1198 #endif
1199                 child_set_env(&env, &envsize, "HOME", pw->pw_dir);
1200 #ifdef HAVE_LOGIN_CAP
1201                 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)
1202                         child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1203                 else
1204                         child_set_env(&env, &envsize, "PATH", getenv("PATH"));
1205 #else /* HAVE_LOGIN_CAP */
1206 # ifndef HAVE_CYGWIN
1207                 /*
1208                  * There's no standard path on Windows. The path contains
1209                  * important components pointing to the system directories,
1210                  * needed for loading shared libraries. So the path better
1211                  * remains intact here.
1212                  */
1213 #  ifdef HAVE_ETC_DEFAULT_LOGIN
1214                 read_etc_default_login(&env, &envsize, pw->pw_uid);
1215                 path = child_get_env(env, "PATH");
1216 #  endif /* HAVE_ETC_DEFAULT_LOGIN */
1217                 if (path == NULL || *path == '\0') {
1218                         child_set_env(&env, &envsize, "PATH",
1219                             s->pw->pw_uid == 0 ?
1220                                 SUPERUSER_PATH : _PATH_STDPATH);
1221                 }
1222 # endif /* HAVE_CYGWIN */
1223 #endif /* HAVE_LOGIN_CAP */
1224
1225                 snprintf(buf, sizeof buf, "%.200s/%.50s",
1226                          _PATH_MAILDIR, pw->pw_name);
1227                 child_set_env(&env, &envsize, "MAIL", buf);
1228
1229                 /* Normal systems set SHELL by default. */
1230                 child_set_env(&env, &envsize, "SHELL", shell);
1231         }
1232         if (getenv("TZ"))
1233                 child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1234
1235 #ifdef GSI /* GSI shared libs typically installed in non-system locations. */
1236         {
1237                 char *cp;
1238
1239                 if ((cp = getenv("LD_LIBRARY_PATH")) != NULL)
1240                         child_set_env(&env, &envsize, "LD_LIBRARY_PATH", cp);
1241                 if ((cp = getenv("LIBPATH")) != NULL)
1242                         child_set_env(&env, &envsize, "LIBPATH", cp);
1243                 if ((cp = getenv("SHLIB_PATH")) != NULL)
1244                         child_set_env(&env, &envsize, "SHLIB_PATH", cp);
1245                 if ((cp = getenv("LD_LIBRARYN32_PATH")) != NULL)
1246                         child_set_env(&env, &envsize, "LD_LIBRARYN32_PATH",cp);
1247                 if ((cp = getenv("LD_LIBRARY64_PATH")) != NULL)
1248                         child_set_env(&env, &envsize, "LD_LIBRARY64_PATH",cp);
1249         }
1250 #endif
1251
1252         /* Set custom environment options from RSA authentication. */
1253         if (!options.use_login) {
1254                 while (custom_environment) {
1255                         struct envstring *ce = custom_environment;
1256                         char *str = ce->s;
1257
1258                         for (i = 0; str[i] != '=' && str[i]; i++)
1259                                 ;
1260                         if (str[i] == '=') {
1261                                 str[i] = 0;
1262                                 child_set_env(&env, &envsize, str, str + i + 1);
1263                         }
1264                         custom_environment = ce->next;
1265                         xfree(ce->s);
1266                         xfree(ce);
1267                 }
1268         }
1269
1270         /* SSH_CLIENT deprecated */
1271         snprintf(buf, sizeof buf, "%.50s %d %d",
1272             get_remote_ipaddr(), get_remote_port(), get_local_port());
1273         child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1274
1275         laddr = get_local_ipaddr(packet_get_connection_in());
1276         snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
1277             get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());
1278         xfree(laddr);
1279         child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1280
1281         if (s->ttyfd != -1)
1282                 child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1283         if (s->term)
1284                 child_set_env(&env, &envsize, "TERM", s->term);
1285         if (s->display)
1286                 child_set_env(&env, &envsize, "DISPLAY", s->display);
1287         if (original_command)
1288                 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1289                     original_command);
1290
1291 #ifdef _UNICOS
1292         if (cray_tmpdir[0] != '\0')
1293                 child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir);
1294 #endif /* _UNICOS */
1295
1296         /*
1297          * Since we clear KRB5CCNAME at startup, if it's set now then it
1298          * must have been set by a native authentication method (eg AIX or
1299          * SIA), so copy it to the child.
1300          */
1301         {
1302                 char *cp;
1303
1304                 if ((cp = getenv("KRB5CCNAME")) != NULL)
1305                         child_set_env(&env, &envsize, "KRB5CCNAME", cp);
1306         }
1307
1308 #ifdef _AIX
1309         {
1310                 char *cp;
1311
1312                 if ((cp = getenv("AUTHSTATE")) != NULL)
1313                         child_set_env(&env, &envsize, "AUTHSTATE", cp);
1314                 read_environment_file(&env, &envsize, "/etc/environment");
1315         }
1316 #endif
1317 #ifdef KRB5
1318         if (s->authctxt->krb5_ccname)
1319                 child_set_env(&env, &envsize, "KRB5CCNAME",
1320                     s->authctxt->krb5_ccname);
1321 #endif
1322 #ifdef USE_PAM
1323         /*
1324          * Pull in any environment variables that may have
1325          * been set by PAM.
1326          */
1327         if (options.use_pam) {
1328                 char **p;
1329
1330                 p = fetch_pam_child_environment();
1331                 copy_environment(p, &env, &envsize);
1332                 free_pam_environment(p);
1333
1334                 p = fetch_pam_environment();
1335                 copy_environment(p, &env, &envsize);
1336                 free_pam_environment(p);
1337         }
1338 #endif /* USE_PAM */
1339
1340         if (auth_sock_name != NULL)
1341                 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1342                     auth_sock_name);
1343
1344         /* read $HOME/.ssh/environment. */
1345         if (options.permit_user_env && !options.use_login) {
1346                 snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
1347                     strcmp(pw->pw_dir, "/") ? pw->pw_dir : "");
1348                 read_environment_file(&env, &envsize, buf);
1349         }
1350         if (debug_flag) {
1351                 /* dump the environment */
1352                 fprintf(stderr, "Environment:\n");
1353                 for (i = 0; env[i]; i++)
1354                         fprintf(stderr, "  %.200s\n", env[i]);
1355         }
1356         return env;
1357 }
1358
1359 /*
1360  * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
1361  * first in this order).
1362  */
1363 static void
1364 do_rc_files(Session *s, const char *shell)
1365 {
1366         FILE *f = NULL;
1367         char cmd[1024];
1368         int do_xauth;
1369         struct stat st;
1370
1371         do_xauth =
1372             s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
1373
1374         /* ignore _PATH_SSH_USER_RC for subsystems */
1375         if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
1376                 snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
1377                     shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
1378                 if (debug_flag)
1379                         fprintf(stderr, "Running %s\n", cmd);
1380                 f = popen(cmd, "w");
1381                 if (f) {
1382                         if (do_xauth)
1383                                 fprintf(f, "%s %s\n", s->auth_proto,
1384                                     s->auth_data);
1385                         pclose(f);
1386                 } else
1387                         fprintf(stderr, "Could not run %s\n",
1388                             _PATH_SSH_USER_RC);
1389         } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
1390                 if (debug_flag)
1391                         fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
1392                             _PATH_SSH_SYSTEM_RC);
1393                 f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
1394                 if (f) {
1395                         if (do_xauth)
1396                                 fprintf(f, "%s %s\n", s->auth_proto,
1397                                     s->auth_data);
1398                         pclose(f);
1399                 } else
1400                         fprintf(stderr, "Could not run %s\n",
1401                             _PATH_SSH_SYSTEM_RC);
1402         } else if (do_xauth && options.xauth_location != NULL) {
1403                 /* Add authority data to .Xauthority if appropriate. */
1404                 if (debug_flag) {
1405                         fprintf(stderr,
1406                             "Running %.500s remove %.100s\n",
1407                             options.xauth_location, s->auth_display);
1408                         fprintf(stderr,
1409                             "%.500s add %.100s %.100s %.100s\n",
1410                             options.xauth_location, s->auth_display,
1411                             s->auth_proto, s->auth_data);
1412                 }
1413                 snprintf(cmd, sizeof cmd, "%s -q -",
1414                     options.xauth_location);
1415                 f = popen(cmd, "w");
1416                 if (f) {
1417                         fprintf(f, "remove %s\n",
1418                             s->auth_display);
1419                         fprintf(f, "add %s %s %s\n",
1420                             s->auth_display, s->auth_proto,
1421                             s->auth_data);
1422                         pclose(f);
1423                 } else {
1424                         fprintf(stderr, "Could not run %s\n",
1425                             cmd);
1426                 }
1427         }
1428 }
1429
1430 static void
1431 do_nologin(struct passwd *pw)
1432 {
1433         FILE *f = NULL;
1434         char buf[1024];
1435
1436 #ifdef HAVE_LOGIN_CAP
1437         if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
1438                 f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
1439                     _PATH_NOLOGIN), "r");
1440 #else
1441         if (pw->pw_uid)
1442                 f = fopen(_PATH_NOLOGIN, "r");
1443 #endif
1444         if (f) {
1445                 /* /etc/nologin exists.  Print its contents and exit. */
1446                 logit("User %.100s not allowed because %s exists",
1447                     pw->pw_name, _PATH_NOLOGIN);
1448                 while (fgets(buf, sizeof(buf), f))
1449                         fputs(buf, stderr);
1450                 fclose(f);
1451                 fflush(NULL);
1452                 exit(254);
1453         }
1454 }
1455
1456 /* Set login name, uid, gid, and groups. */
1457 void
1458 do_setusercontext(struct passwd *pw)
1459 {
1460 #ifndef HAVE_CYGWIN
1461         if (getuid() == 0 || geteuid() == 0)
1462 #endif /* HAVE_CYGWIN */
1463         {
1464
1465 #ifdef HAVE_SETPCRED
1466                 if (setpcred(pw->pw_name, (char **)NULL) == -1)
1467                         fatal("Failed to set process credentials");
1468 #endif /* HAVE_SETPCRED */
1469 #ifdef HAVE_LOGIN_CAP
1470 # ifdef __bsdi__
1471                 setpgid(0, 0);
1472 # endif
1473 #ifdef GSSAPI
1474                 if (options.gss_authentication) {
1475                         temporarily_use_uid(pw);
1476                         ssh_gssapi_storecreds();
1477                         restore_uid();
1478                 }
1479 #endif
1480 # ifdef USE_PAM
1481                 if (options.use_pam) {
1482                         do_pam_session();
1483                         do_pam_setcred(use_privsep);
1484                 }
1485 # endif /* USE_PAM */
1486                 if (setusercontext(lc, pw, pw->pw_uid,
1487                     (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
1488                         perror("unable to set user context");
1489                         exit(1);
1490                 }
1491 #else
1492 # if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
1493                 /* Sets login uid for accounting */
1494                 if (getluid() == -1 && setluid(pw->pw_uid) == -1)
1495                         error("setluid: %s", strerror(errno));
1496 # endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
1497
1498                 if (setlogin(pw->pw_name) < 0)
1499                         error("setlogin failed: %s", strerror(errno));
1500                 if (setgid(pw->pw_gid) < 0) {
1501                         perror("setgid");
1502                         exit(1);
1503                 }
1504                 /* Initialize the group list. */
1505                 if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
1506                         perror("initgroups");
1507                         exit(1);
1508                 }
1509                 endgrent();
1510 #ifdef GSSAPI
1511                 if (options.gss_authentication) {
1512                         temporarily_use_uid(pw);
1513                         ssh_gssapi_storecreds();
1514                         restore_uid();
1515                 }
1516 #endif
1517 # ifdef USE_PAM
1518                 /*
1519                  * PAM credentials may take the form of supplementary groups.
1520                  * These will have been wiped by the above initgroups() call.
1521                  * Reestablish them here.
1522                  */
1523                 if (options.use_pam) {
1524                         do_pam_session();
1525                         do_pam_setcred(use_privsep);
1526                 }
1527 # endif /* USE_PAM */
1528 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
1529                 irix_setusercontext(pw);
1530 #  endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1531 # ifdef _AIX
1532                 aix_usrinfo(pw);
1533 # endif /* _AIX */
1534 #ifdef USE_LIBIAF
1535                 if (set_id(pw->pw_name) != 0) {
1536                         exit(1);
1537                 }
1538 #endif /* USE_LIBIAF */
1539                 /* Permanently switch to the desired uid. */
1540                 permanently_set_uid(pw);
1541 #endif
1542         }
1543
1544 #ifdef HAVE_CYGWIN
1545         if (is_winnt)
1546 #endif
1547         if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1548                 fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1549
1550 #ifdef WITH_SELINUX
1551         ssh_selinux_setup_exec_context(pw->pw_name);
1552 #endif
1553 }
1554
1555 static void
1556 do_pwchange(Session *s)
1557 {
1558         fflush(NULL);
1559         fprintf(stderr, "WARNING: Your password has expired.\n");
1560         if (s->ttyfd != -1) {
1561                 fprintf(stderr,
1562                     "You must change your password now and login again!\n");
1563 #ifdef PASSWD_NEEDS_USERNAME
1564                 execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
1565                     (char *)NULL);
1566 #else
1567                 execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
1568 #endif
1569                 perror("passwd");
1570         } else {
1571                 fprintf(stderr,
1572                     "Password change required but no TTY available.\n");
1573         }
1574         exit(1);
1575 }
1576
1577 static void
1578 launch_login(struct passwd *pw, const char *hostname)
1579 {
1580         /* Launch login(1). */
1581
1582         execl(LOGIN_PROGRAM, "login", "-h", hostname,
1583 #ifdef xxxLOGIN_NEEDS_TERM
1584                     (s->term ? s->term : "unknown"),
1585 #endif /* LOGIN_NEEDS_TERM */
1586 #ifdef LOGIN_NO_ENDOPT
1587             "-p", "-f", pw->pw_name, (char *)NULL);
1588 #else
1589             "-p", "-f", "--", pw->pw_name, (char *)NULL);
1590 #endif
1591
1592         /* Login couldn't be executed, die. */
1593
1594         perror("login");
1595         exit(1);
1596 }
1597
1598 static void
1599 child_close_fds(void)
1600 {
1601         int i;
1602
1603         if (packet_get_connection_in() == packet_get_connection_out())
1604                 close(packet_get_connection_in());
1605         else {
1606                 close(packet_get_connection_in());
1607                 close(packet_get_connection_out());
1608         }
1609         /*
1610          * Close all descriptors related to channels.  They will still remain
1611          * open in the parent.
1612          */
1613         /* XXX better use close-on-exec? -markus */
1614         channel_close_all();
1615
1616         /*
1617          * Close any extra file descriptors.  Note that there may still be
1618          * descriptors left by system functions.  They will be closed later.
1619          */
1620         endpwent();
1621
1622         /*
1623          * Close any extra open file descriptors so that we don't have them
1624          * hanging around in clients.  Note that we want to do this after
1625          * initgroups, because at least on Solaris 2.3 it leaves file
1626          * descriptors open.
1627          */
1628         for (i = 3; i < 64; i++)
1629                 close(i);
1630 }
1631
1632 /*
1633  * Performs common processing for the child, such as setting up the
1634  * environment, closing extra file descriptors, setting the user and group
1635  * ids, and executing the command or shell.
1636  */
1637 void
1638 do_child(Session *s, const char *command)
1639 {
1640         extern char **environ;
1641         char **env;
1642         char *argv[10];
1643         const char *shell, *shell0, *hostname = NULL;
1644         struct passwd *pw = s->pw;
1645
1646 #ifdef AFS_KRB5
1647 /* Default place to look for aklog. */
1648 #ifdef AKLOG_PATH
1649 #define KPROGDIR AKLOG_PATH
1650 #else
1651 #define KPROGDIR "/usr/bin/aklog"
1652 #endif /* AKLOG_PATH */
1653
1654         struct stat st;
1655         char *aklog_path;
1656 #endif /* AFS_KRB5 */
1657
1658         /* remove hostkey from the child's memory */
1659         destroy_sensitive_data();
1660
1661         /* Force a password change */
1662         if (s->authctxt->force_pwchange) {
1663                 do_setusercontext(pw);
1664                 child_close_fds();
1665                 do_pwchange(s);
1666                 exit(1);
1667         }
1668
1669         /* login(1) is only called if we execute the login shell */
1670         if (options.use_login && command != NULL)
1671                 options.use_login = 0;
1672
1673 #ifdef _UNICOS
1674         cray_setup(pw->pw_uid, pw->pw_name, command);
1675 #endif /* _UNICOS */
1676
1677         /*
1678          * Login(1) does this as well, and it needs uid 0 for the "-h"
1679          * switch, so we let login(1) to this for us.
1680          */
1681         if (!options.use_login) {
1682 #ifdef HAVE_OSF_SIA
1683                 session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty);
1684                 if (!check_quietlogin(s, command))
1685                         do_motd();
1686 #else /* HAVE_OSF_SIA */
1687                 /* When PAM is enabled we rely on it to do the nologin check */
1688                 if (!options.use_pam)
1689                         do_nologin(pw);
1690                 do_setusercontext(pw);
1691                 /*
1692                  * PAM session modules in do_setusercontext may have
1693                  * generated messages, so if this in an interactive
1694                  * login then display them too.
1695                  */
1696                 if (!check_quietlogin(s, command))
1697                         display_loginmsg();
1698 #endif /* HAVE_OSF_SIA */
1699         }
1700
1701 #ifdef USE_PAM
1702         if (options.use_pam && !options.use_login && !is_pam_session_open()) {
1703                 debug3("PAM session not opened, exiting");
1704                 display_loginmsg();
1705                 exit(254);
1706         }
1707 #endif
1708
1709         /*
1710          * Get the shell from the password data.  An empty shell field is
1711          * legal, and means /bin/sh.
1712          */
1713         shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1714
1715         /*
1716          * Make sure $SHELL points to the shell from the password file,
1717          * even if shell is overridden from login.conf
1718          */
1719         env = do_setup_env(s, shell);
1720
1721 #ifdef HAVE_LOGIN_CAP
1722         shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
1723 #endif
1724
1725         /* we have to stash the hostname before we close our socket. */
1726         if (options.use_login)
1727                 hostname = get_remote_name_or_ip(utmp_len,
1728                     options.use_dns);
1729         /*
1730          * Close the connection descriptors; note that this is the child, and
1731          * the server will still have the socket open, and it is important
1732          * that we do not shutdown it.  Note that the descriptors cannot be
1733          * closed before building the environment, as we call
1734          * get_remote_ipaddr there.
1735          */
1736         child_close_fds();
1737
1738         /*
1739          * Must take new environment into use so that .ssh/rc,
1740          * /etc/ssh/sshrc and xauth are run in the proper environment.
1741          */
1742         environ = env;
1743
1744 #if defined(KRB5) && defined(USE_AFS)
1745         /*
1746          * At this point, we check to see if AFS is active and if we have
1747          * a valid Kerberos 5 TGT. If so, it seems like a good idea to see
1748          * if we can (and need to) extend the ticket into an AFS token. If
1749          * we don't do this, we run into potential problems if the user's
1750          * home directory is in AFS and it's not world-readable.
1751          */
1752
1753         if (options.kerberos_get_afs_token && k_hasafs() &&
1754             (s->authctxt->krb5_ctx != NULL)) {
1755                 char cell[64];
1756
1757                 debug("Getting AFS token");
1758
1759                 k_setpag();
1760
1761                 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1762                         krb5_afslog(s->authctxt->krb5_ctx,
1763                             s->authctxt->krb5_fwd_ccache, cell, NULL);
1764
1765                 krb5_afslog_home(s->authctxt->krb5_ctx,
1766                     s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
1767         }
1768 #endif
1769
1770 #ifdef AFS_KRB5
1771
1772         /* User has authenticated, and if a ticket was going to be
1773          * passed we would have it.  KRB5CCNAME should already be set.
1774          * Now try to get an AFS token using aklog.
1775          */
1776         if (k_hasafs()) {  /* Do we have AFS? */
1777
1778                 aklog_path = xstrdup(KPROGDIR);
1779
1780                 /*
1781                  * Make sure it exists before we try to run it
1782                  */
1783                 if (stat(aklog_path, &st) == 0) {
1784                         debug("Running %s to get afs token.",aklog_path);
1785                         system(aklog_path);
1786                 } else {
1787                         debug("%s does not exist.",aklog_path);
1788                 }
1789
1790                 xfree(aklog_path);
1791         }
1792 #endif /* AFS_KRB5 */
1793
1794 #ifdef SESSION_HOOKS
1795         if (options.session_hooks_allow &&
1796             options.session_hooks_startup_cmd)
1797         {
1798             execute_session_hook(options.session_hooks_startup_cmd,
1799                                  s->authctxt,
1800                                  /* startup = */ 1,
1801                                  options.session_hooks_shutdown_cmd != NULL);
1802         }
1803 #endif
1804
1805         /* Change current directory to the user's home directory. */
1806         if (chdir(pw->pw_dir) < 0) {
1807                 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1808                     pw->pw_dir, strerror(errno));
1809 #ifdef HAVE_LOGIN_CAP
1810                 if (login_getcapbool(lc, "requirehome", 0))
1811                         exit(1);
1812 #endif
1813         }
1814
1815         if (!options.use_login)
1816                 do_rc_files(s, shell);
1817
1818         /* restore SIGPIPE for child */
1819         signal(SIGPIPE, SIG_DFL);
1820
1821         if (options.use_login) {
1822                 launch_login(pw, hostname);
1823                 /* NEVERREACHED */
1824         }
1825
1826         /* Get the last component of the shell name. */
1827         if ((shell0 = strrchr(shell, '/')) != NULL)
1828                 shell0++;
1829         else
1830                 shell0 = shell;
1831
1832         /*
1833          * If we have no command, execute the shell.  In this case, the shell
1834          * name to be passed in argv[0] is preceded by '-' to indicate that
1835          * this is a login shell.
1836          */
1837         if (!command) {
1838                 char argv0[256];
1839
1840                 /* Start the shell.  Set initial character to '-'. */
1841                 argv0[0] = '-';
1842
1843                 if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
1844                     >= sizeof(argv0) - 1) {
1845                         errno = EINVAL;
1846                         perror(shell);
1847                         exit(1);
1848                 }
1849
1850                 /* Execute the shell. */
1851                 argv[0] = argv0;
1852                 argv[1] = NULL;
1853                 execve(shell, argv, environ);
1854
1855                 /* Executing the shell failed. */
1856                 perror(shell);
1857                 exit(1);
1858         }
1859         /*
1860          * Execute the command using the user's shell.  This uses the -c
1861          * option to execute the command.
1862          */
1863         argv[0] = (char *) shell0;
1864         argv[1] = "-c";
1865         argv[2] = (char *) command;
1866         argv[3] = NULL;
1867         execve(shell, argv, environ);
1868         perror(shell);
1869         exit(1);
1870 }
1871
1872 Session *
1873 session_new(void)
1874 {
1875         int i;
1876         static int did_init = 0;
1877         if (!did_init) {
1878                 debug("session_new: init");
1879                 for (i = 0; i < MAX_SESSIONS; i++) {
1880                         sessions[i].used = 0;
1881                 }
1882                 did_init = 1;
1883         }
1884         for (i = 0; i < MAX_SESSIONS; i++) {
1885                 Session *s = &sessions[i];
1886                 if (! s->used) {
1887                         memset(s, 0, sizeof(*s));
1888                         s->chanid = -1;
1889                         s->ptyfd = -1;
1890                         s->ttyfd = -1;
1891                         s->used = 1;
1892                         s->self = i;
1893                         s->x11_chanids = NULL;
1894                         debug("session_new: session %d", i);
1895                         return s;
1896                 }
1897         }
1898         return NULL;
1899 }
1900
1901 static void
1902 session_dump(void)
1903 {
1904         int i;
1905         for (i = 0; i < MAX_SESSIONS; i++) {
1906                 Session *s = &sessions[i];
1907                 debug("dump: used %d session %d %p channel %d pid %ld",
1908                     s->used,
1909                     s->self,
1910                     s,
1911                     s->chanid,
1912                     (long)s->pid);
1913         }
1914 }
1915
1916 int
1917 session_open(Authctxt *authctxt, int chanid)
1918 {
1919         Session *s = session_new();
1920         debug("session_open: channel %d", chanid);
1921         if (s == NULL) {
1922                 error("no more sessions");
1923                 return 0;
1924         }
1925         s->authctxt = authctxt;
1926         s->pw = authctxt->pw;
1927         if (s->pw == NULL || !authctxt->valid)
1928                 fatal("no user for session %d", s->self);
1929         debug("session_open: session %d: link with channel %d", s->self, chanid);
1930         s->chanid = chanid;
1931         return 1;
1932 }
1933
1934 Session *
1935 session_by_tty(char *tty)
1936 {
1937         int i;
1938         for (i = 0; i < MAX_SESSIONS; i++) {
1939                 Session *s = &sessions[i];
1940                 if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
1941                         debug("session_by_tty: session %d tty %s", i, tty);
1942                         return s;
1943                 }
1944         }
1945         debug("session_by_tty: unknown tty %.100s", tty);
1946         session_dump();
1947         return NULL;
1948 }
1949
1950 static Session *
1951 session_by_channel(int id)
1952 {
1953         int i;
1954         for (i = 0; i < MAX_SESSIONS; i++) {
1955                 Session *s = &sessions[i];
1956                 if (s->used && s->chanid == id) {
1957                         debug("session_by_channel: session %d channel %d", i, id);
1958                         return s;
1959                 }
1960         }
1961         debug("session_by_channel: unknown channel %d", id);
1962         session_dump();
1963         return NULL;
1964 }
1965
1966 static Session *
1967 session_by_x11_channel(int id)
1968 {
1969         int i, j;
1970
1971         for (i = 0; i < MAX_SESSIONS; i++) {
1972                 Session *s = &sessions[i];
1973
1974                 if (s->x11_chanids == NULL || !s->used)
1975                         continue;
1976                 for (j = 0; s->x11_chanids[j] != -1; j++) {
1977                         if (s->x11_chanids[j] == id) {
1978                                 debug("session_by_x11_channel: session %d "
1979                                     "channel %d", s->self, id);
1980                                 return s;
1981                         }
1982                 }
1983         }
1984         debug("session_by_x11_channel: unknown channel %d", id);
1985         session_dump();
1986         return NULL;
1987 }
1988
1989 static Session *
1990 session_by_pid(pid_t pid)
1991 {
1992         int i;
1993         debug("session_by_pid: pid %ld", (long)pid);
1994         for (i = 0; i < MAX_SESSIONS; i++) {
1995                 Session *s = &sessions[i];
1996                 if (s->used && s->pid == pid)
1997                         return s;
1998         }
1999         error("session_by_pid: unknown pid %ld", (long)pid);
2000         session_dump();
2001         return NULL;
2002 }
2003
2004 static int
2005 session_window_change_req(Session *s)
2006 {
2007         s->col = packet_get_int();
2008         s->row = packet_get_int();
2009         s->xpixel = packet_get_int();
2010         s->ypixel = packet_get_int();
2011         packet_check_eom();
2012         pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
2013         return 1;
2014 }
2015
2016 static int
2017 session_pty_req(Session *s)
2018 {
2019         u_int len;
2020         int n_bytes;
2021
2022         if (no_pty_flag) {
2023                 debug("Allocating a pty not permitted for this authentication.");
2024                 return 0;
2025         }
2026         if (s->ttyfd != -1) {
2027                 packet_disconnect("Protocol error: you already have a pty.");
2028                 return 0;
2029         }
2030
2031         s->term = packet_get_string(&len);
2032
2033         if (compat20) {
2034                 s->col = packet_get_int();
2035                 s->row = packet_get_int();
2036         } else {
2037                 s->row = packet_get_int();
2038                 s->col = packet_get_int();
2039         }
2040         s->xpixel = packet_get_int();
2041         s->ypixel = packet_get_int();
2042
2043         if (strcmp(s->term, "") == 0) {
2044                 xfree(s->term);
2045                 s->term = NULL;
2046         }
2047
2048         /* Allocate a pty and open it. */
2049         debug("Allocating pty.");
2050         if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) {
2051                 if (s->term)
2052                         xfree(s->term);
2053                 s->term = NULL;
2054                 s->ptyfd = -1;
2055                 s->ttyfd = -1;
2056                 error("session_pty_req: session %d alloc failed", s->self);
2057                 return 0;
2058         }
2059         debug("session_pty_req: session %d alloc %s", s->self, s->tty);
2060
2061         /* for SSH1 the tty modes length is not given */
2062         if (!compat20)
2063                 n_bytes = packet_remaining();
2064         tty_parse_modes(s->ttyfd, &n_bytes);
2065
2066         if (!use_privsep)
2067                 pty_setowner(s->pw, s->tty);
2068
2069         /* Set window size from the packet. */
2070         pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
2071
2072         packet_check_eom();
2073         session_proctitle(s);
2074         return 1;
2075 }
2076
2077 static int
2078 session_subsystem_req(Session *s)
2079 {
2080         struct stat st;
2081         u_int len;
2082         int success = 0;
2083         char *prog, *cmd, *subsys = packet_get_string(&len);
2084         u_int i;
2085
2086         packet_check_eom();
2087         logit("subsystem request for %.100s", subsys);
2088
2089         for (i = 0; i < options.num_subsystems; i++) {
2090                 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
2091                         prog = options.subsystem_command[i];
2092                         cmd = options.subsystem_args[i];
2093                         if (stat(prog, &st) < 0) {
2094                                 error("subsystem: cannot stat %s: %s", prog,
2095                                     strerror(errno));
2096                                 break;
2097                         }
2098                         debug("subsystem: exec() %s", cmd);
2099                         s->is_subsystem = 1;
2100                         do_exec(s, cmd);
2101                         success = 1;
2102                         break;
2103                 }
2104         }
2105
2106         if (!success)
2107                 logit("subsystem request for %.100s failed, subsystem not found",
2108                     subsys);
2109
2110         xfree(subsys);
2111         return success;
2112 }
2113
2114 static int
2115 session_x11_req(Session *s)
2116 {
2117         int success;
2118
2119         if (s->auth_proto != NULL || s->auth_data != NULL) {
2120                 error("session_x11_req: session %d: "
2121                     "x11 forwarding already active", s->self);
2122                 return 0;
2123         }
2124         s->single_connection = packet_get_char();
2125         s->auth_proto = packet_get_string(NULL);
2126         s->auth_data = packet_get_string(NULL);
2127         s->screen = packet_get_int();
2128         packet_check_eom();
2129
2130         success = session_setup_x11fwd(s);
2131         if (!success) {
2132                 xfree(s->auth_proto);
2133                 xfree(s->auth_data);
2134                 s->auth_proto = NULL;
2135                 s->auth_data = NULL;
2136         }
2137         return success;
2138 }
2139
2140 static int
2141 session_shell_req(Session *s)
2142 {
2143         packet_check_eom();
2144         do_exec(s, NULL);
2145         return 1;
2146 }
2147
2148 static int
2149 session_exec_req(Session *s)
2150 {
2151         u_int len;
2152         char *command = packet_get_string(&len);
2153         packet_check_eom();
2154         do_exec(s, command);
2155         xfree(command);
2156         return 1;
2157 }
2158
2159 static int
2160 session_break_req(Session *s)
2161 {
2162
2163         packet_get_int();       /* ignored */
2164         packet_check_eom();
2165
2166         if (s->ttyfd == -1 ||
2167             tcsendbreak(s->ttyfd, 0) < 0)
2168                 return 0;
2169         return 1;
2170 }
2171
2172 static int
2173 session_env_req(Session *s)
2174 {
2175         char *name, *val;
2176         u_int name_len, val_len, i;
2177
2178         name = packet_get_string(&name_len);
2179         val = packet_get_string(&val_len);
2180         packet_check_eom();
2181
2182         /* Don't set too many environment variables */
2183         if (s->num_env > 128) {
2184                 debug2("Ignoring env request %s: too many env vars", name);
2185                 goto fail;
2186         }
2187
2188         for (i = 0; i < options.num_accept_env; i++) {
2189                 if (match_pattern(name, options.accept_env[i])) {
2190                         debug2("Setting env %d: %s=%s", s->num_env, name, val);
2191                         s->env = xrealloc(s->env, s->num_env + 1,
2192                             sizeof(*s->env));
2193                         s->env[s->num_env].name = name;
2194                         s->env[s->num_env].val = val;
2195                         s->num_env++;
2196                         return (1);
2197                 }
2198         }
2199         debug2("Ignoring env request %s: disallowed name", name);
2200
2201  fail:
2202         xfree(name);
2203         xfree(val);
2204         return (0);
2205 }
2206
2207 static int
2208 session_auth_agent_req(Session *s)
2209 {
2210         static int called = 0;
2211         packet_check_eom();
2212         if (no_agent_forwarding_flag) {
2213                 debug("session_auth_agent_req: no_agent_forwarding_flag");
2214                 return 0;
2215         }
2216         if (called) {
2217                 return 0;
2218         } else {
2219                 called = 1;
2220                 return auth_input_request_forwarding(s->pw);
2221         }
2222 }
2223
2224 int
2225 session_input_channel_req(Channel *c, const char *rtype)
2226 {
2227         int success = 0;
2228         Session *s;
2229
2230         if ((s = session_by_channel(c->self)) == NULL) {
2231                 logit("session_input_channel_req: no session %d req %.100s",
2232                     c->self, rtype);
2233                 return 0;
2234         }
2235         debug("session_input_channel_req: session %d req %s", s->self, rtype);
2236
2237         /*
2238          * a session is in LARVAL state until a shell, a command
2239          * or a subsystem is executed
2240          */
2241         if (c->type == SSH_CHANNEL_LARVAL) {
2242                 if (strcmp(rtype, "shell") == 0) {
2243                         success = session_shell_req(s);
2244                 } else if (strcmp(rtype, "exec") == 0) {
2245                         success = session_exec_req(s);
2246                 } else if (strcmp(rtype, "pty-req") == 0) {
2247                         success = session_pty_req(s);
2248                 } else if (strcmp(rtype, "x11-req") == 0) {
2249                         success = session_x11_req(s);
2250                 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
2251                         success = session_auth_agent_req(s);
2252                 } else if (strcmp(rtype, "subsystem") == 0) {
2253                         success = session_subsystem_req(s);
2254                 } else if (strcmp(rtype, "env") == 0) {
2255                         success = session_env_req(s);
2256                 }
2257         }
2258         if (strcmp(rtype, "window-change") == 0) {
2259                 success = session_window_change_req(s);
2260         } else if (strcmp(rtype, "break") == 0) {
2261                 success = session_break_req(s);
2262         }
2263
2264         return success;
2265 }
2266
2267 void
2268 session_set_fds(Session *s, int fdin, int fdout, int fderr)
2269 {
2270         if (!compat20)
2271                 fatal("session_set_fds: called for proto != 2.0");
2272         /*
2273          * now that have a child and a pipe to the child,
2274          * we can activate our channel and register the fd's
2275          */
2276         if (s->chanid == -1)
2277                 fatal("no channel for session %d", s->self);
2278         if(options.hpn_disabled) 
2279         channel_set_fds(s->chanid,
2280             fdout, fdin, fderr,
2281             fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2282             1,
2283             CHAN_SES_WINDOW_DEFAULT);
2284         else
2285                 channel_set_fds(s->chanid,
2286                     fdout, fdin, fderr,
2287                     fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2288                     1,
2289                     options.hpn_buffer_size);
2290 }
2291
2292 /*
2293  * Function to perform pty cleanup. Also called if we get aborted abnormally
2294  * (e.g., due to a dropped connection).
2295  */
2296 void
2297 session_pty_cleanup2(Session *s)
2298 {
2299         if (s == NULL) {
2300                 error("session_pty_cleanup: no session");
2301                 return;
2302         }
2303         if (s->ttyfd == -1)
2304                 return;
2305
2306         debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
2307
2308         /* Record that the user has logged out. */
2309         if (s->pid != 0)
2310                 record_logout(s->pid, s->tty, s->pw->pw_name);
2311
2312         /* Release the pseudo-tty. */
2313         if (getuid() == 0)
2314                 pty_release(s->tty);
2315
2316         /*
2317          * Close the server side of the socket pairs.  We must do this after
2318          * the pty cleanup, so that another process doesn't get this pty
2319          * while we're still cleaning up.
2320          */
2321         if (close(s->ptymaster) < 0)
2322                 error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno));
2323
2324         /* unlink pty from session */
2325         s->ttyfd = -1;
2326 }
2327
2328 void
2329 session_pty_cleanup(Session *s)
2330 {
2331         PRIVSEP(session_pty_cleanup2(s));
2332 }
2333
2334 static char *
2335 sig2name(int sig)
2336 {
2337 #define SSH_SIG(x) if (sig == SIG ## x) return #x
2338         SSH_SIG(ABRT);
2339         SSH_SIG(ALRM);
2340         SSH_SIG(FPE);
2341         SSH_SIG(HUP);
2342         SSH_SIG(ILL);
2343         SSH_SIG(INT);
2344         SSH_SIG(KILL);
2345         SSH_SIG(PIPE);
2346         SSH_SIG(QUIT);
2347         SSH_SIG(SEGV);
2348         SSH_SIG(TERM);
2349         SSH_SIG(USR1);
2350         SSH_SIG(USR2);
2351 #undef  SSH_SIG
2352         return "SIG@openssh.com";
2353 }
2354
2355 static void
2356 session_close_x11(int id)
2357 {
2358         Channel *c;
2359
2360         if ((c = channel_by_id(id)) == NULL) {
2361                 debug("session_close_x11: x11 channel %d missing", id);
2362         } else {
2363                 /* Detach X11 listener */
2364                 debug("session_close_x11: detach x11 channel %d", id);
2365                 channel_cancel_cleanup(id);
2366                 if (c->ostate != CHAN_OUTPUT_CLOSED)
2367                         chan_mark_dead(c);
2368         }
2369 }
2370
2371 static void
2372 session_close_single_x11(int id, void *arg)
2373 {
2374         Session *s;
2375         u_int i;
2376
2377         debug3("session_close_single_x11: channel %d", id);
2378         channel_cancel_cleanup(id);
2379         if ((s = session_by_x11_channel(id)) == NULL)
2380                 fatal("session_close_single_x11: no x11 channel %d", id);
2381         for (i = 0; s->x11_chanids[i] != -1; i++) {
2382                 debug("session_close_single_x11: session %d: "
2383                     "closing channel %d", s->self, s->x11_chanids[i]);
2384                 /*
2385                  * The channel "id" is already closing, but make sure we
2386                  * close all of its siblings.
2387                  */
2388                 if (s->x11_chanids[i] != id)
2389                         session_close_x11(s->x11_chanids[i]);
2390         }
2391         xfree(s->x11_chanids);
2392         s->x11_chanids = NULL;
2393         if (s->display) {
2394                 xfree(s->display);
2395                 s->display = NULL;
2396         }
2397         if (s->auth_proto) {
2398                 xfree(s->auth_proto);
2399                 s->auth_proto = NULL;
2400         }
2401         if (s->auth_data) {
2402                 xfree(s->auth_data);
2403                 s->auth_data = NULL;
2404         }
2405         if (s->auth_display) {
2406                 xfree(s->auth_display);
2407                 s->auth_display = NULL;
2408         }
2409 }
2410
2411 static void
2412 session_exit_message(Session *s, int status)
2413 {
2414         Channel *c;
2415
2416         if ((c = channel_lookup(s->chanid)) == NULL)
2417                 fatal("session_exit_message: session %d: no channel %d",
2418                     s->self, s->chanid);
2419         debug("session_exit_message: session %d channel %d pid %ld",
2420             s->self, s->chanid, (long)s->pid);
2421
2422         if (WIFEXITED(status)) {
2423                 channel_request_start(s->chanid, "exit-status", 0);
2424                 packet_put_int(WEXITSTATUS(status));
2425                 packet_send();
2426         } else if (WIFSIGNALED(status)) {
2427                 channel_request_start(s->chanid, "exit-signal", 0);
2428                 packet_put_cstring(sig2name(WTERMSIG(status)));
2429 #ifdef WCOREDUMP
2430                 packet_put_char(WCOREDUMP(status));
2431 #else /* WCOREDUMP */
2432                 packet_put_char(0);
2433 #endif /* WCOREDUMP */
2434                 packet_put_cstring("");
2435                 packet_put_cstring("");
2436                 packet_send();
2437         } else {
2438                 /* Some weird exit cause.  Just exit. */
2439                 packet_disconnect("wait returned status %04x.", status);
2440         }
2441
2442         /* disconnect channel */
2443         debug("session_exit_message: release channel %d", s->chanid);
2444
2445         /*
2446          * Adjust cleanup callback attachment to send close messages when
2447          * the channel gets EOF. The session will be then be closed
2448          * by session_close_by_channel when the childs close their fds.
2449          */
2450         channel_register_cleanup(c->self, session_close_by_channel, 1);
2451
2452         /*
2453          * emulate a write failure with 'chan_write_failed', nobody will be
2454          * interested in data we write.
2455          * Note that we must not call 'chan_read_failed', since there could
2456          * be some more data waiting in the pipe.
2457          */
2458         if (c->ostate != CHAN_OUTPUT_CLOSED)
2459                 chan_write_failed(c);
2460 }
2461
2462 void
2463 session_close(Session *s)
2464 {
2465         u_int i;
2466
2467         debug("session_close: session %d pid %ld", s->self, (long)s->pid);
2468         if (s->ttyfd != -1)
2469                 session_pty_cleanup(s);
2470         if (s->term)
2471                 xfree(s->term);
2472         if (s->display)
2473                 xfree(s->display);
2474         if (s->x11_chanids)
2475                 xfree(s->x11_chanids);
2476         if (s->auth_display)
2477                 xfree(s->auth_display);
2478         if (s->auth_data)
2479                 xfree(s->auth_data);
2480         if (s->auth_proto)
2481                 xfree(s->auth_proto);
2482         s->used = 0;
2483         if (s->env != NULL) {
2484                 for (i = 0; i < s->num_env; i++) {
2485                         xfree(s->env[i].name);
2486                         xfree(s->env[i].val);
2487                 }
2488                 xfree(s->env);
2489         }
2490         session_proctitle(s);
2491 }
2492
2493 void
2494 session_close_by_pid(pid_t pid, int status)
2495 {
2496         Session *s = session_by_pid(pid);
2497         if (s == NULL) {
2498                 debug("session_close_by_pid: no session for pid %ld",
2499                     (long)pid);
2500                 return;
2501         }
2502         if (s->chanid != -1)
2503                 session_exit_message(s, status);
2504         if (s->ttyfd != -1)
2505                 session_pty_cleanup(s);
2506         s->pid = 0;
2507 }
2508
2509 /*
2510  * this is called when a channel dies before
2511  * the session 'child' itself dies
2512  */
2513 void
2514 session_close_by_channel(int id, void *arg)
2515 {
2516         Session *s = session_by_channel(id);
2517         u_int i;
2518
2519         if (s == NULL) {
2520                 debug("session_close_by_channel: no session for id %d", id);
2521                 return;
2522         }
2523         debug("session_close_by_channel: channel %d child %ld",
2524             id, (long)s->pid);
2525         if (s->pid != 0) {
2526                 debug("session_close_by_channel: channel %d: has child", id);
2527                 /*
2528                  * delay detach of session, but release pty, since
2529                  * the fd's to the child are already closed
2530                  */
2531                 if (s->ttyfd != -1)
2532                         session_pty_cleanup(s);
2533                 return;
2534         }
2535         /* detach by removing callback */
2536         channel_cancel_cleanup(s->chanid);
2537
2538         /* Close any X11 listeners associated with this session */
2539         if (s->x11_chanids != NULL) {
2540                 for (i = 0; s->x11_chanids[i] != -1; i++) {
2541                         session_close_x11(s->x11_chanids[i]);
2542                         s->x11_chanids[i] = -1;
2543                 }
2544         }
2545
2546         s->chanid = -1;
2547         session_close(s);
2548 }
2549
2550 void
2551 session_destroy_all(void (*closefunc)(Session *))
2552 {
2553         int i;
2554         for (i = 0; i < MAX_SESSIONS; i++) {
2555                 Session *s = &sessions[i];
2556                 if (s->used) {
2557                         if (closefunc != NULL)
2558                                 closefunc(s);
2559                         else
2560                                 session_close(s);
2561                 }
2562         }
2563 }
2564
2565 static char *
2566 session_tty_list(void)
2567 {
2568         static char buf[1024];
2569         int i;
2570         char *cp;
2571
2572         buf[0] = '\0';
2573         for (i = 0; i < MAX_SESSIONS; i++) {
2574                 Session *s = &sessions[i];
2575                 if (s->used && s->ttyfd != -1) {
2576
2577                         if (strncmp(s->tty, "/dev/", 5) != 0) {
2578                                 cp = strrchr(s->tty, '/');
2579                                 cp = (cp == NULL) ? s->tty : cp + 1;
2580                         } else
2581                                 cp = s->tty + 5;
2582
2583                         if (buf[0] != '\0')
2584                                 strlcat(buf, ",", sizeof buf);
2585                         strlcat(buf, cp, sizeof buf);
2586                 }
2587         }
2588         if (buf[0] == '\0')
2589                 strlcpy(buf, "notty", sizeof buf);
2590         return buf;
2591 }
2592
2593 void
2594 session_proctitle(Session *s)
2595 {
2596         if (s->pw == NULL)
2597                 error("no user for session %d", s->self);
2598         else
2599                 setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
2600 }
2601
2602 int
2603 session_setup_x11fwd(Session *s)
2604 {
2605         struct stat st;
2606         char display[512], auth_display[512];
2607         char hostname[MAXHOSTNAMELEN];
2608         u_int i;
2609
2610         if (no_x11_forwarding_flag) {
2611                 packet_send_debug("X11 forwarding disabled in user configuration file.");
2612                 return 0;
2613         }
2614         if (!options.x11_forwarding) {
2615                 debug("X11 forwarding disabled in server configuration file.");
2616                 return 0;
2617         }
2618         if (!options.xauth_location ||
2619             (stat(options.xauth_location, &st) == -1)) {
2620                 packet_send_debug("No xauth program; cannot forward with spoofing.");
2621                 return 0;
2622         }
2623         if (options.use_login) {
2624                 packet_send_debug("X11 forwarding disabled; "
2625                     "not compatible with UseLogin=yes.");
2626                 return 0;
2627         }
2628         if (s->display != NULL) {
2629                 debug("X11 display already set.");
2630                 return 0;
2631         }
2632         if (x11_create_display_inet(options.x11_display_offset,
2633             options.x11_use_localhost, s->single_connection,
2634             &s->display_number, &s->x11_chanids, 
2635             options.hpn_disabled, options.hpn_buffer_size) == -1) {
2636                 debug("x11_create_display_inet failed.");
2637                 return 0;
2638         }
2639         for (i = 0; s->x11_chanids[i] != -1; i++) {
2640                 channel_register_cleanup(s->x11_chanids[i],
2641                     session_close_single_x11, 0);
2642         }
2643
2644         /* Set up a suitable value for the DISPLAY variable. */
2645         if (gethostname(hostname, sizeof(hostname)) < 0)
2646                 fatal("gethostname: %.100s", strerror(errno));
2647         /*
2648          * auth_display must be used as the displayname when the
2649          * authorization entry is added with xauth(1).  This will be
2650          * different than the DISPLAY string for localhost displays.
2651          */
2652         if (options.x11_use_localhost) {
2653                 snprintf(display, sizeof display, "localhost:%u.%u",
2654                     s->display_number, s->screen);
2655                 snprintf(auth_display, sizeof auth_display, "unix:%u.%u",
2656                     s->display_number, s->screen);
2657                 s->display = xstrdup(display);
2658                 s->auth_display = xstrdup(auth_display);
2659         } else {
2660 #ifdef IPADDR_IN_DISPLAY
2661                 struct hostent *he;
2662                 struct in_addr my_addr;
2663
2664                 he = gethostbyname(hostname);
2665                 if (he == NULL) {
2666                         error("Can't get IP address for X11 DISPLAY.");
2667                         packet_send_debug("Can't get IP address for X11 DISPLAY.");
2668                         return 0;
2669                 }
2670                 memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
2671                 snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr),
2672                     s->display_number, s->screen);
2673 #else
2674                 snprintf(display, sizeof display, "%.400s:%u.%u", hostname,
2675                     s->display_number, s->screen);
2676 #endif
2677                 s->display = xstrdup(display);
2678                 s->auth_display = xstrdup(display);
2679         }
2680
2681         return 1;
2682 }
2683
2684 static void
2685 do_authenticated2(Authctxt *authctxt)
2686 {
2687         server_loop2(authctxt);
2688 }
2689
2690 void
2691 do_cleanup(Authctxt *authctxt)
2692 {
2693         static int called = 0;
2694
2695         debug("do_cleanup");
2696
2697         /* no cleanup if we're in the child for login shell */
2698         if (is_child)
2699                 return;
2700
2701         /* avoid double cleanup */
2702         if (called)
2703                 return;
2704         called = 1;
2705
2706         if (authctxt == NULL)
2707                 return;
2708
2709 #ifdef USE_PAM
2710         if (options.use_pam) {
2711                 sshpam_cleanup();
2712                 sshpam_thread_cleanup();
2713         }
2714 #endif
2715
2716         if (!authctxt->authenticated)
2717                 return;
2718
2719 #ifdef KRB5
2720         if (options.kerberos_ticket_cleanup &&
2721             authctxt->krb5_ctx)
2722                 krb5_cleanup_proc(authctxt);
2723 #endif
2724
2725 #ifdef GSSAPI
2726         if (compat20 && options.gss_cleanup_creds)
2727                 ssh_gssapi_cleanup_creds();
2728 #endif
2729
2730         /* remove agent socket */
2731         auth_sock_cleanup_proc(authctxt->pw);
2732
2733         /*
2734          * Cleanup ptys/utmp only if privsep is disabled,
2735          * or if running in monitor.
2736          */
2737         if (!use_privsep || mm_is_monitor())
2738                 session_destroy_all(session_pty_cleanup2);
2739 }
This page took 3.527259 seconds and 3 git commands to generate.