]> andersk Git - gssapi-openssh.git/blob - openssh/session.c
OPENSSH_4_5P1_20070215 merged to GPT branch
[gssapi-openssh.git] / openssh / session.c
1 /* $OpenBSD: session.c,v 1.220 2006/10/09 23:36:11 djm 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",
1203                                       _PATH_STDPATH_WITH_SCP);
1204                 else
1205                         child_set_env(&env, &envsize, "PATH", getenv("PATH"));
1206 #else /* HAVE_LOGIN_CAP */
1207 # ifndef HAVE_CYGWIN
1208                 /*
1209                  * There's no standard path on Windows. The path contains
1210                  * important components pointing to the system directories,
1211                  * needed for loading shared libraries. So the path better
1212                  * remains intact here.
1213                  */
1214 #  ifdef HAVE_ETC_DEFAULT_LOGIN
1215                 read_etc_default_login(&env, &envsize, pw->pw_uid);
1216                 path = child_get_env(env, "PATH");
1217 #  endif /* HAVE_ETC_DEFAULT_LOGIN */
1218                 if (path == NULL || *path == '\0') {
1219                         child_set_env(&env, &envsize, "PATH",
1220                             s->pw->pw_uid == 0 ?
1221                                 SUPERUSER_PATH : _PATH_STDPATH_WITH_SCP);
1222                 }
1223 # endif /* HAVE_CYGWIN */
1224 #endif /* HAVE_LOGIN_CAP */
1225
1226                 snprintf(buf, sizeof buf, "%.200s/%.50s",
1227                          _PATH_MAILDIR, pw->pw_name);
1228                 child_set_env(&env, &envsize, "MAIL", buf);
1229
1230                 /* Normal systems set SHELL by default. */
1231                 child_set_env(&env, &envsize, "SHELL", shell);
1232         }
1233         if (getenv("TZ"))
1234                 child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1235
1236 #ifdef GSI /* GSI shared libs typically installed in non-system locations. */
1237         {
1238                 char *cp;
1239
1240                 if ((cp = getenv("LD_LIBRARY_PATH")) != NULL)
1241                         child_set_env(&env, &envsize, "LD_LIBRARY_PATH", cp);
1242                 if ((cp = getenv("LIBPATH")) != NULL)
1243                         child_set_env(&env, &envsize, "LIBPATH", cp);
1244                 if ((cp = getenv("SHLIB_PATH")) != NULL)
1245                         child_set_env(&env, &envsize, "SHLIB_PATH", cp);
1246                 if ((cp = getenv("LD_LIBRARYN32_PATH")) != NULL)
1247                         child_set_env(&env, &envsize, "LD_LIBRARYN32_PATH",cp);
1248                 if ((cp = getenv("LD_LIBRARY64_PATH")) != NULL)
1249                         child_set_env(&env, &envsize, "LD_LIBRARY64_PATH",cp);
1250                 if ((cp = getenv("GLOBUS_LOCATION")) != NULL)
1251                         child_set_env(&env, &envsize, "GLOBUS_LOCATION",cp);
1252         }
1253 #endif
1254
1255         /* Set custom environment options from RSA authentication. */
1256         if (!options.use_login) {
1257                 while (custom_environment) {
1258                         struct envstring *ce = custom_environment;
1259                         char *str = ce->s;
1260
1261                         for (i = 0; str[i] != '=' && str[i]; i++)
1262                                 ;
1263                         if (str[i] == '=') {
1264                                 str[i] = 0;
1265                                 child_set_env(&env, &envsize, str, str + i + 1);
1266                         }
1267                         custom_environment = ce->next;
1268                         xfree(ce->s);
1269                         xfree(ce);
1270                 }
1271         }
1272
1273         /* SSH_CLIENT deprecated */
1274         snprintf(buf, sizeof buf, "%.50s %d %d",
1275             get_remote_ipaddr(), get_remote_port(), get_local_port());
1276         child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1277
1278         laddr = get_local_ipaddr(packet_get_connection_in());
1279         snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
1280             get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());
1281         xfree(laddr);
1282         child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1283
1284         if (s->ttyfd != -1)
1285                 child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1286         if (s->term)
1287                 child_set_env(&env, &envsize, "TERM", s->term);
1288         if (s->display)
1289                 child_set_env(&env, &envsize, "DISPLAY", s->display);
1290         if (original_command)
1291                 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1292                     original_command);
1293
1294 #ifdef _UNICOS
1295         if (cray_tmpdir[0] != '\0')
1296                 child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir);
1297 #endif /* _UNICOS */
1298
1299         /*
1300          * Since we clear KRB5CCNAME at startup, if it's set now then it
1301          * must have been set by a native authentication method (eg AIX or
1302          * SIA), so copy it to the child.
1303          */
1304         {
1305                 char *cp;
1306
1307                 if ((cp = getenv("KRB5CCNAME")) != NULL)
1308                         child_set_env(&env, &envsize, "KRB5CCNAME", cp);
1309         }
1310
1311 #ifdef _AIX
1312         {
1313                 char *cp;
1314
1315                 if ((cp = getenv("AUTHSTATE")) != NULL)
1316                         child_set_env(&env, &envsize, "AUTHSTATE", cp);
1317                 read_environment_file(&env, &envsize, "/etc/environment");
1318         }
1319 #endif
1320 #ifdef KRB5
1321         if (s->authctxt->krb5_ccname)
1322                 child_set_env(&env, &envsize, "KRB5CCNAME",
1323                     s->authctxt->krb5_ccname);
1324 #endif
1325 #ifdef USE_PAM
1326         /*
1327          * Pull in any environment variables that may have
1328          * been set by PAM.
1329          */
1330         if (options.use_pam) {
1331                 char **p;
1332
1333                 p = fetch_pam_child_environment();
1334                 copy_environment(p, &env, &envsize);
1335                 free_pam_environment(p);
1336
1337                 p = fetch_pam_environment();
1338                 copy_environment(p, &env, &envsize);
1339                 free_pam_environment(p);
1340         }
1341 #endif /* USE_PAM */
1342
1343         if (auth_sock_name != NULL)
1344                 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1345                     auth_sock_name);
1346
1347         /* read $HOME/.ssh/environment. */
1348         if (options.permit_user_env && !options.use_login) {
1349                 snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
1350                     strcmp(pw->pw_dir, "/") ? pw->pw_dir : "");
1351                 read_environment_file(&env, &envsize, buf);
1352         }
1353         if (debug_flag) {
1354                 /* dump the environment */
1355                 fprintf(stderr, "Environment:\n");
1356                 for (i = 0; env[i]; i++)
1357                         fprintf(stderr, "  %.200s\n", env[i]);
1358         }
1359         return env;
1360 }
1361
1362 /*
1363  * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
1364  * first in this order).
1365  */
1366 static void
1367 do_rc_files(Session *s, const char *shell)
1368 {
1369         FILE *f = NULL;
1370         char cmd[1024];
1371         int do_xauth;
1372         struct stat st;
1373
1374         do_xauth =
1375             s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
1376
1377         /* ignore _PATH_SSH_USER_RC for subsystems */
1378         if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
1379                 snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
1380                     shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
1381                 if (debug_flag)
1382                         fprintf(stderr, "Running %s\n", cmd);
1383                 f = popen(cmd, "w");
1384                 if (f) {
1385                         if (do_xauth)
1386                                 fprintf(f, "%s %s\n", s->auth_proto,
1387                                     s->auth_data);
1388                         pclose(f);
1389                 } else
1390                         fprintf(stderr, "Could not run %s\n",
1391                             _PATH_SSH_USER_RC);
1392         } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
1393                 snprintf(cmd, sizeof cmd, "%s %s", _PATH_BSHELL,
1394                          _PATH_SSH_SYSTEM_RC);
1395                 if (debug_flag)
1396                         fprintf(stderr, "Running %s\n", cmd);
1397                 f = popen(cmd, "w");
1398                 if (f) {
1399                         if (do_xauth)
1400                                 fprintf(f, "%s %s\n", s->auth_proto,
1401                                     s->auth_data);
1402                         pclose(f);
1403                 } else
1404                         fprintf(stderr, "Could not run %s\n",
1405                             _PATH_SSH_SYSTEM_RC);
1406         } else if (do_xauth && options.xauth_location != NULL) {
1407                 /* Add authority data to .Xauthority if appropriate. */
1408                 if (debug_flag) {
1409                         fprintf(stderr,
1410                             "Running %.500s remove %.100s\n",
1411                             options.xauth_location, s->auth_display);
1412                         fprintf(stderr,
1413                             "%.500s add %.100s %.100s %.100s\n",
1414                             options.xauth_location, s->auth_display,
1415                             s->auth_proto, s->auth_data);
1416                 }
1417                 snprintf(cmd, sizeof cmd, "%s -q -",
1418                     options.xauth_location);
1419                 f = popen(cmd, "w");
1420                 if (f) {
1421                         fprintf(f, "remove %s\n",
1422                             s->auth_display);
1423                         fprintf(f, "add %s %s %s\n",
1424                             s->auth_display, s->auth_proto,
1425                             s->auth_data);
1426                         pclose(f);
1427                 } else {
1428                         fprintf(stderr, "Could not run %s\n",
1429                             cmd);
1430                 }
1431         }
1432 }
1433
1434 static void
1435 do_nologin(struct passwd *pw)
1436 {
1437         FILE *f = NULL;
1438         char buf[1024];
1439
1440 #ifdef HAVE_LOGIN_CAP
1441         if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
1442                 f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
1443                     _PATH_NOLOGIN), "r");
1444 #else
1445         if (pw->pw_uid)
1446                 f = fopen(_PATH_NOLOGIN, "r");
1447 #endif
1448         if (f) {
1449                 /* /etc/nologin exists.  Print its contents and exit. */
1450                 logit("User %.100s not allowed because %s exists",
1451                     pw->pw_name, _PATH_NOLOGIN);
1452                 while (fgets(buf, sizeof(buf), f))
1453                         fputs(buf, stderr);
1454                 fclose(f);
1455                 fflush(NULL);
1456                 exit(254);
1457         }
1458 }
1459
1460 /* Set login name, uid, gid, and groups. */
1461 void
1462 do_setusercontext(struct passwd *pw)
1463 {
1464 #ifndef HAVE_CYGWIN
1465         if (getuid() == 0 || geteuid() == 0)
1466 #endif /* HAVE_CYGWIN */
1467         {
1468
1469 #ifdef HAVE_SETPCRED
1470                 if (setpcred(pw->pw_name, (char **)NULL) == -1)
1471                         fatal("Failed to set process credentials");
1472 #endif /* HAVE_SETPCRED */
1473 #ifdef HAVE_LOGIN_CAP
1474 # ifdef __bsdi__
1475                 setpgid(0, 0);
1476 # endif
1477 #ifdef GSSAPI
1478                 if (options.gss_authentication) {
1479                         temporarily_use_uid(pw);
1480                         ssh_gssapi_storecreds();
1481                         restore_uid();
1482                 }
1483 #endif
1484 # ifdef USE_PAM
1485                 if (options.use_pam) {
1486                         do_pam_session();
1487                         do_pam_setcred(0);
1488                 }
1489 # endif /* USE_PAM */
1490                 if (setusercontext(lc, pw, pw->pw_uid,
1491                     (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
1492                         perror("unable to set user context");
1493                         exit(1);
1494                 }
1495 #else
1496 # if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
1497                 /* Sets login uid for accounting */
1498                 if (getluid() == -1 && setluid(pw->pw_uid) == -1)
1499                         error("setluid: %s", strerror(errno));
1500 # endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
1501
1502                 if (setlogin(pw->pw_name) < 0)
1503                         error("setlogin failed: %s", strerror(errno));
1504                 if (setgid(pw->pw_gid) < 0) {
1505                         perror("setgid");
1506                         exit(1);
1507                 }
1508                 /* Initialize the group list. */
1509                 if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
1510                         perror("initgroups");
1511                         exit(1);
1512                 }
1513                 endgrent();
1514 #ifdef GSSAPI
1515                 if (options.gss_authentication) {
1516                         temporarily_use_uid(pw);
1517                         ssh_gssapi_storecreds();
1518                         restore_uid();
1519                 }
1520 #endif
1521 # ifdef USE_PAM
1522                 /*
1523                  * PAM credentials may take the form of supplementary groups.
1524                  * These will have been wiped by the above initgroups() call.
1525                  * Reestablish them here.
1526                  */
1527                 if (options.use_pam) {
1528                         do_pam_session();
1529                         do_pam_setcred(0);
1530                 }
1531 # endif /* USE_PAM */
1532 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
1533                 irix_setusercontext(pw);
1534 #  endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1535 # ifdef _AIX
1536                 aix_usrinfo(pw);
1537 # endif /* _AIX */
1538 #if defined(HAVE_LIBIAF)  &&  !defined(BROKEN_LIBIAF)
1539                 if (set_id(pw->pw_name) != 0) {
1540                         exit(1);
1541                 }
1542 #endif /* HAVE_LIBIAF  && !BROKEN_LIBIAF */
1543                 /* Permanently switch to the desired uid. */
1544                 permanently_set_uid(pw);
1545 #endif
1546         }
1547
1548 #ifdef HAVE_CYGWIN
1549         if (is_winnt)
1550 #endif
1551         if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1552                 fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1553
1554 #ifdef WITH_SELINUX
1555         ssh_selinux_setup_exec_context(pw->pw_name);
1556 #endif
1557 }
1558
1559 static void
1560 do_pwchange(Session *s)
1561 {
1562         fflush(NULL);
1563         fprintf(stderr, "WARNING: Your password has expired.\n");
1564         if (s->ttyfd != -1) {
1565                 fprintf(stderr,
1566                     "You must change your password now and login again!\n");
1567 #ifdef PASSWD_NEEDS_USERNAME
1568                 execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
1569                     (char *)NULL);
1570 #else
1571                 execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
1572 #endif
1573                 perror("passwd");
1574         } else {
1575                 fprintf(stderr,
1576                     "Password change required but no TTY available.\n");
1577         }
1578         exit(1);
1579 }
1580
1581 static void
1582 launch_login(struct passwd *pw, const char *hostname)
1583 {
1584         /* Launch login(1). */
1585
1586         execl(LOGIN_PROGRAM, "login", "-h", hostname,
1587 #ifdef xxxLOGIN_NEEDS_TERM
1588                     (s->term ? s->term : "unknown"),
1589 #endif /* LOGIN_NEEDS_TERM */
1590 #ifdef LOGIN_NO_ENDOPT
1591             "-p", "-f", pw->pw_name, (char *)NULL);
1592 #else
1593             "-p", "-f", "--", pw->pw_name, (char *)NULL);
1594 #endif
1595
1596         /* Login couldn't be executed, die. */
1597
1598         perror("login");
1599         exit(1);
1600 }
1601
1602 static void
1603 child_close_fds(void)
1604 {
1605         int i;
1606
1607         if (packet_get_connection_in() == packet_get_connection_out())
1608                 close(packet_get_connection_in());
1609         else {
1610                 close(packet_get_connection_in());
1611                 close(packet_get_connection_out());
1612         }
1613         /*
1614          * Close all descriptors related to channels.  They will still remain
1615          * open in the parent.
1616          */
1617         /* XXX better use close-on-exec? -markus */
1618         channel_close_all();
1619
1620         /*
1621          * Close any extra file descriptors.  Note that there may still be
1622          * descriptors left by system functions.  They will be closed later.
1623          */
1624         endpwent();
1625
1626         /*
1627          * Close any extra open file descriptors so that we don't have them
1628          * hanging around in clients.  Note that we want to do this after
1629          * initgroups, because at least on Solaris 2.3 it leaves file
1630          * descriptors open.
1631          */
1632         for (i = 3; i < 64; i++)
1633                 close(i);
1634 }
1635
1636 /*
1637  * Performs common processing for the child, such as setting up the
1638  * environment, closing extra file descriptors, setting the user and group
1639  * ids, and executing the command or shell.
1640  */
1641 void
1642 do_child(Session *s, const char *command)
1643 {
1644         extern char **environ;
1645         char **env;
1646         char *argv[10];
1647         const char *shell, *shell0, *hostname = NULL;
1648         struct passwd *pw = s->pw;
1649
1650 #ifdef AFS_KRB5
1651 /* Default place to look for aklog. */
1652 #ifdef AKLOG_PATH
1653 #define KPROGDIR AKLOG_PATH
1654 #else
1655 #define KPROGDIR "/usr/bin/aklog"
1656 #endif /* AKLOG_PATH */
1657
1658         struct stat st;
1659         char *aklog_path;
1660 #endif /* AFS_KRB5 */
1661
1662         /* remove hostkey from the child's memory */
1663         destroy_sensitive_data();
1664
1665         /* Force a password change */
1666         if (s->authctxt->force_pwchange) {
1667                 do_setusercontext(pw);
1668                 child_close_fds();
1669                 do_pwchange(s);
1670                 exit(1);
1671         }
1672
1673         /* login(1) is only called if we execute the login shell */
1674         if (options.use_login && command != NULL)
1675                 options.use_login = 0;
1676
1677 #ifdef _UNICOS
1678         cray_setup(pw->pw_uid, pw->pw_name, command);
1679 #endif /* _UNICOS */
1680
1681         /*
1682          * Login(1) does this as well, and it needs uid 0 for the "-h"
1683          * switch, so we let login(1) to this for us.
1684          */
1685         if (!options.use_login) {
1686 #ifdef HAVE_OSF_SIA
1687                 session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty);
1688                 if (!check_quietlogin(s, command))
1689                         do_motd();
1690 #else /* HAVE_OSF_SIA */
1691                 /* When PAM is enabled we rely on it to do the nologin check */
1692                 if (!options.use_pam)
1693                         do_nologin(pw);
1694                 do_setusercontext(pw);
1695                 /*
1696                  * PAM session modules in do_setusercontext may have
1697                  * generated messages, so if this in an interactive
1698                  * login then display them too.
1699                  */
1700                 if (!check_quietlogin(s, command))
1701                         display_loginmsg();
1702 #endif /* HAVE_OSF_SIA */
1703         }
1704
1705 #ifdef USE_PAM
1706         if (options.use_pam && !options.use_login && !is_pam_session_open()) {
1707                 debug3("PAM session not opened, exiting");
1708                 display_loginmsg();
1709                 exit(254);
1710         }
1711 #endif
1712
1713         /*
1714          * Get the shell from the password data.  An empty shell field is
1715          * legal, and means /bin/sh.
1716          */
1717         shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1718
1719         /*
1720          * Make sure $SHELL points to the shell from the password file,
1721          * even if shell is overridden from login.conf
1722          */
1723         env = do_setup_env(s, shell);
1724
1725 #ifdef HAVE_LOGIN_CAP
1726         shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
1727 #endif
1728
1729         /* we have to stash the hostname before we close our socket. */
1730         if (options.use_login)
1731                 hostname = get_remote_name_or_ip(utmp_len,
1732                     options.use_dns);
1733         /*
1734          * Close the connection descriptors; note that this is the child, and
1735          * the server will still have the socket open, and it is important
1736          * that we do not shutdown it.  Note that the descriptors cannot be
1737          * closed before building the environment, as we call
1738          * get_remote_ipaddr there.
1739          */
1740         child_close_fds();
1741
1742         /*
1743          * Must take new environment into use so that .ssh/rc,
1744          * /etc/ssh/sshrc and xauth are run in the proper environment.
1745          */
1746         environ = env;
1747
1748 #if defined(KRB5) && defined(USE_AFS)
1749         /*
1750          * At this point, we check to see if AFS is active and if we have
1751          * a valid Kerberos 5 TGT. If so, it seems like a good idea to see
1752          * if we can (and need to) extend the ticket into an AFS token. If
1753          * we don't do this, we run into potential problems if the user's
1754          * home directory is in AFS and it's not world-readable.
1755          */
1756
1757         if (options.kerberos_get_afs_token && k_hasafs() &&
1758             (s->authctxt->krb5_ctx != NULL)) {
1759                 char cell[64];
1760
1761                 debug("Getting AFS token");
1762
1763                 k_setpag();
1764
1765                 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1766                         krb5_afslog(s->authctxt->krb5_ctx,
1767                             s->authctxt->krb5_fwd_ccache, cell, NULL);
1768
1769                 krb5_afslog_home(s->authctxt->krb5_ctx,
1770                     s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
1771         }
1772 #endif
1773
1774 #ifdef AFS_KRB5
1775
1776         /* User has authenticated, and if a ticket was going to be
1777          * passed we would have it.  KRB5CCNAME should already be set.
1778          * Now try to get an AFS token using aklog.
1779          */
1780         if (k_hasafs()) {  /* Do we have AFS? */
1781
1782                 aklog_path = xstrdup(KPROGDIR);
1783
1784                 /*
1785                  * Make sure it exists before we try to run it
1786                  */
1787                 if (stat(aklog_path, &st) == 0) {
1788                         debug("Running %s to get afs token.",aklog_path);
1789                         system(aklog_path);
1790                 } else {
1791                         debug("%s does not exist.",aklog_path);
1792                 }
1793
1794                 xfree(aklog_path);
1795         }
1796 #endif /* AFS_KRB5 */
1797
1798 #ifdef SESSION_HOOKS
1799         if (options.session_hooks_allow &&
1800             options.session_hooks_startup_cmd)
1801         {
1802             execute_session_hook(options.session_hooks_startup_cmd,
1803                                  s->authctxt,
1804                                  /* startup = */ 1,
1805                                  options.session_hooks_shutdown_cmd != NULL);
1806         }
1807 #endif
1808
1809         /* Change current directory to the user's home directory. */
1810         if (chdir(pw->pw_dir) < 0) {
1811                 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1812                     pw->pw_dir, strerror(errno));
1813 #ifdef HAVE_LOGIN_CAP
1814                 if (login_getcapbool(lc, "requirehome", 0))
1815                         exit(1);
1816 #endif
1817         }
1818
1819         if (!options.use_login)
1820                 do_rc_files(s, shell);
1821
1822         /* restore SIGPIPE for child */
1823         signal(SIGPIPE, SIG_DFL);
1824
1825         if (options.use_login) {
1826                 launch_login(pw, hostname);
1827                 /* NEVERREACHED */
1828         }
1829
1830         /* Get the last component of the shell name. */
1831         if ((shell0 = strrchr(shell, '/')) != NULL)
1832                 shell0++;
1833         else
1834                 shell0 = shell;
1835
1836         /*
1837          * If we have no command, execute the shell.  In this case, the shell
1838          * name to be passed in argv[0] is preceded by '-' to indicate that
1839          * this is a login shell.
1840          */
1841         if (!command) {
1842                 char argv0[256];
1843
1844                 /* Start the shell.  Set initial character to '-'. */
1845                 argv0[0] = '-';
1846
1847                 if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
1848                     >= sizeof(argv0) - 1) {
1849                         errno = EINVAL;
1850                         perror(shell);
1851                         exit(1);
1852                 }
1853
1854                 /* Execute the shell. */
1855                 argv[0] = argv0;
1856                 argv[1] = NULL;
1857                 execve(shell, argv, environ);
1858
1859                 /* Executing the shell failed. */
1860                 perror(shell);
1861                 exit(1);
1862         }
1863         /*
1864          * Execute the command using the user's shell.  This uses the -c
1865          * option to execute the command.
1866          */
1867         argv[0] = (char *) shell0;
1868         argv[1] = "-c";
1869         argv[2] = (char *) command;
1870         argv[3] = NULL;
1871         execve(shell, argv, environ);
1872         perror(shell);
1873         exit(1);
1874 }
1875
1876 Session *
1877 session_new(void)
1878 {
1879         int i;
1880         static int did_init = 0;
1881         if (!did_init) {
1882                 debug("session_new: init");
1883                 for (i = 0; i < MAX_SESSIONS; i++) {
1884                         sessions[i].used = 0;
1885                 }
1886                 did_init = 1;
1887         }
1888         for (i = 0; i < MAX_SESSIONS; i++) {
1889                 Session *s = &sessions[i];
1890                 if (! s->used) {
1891                         memset(s, 0, sizeof(*s));
1892                         s->chanid = -1;
1893                         s->ptyfd = -1;
1894                         s->ttyfd = -1;
1895                         s->used = 1;
1896                         s->self = i;
1897                         s->x11_chanids = NULL;
1898                         debug("session_new: session %d", i);
1899                         return s;
1900                 }
1901         }
1902         return NULL;
1903 }
1904
1905 static void
1906 session_dump(void)
1907 {
1908         int i;
1909         for (i = 0; i < MAX_SESSIONS; i++) {
1910                 Session *s = &sessions[i];
1911                 debug("dump: used %d session %d %p channel %d pid %ld",
1912                     s->used,
1913                     s->self,
1914                     s,
1915                     s->chanid,
1916                     (long)s->pid);
1917         }
1918 }
1919
1920 int
1921 session_open(Authctxt *authctxt, int chanid)
1922 {
1923         Session *s = session_new();
1924         debug("session_open: channel %d", chanid);
1925         if (s == NULL) {
1926                 error("no more sessions");
1927                 return 0;
1928         }
1929         s->authctxt = authctxt;
1930         s->pw = authctxt->pw;
1931         if (s->pw == NULL || !authctxt->valid)
1932                 fatal("no user for session %d", s->self);
1933         debug("session_open: session %d: link with channel %d", s->self, chanid);
1934         s->chanid = chanid;
1935         return 1;
1936 }
1937
1938 Session *
1939 session_by_tty(char *tty)
1940 {
1941         int i;
1942         for (i = 0; i < MAX_SESSIONS; i++) {
1943                 Session *s = &sessions[i];
1944                 if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
1945                         debug("session_by_tty: session %d tty %s", i, tty);
1946                         return s;
1947                 }
1948         }
1949         debug("session_by_tty: unknown tty %.100s", tty);
1950         session_dump();
1951         return NULL;
1952 }
1953
1954 static Session *
1955 session_by_channel(int id)
1956 {
1957         int i;
1958         for (i = 0; i < MAX_SESSIONS; i++) {
1959                 Session *s = &sessions[i];
1960                 if (s->used && s->chanid == id) {
1961                         debug("session_by_channel: session %d channel %d", i, id);
1962                         return s;
1963                 }
1964         }
1965         debug("session_by_channel: unknown channel %d", id);
1966         session_dump();
1967         return NULL;
1968 }
1969
1970 static Session *
1971 session_by_x11_channel(int id)
1972 {
1973         int i, j;
1974
1975         for (i = 0; i < MAX_SESSIONS; i++) {
1976                 Session *s = &sessions[i];
1977
1978                 if (s->x11_chanids == NULL || !s->used)
1979                         continue;
1980                 for (j = 0; s->x11_chanids[j] != -1; j++) {
1981                         if (s->x11_chanids[j] == id) {
1982                                 debug("session_by_x11_channel: session %d "
1983                                     "channel %d", s->self, id);
1984                                 return s;
1985                         }
1986                 }
1987         }
1988         debug("session_by_x11_channel: unknown channel %d", id);
1989         session_dump();
1990         return NULL;
1991 }
1992
1993 static Session *
1994 session_by_pid(pid_t pid)
1995 {
1996         int i;
1997         debug("session_by_pid: pid %ld", (long)pid);
1998         for (i = 0; i < MAX_SESSIONS; i++) {
1999                 Session *s = &sessions[i];
2000                 if (s->used && s->pid == pid)
2001                         return s;
2002         }
2003         error("session_by_pid: unknown pid %ld", (long)pid);
2004         session_dump();
2005         return NULL;
2006 }
2007
2008 static int
2009 session_window_change_req(Session *s)
2010 {
2011         s->col = packet_get_int();
2012         s->row = packet_get_int();
2013         s->xpixel = packet_get_int();
2014         s->ypixel = packet_get_int();
2015         packet_check_eom();
2016         pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
2017         return 1;
2018 }
2019
2020 static int
2021 session_pty_req(Session *s)
2022 {
2023         u_int len;
2024         int n_bytes;
2025
2026         if (no_pty_flag) {
2027                 debug("Allocating a pty not permitted for this authentication.");
2028                 return 0;
2029         }
2030         if (s->ttyfd != -1) {
2031                 packet_disconnect("Protocol error: you already have a pty.");
2032                 return 0;
2033         }
2034
2035         s->term = packet_get_string(&len);
2036
2037         if (compat20) {
2038                 s->col = packet_get_int();
2039                 s->row = packet_get_int();
2040         } else {
2041                 s->row = packet_get_int();
2042                 s->col = packet_get_int();
2043         }
2044         s->xpixel = packet_get_int();
2045         s->ypixel = packet_get_int();
2046
2047         if (strcmp(s->term, "") == 0) {
2048                 xfree(s->term);
2049                 s->term = NULL;
2050         }
2051
2052         /* Allocate a pty and open it. */
2053         debug("Allocating pty.");
2054         if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) {
2055                 if (s->term)
2056                         xfree(s->term);
2057                 s->term = NULL;
2058                 s->ptyfd = -1;
2059                 s->ttyfd = -1;
2060                 error("session_pty_req: session %d alloc failed", s->self);
2061                 return 0;
2062         }
2063         debug("session_pty_req: session %d alloc %s", s->self, s->tty);
2064
2065         /* for SSH1 the tty modes length is not given */
2066         if (!compat20)
2067                 n_bytes = packet_remaining();
2068         tty_parse_modes(s->ttyfd, &n_bytes);
2069
2070         if (!use_privsep)
2071                 pty_setowner(s->pw, s->tty);
2072
2073         /* Set window size from the packet. */
2074         pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
2075
2076         packet_check_eom();
2077         session_proctitle(s);
2078         return 1;
2079 }
2080
2081 static int
2082 session_subsystem_req(Session *s)
2083 {
2084         struct stat st;
2085         u_int len;
2086         int success = 0;
2087         char *prog, *cmd, *subsys = packet_get_string(&len);
2088         u_int i;
2089
2090         packet_check_eom();
2091         logit("subsystem request for %.100s", subsys);
2092
2093         for (i = 0; i < options.num_subsystems; i++) {
2094                 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
2095                         prog = options.subsystem_command[i];
2096                         cmd = options.subsystem_args[i];
2097                         if (stat(prog, &st) < 0) {
2098                                 error("subsystem: cannot stat %s: %s", prog,
2099                                     strerror(errno));
2100                                 break;
2101                         }
2102                         debug("subsystem: exec() %s", cmd);
2103                         s->is_subsystem = 1;
2104                         do_exec(s, cmd);
2105                         success = 1;
2106                         break;
2107                 }
2108         }
2109
2110         if (!success)
2111                 logit("subsystem request for %.100s failed, subsystem not found",
2112                     subsys);
2113
2114         xfree(subsys);
2115         return success;
2116 }
2117
2118 static int
2119 session_x11_req(Session *s)
2120 {
2121         int success;
2122
2123         if (s->auth_proto != NULL || s->auth_data != NULL) {
2124                 error("session_x11_req: session %d: "
2125                     "x11 forwarding already active", s->self);
2126                 return 0;
2127         }
2128         s->single_connection = packet_get_char();
2129         s->auth_proto = packet_get_string(NULL);
2130         s->auth_data = packet_get_string(NULL);
2131         s->screen = packet_get_int();
2132         packet_check_eom();
2133
2134         success = session_setup_x11fwd(s);
2135         if (!success) {
2136                 xfree(s->auth_proto);
2137                 xfree(s->auth_data);
2138                 s->auth_proto = NULL;
2139                 s->auth_data = NULL;
2140         }
2141         return success;
2142 }
2143
2144 static int
2145 session_shell_req(Session *s)
2146 {
2147         packet_check_eom();
2148         do_exec(s, NULL);
2149         return 1;
2150 }
2151
2152 static int
2153 session_exec_req(Session *s)
2154 {
2155         u_int len;
2156         char *command = packet_get_string(&len);
2157         packet_check_eom();
2158         do_exec(s, command);
2159         xfree(command);
2160         return 1;
2161 }
2162
2163 static int
2164 session_break_req(Session *s)
2165 {
2166
2167         packet_get_int();       /* ignored */
2168         packet_check_eom();
2169
2170         if (s->ttyfd == -1 ||
2171             tcsendbreak(s->ttyfd, 0) < 0)
2172                 return 0;
2173         return 1;
2174 }
2175
2176 static int
2177 session_env_req(Session *s)
2178 {
2179         char *name, *val;
2180         u_int name_len, val_len, i;
2181
2182         name = packet_get_string(&name_len);
2183         val = packet_get_string(&val_len);
2184         packet_check_eom();
2185
2186         /* Don't set too many environment variables */
2187         if (s->num_env > 128) {
2188                 debug2("Ignoring env request %s: too many env vars", name);
2189                 goto fail;
2190         }
2191
2192         for (i = 0; i < options.num_accept_env; i++) {
2193                 if (match_pattern(name, options.accept_env[i])) {
2194                         debug2("Setting env %d: %s=%s", s->num_env, name, val);
2195                         s->env = xrealloc(s->env, s->num_env + 1,
2196                             sizeof(*s->env));
2197                         s->env[s->num_env].name = name;
2198                         s->env[s->num_env].val = val;
2199                         s->num_env++;
2200                         return (1);
2201                 }
2202         }
2203         debug2("Ignoring env request %s: disallowed name", name);
2204
2205  fail:
2206         xfree(name);
2207         xfree(val);
2208         return (0);
2209 }
2210
2211 static int
2212 session_auth_agent_req(Session *s)
2213 {
2214         static int called = 0;
2215         packet_check_eom();
2216         if (no_agent_forwarding_flag) {
2217                 debug("session_auth_agent_req: no_agent_forwarding_flag");
2218                 return 0;
2219         }
2220         if (called) {
2221                 return 0;
2222         } else {
2223                 called = 1;
2224                 return auth_input_request_forwarding(s->pw);
2225         }
2226 }
2227
2228 int
2229 session_input_channel_req(Channel *c, const char *rtype)
2230 {
2231         int success = 0;
2232         Session *s;
2233
2234         if ((s = session_by_channel(c->self)) == NULL) {
2235                 logit("session_input_channel_req: no session %d req %.100s",
2236                     c->self, rtype);
2237                 return 0;
2238         }
2239         debug("session_input_channel_req: session %d req %s", s->self, rtype);
2240
2241         /*
2242          * a session is in LARVAL state until a shell, a command
2243          * or a subsystem is executed
2244          */
2245         if (c->type == SSH_CHANNEL_LARVAL) {
2246                 if (strcmp(rtype, "shell") == 0) {
2247                         success = session_shell_req(s);
2248                 } else if (strcmp(rtype, "exec") == 0) {
2249                         success = session_exec_req(s);
2250                 } else if (strcmp(rtype, "pty-req") == 0) {
2251                         success =  session_pty_req(s);
2252                 } else if (strcmp(rtype, "x11-req") == 0) {
2253                         success = session_x11_req(s);
2254                 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
2255                         success = session_auth_agent_req(s);
2256                 } else if (strcmp(rtype, "subsystem") == 0) {
2257                         success = session_subsystem_req(s);
2258                 } else if (strcmp(rtype, "env") == 0) {
2259                         success = session_env_req(s);
2260                 }
2261         }
2262         if (strcmp(rtype, "window-change") == 0) {
2263                 success = session_window_change_req(s);
2264         } else if (strcmp(rtype, "break") == 0) {
2265                 success = session_break_req(s);
2266         }
2267
2268         return success;
2269 }
2270
2271 void
2272 session_set_fds(Session *s, int fdin, int fdout, int fderr)
2273 {
2274         if (!compat20)
2275                 fatal("session_set_fds: called for proto != 2.0");
2276         /*
2277          * now that have a child and a pipe to the child,
2278          * we can activate our channel and register the fd's
2279          */
2280         if (s->chanid == -1)
2281                 fatal("no channel for session %d", s->self);
2282         if(options.hpn_disabled) 
2283                 channel_set_fds(s->chanid,
2284                     fdout, fdin, fderr,
2285                     fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2286                     1,
2287                     CHAN_SES_WINDOW_DEFAULT);
2288         else
2289                 channel_set_fds(s->chanid,
2290                     fdout, fdin, fderr,
2291                     fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2292                     1,
2293                     options.hpn_buffer_size);
2294 }
2295
2296 /*
2297  * Function to perform pty cleanup. Also called if we get aborted abnormally
2298  * (e.g., due to a dropped connection).
2299  */
2300 void
2301 session_pty_cleanup2(Session *s)
2302 {
2303         if (s == NULL) {
2304                 error("session_pty_cleanup: no session");
2305                 return;
2306         }
2307         if (s->ttyfd == -1)
2308                 return;
2309
2310         debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
2311
2312         /* Record that the user has logged out. */
2313         if (s->pid != 0)
2314                 record_logout(s->pid, s->tty, s->pw->pw_name);
2315
2316         /* Release the pseudo-tty. */
2317         if (getuid() == 0)
2318                 pty_release(s->tty);
2319
2320         /*
2321          * Close the server side of the socket pairs.  We must do this after
2322          * the pty cleanup, so that another process doesn't get this pty
2323          * while we're still cleaning up.
2324          */
2325         if (close(s->ptymaster) < 0)
2326                 error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno));
2327
2328         /* unlink pty from session */
2329         s->ttyfd = -1;
2330 }
2331
2332 void
2333 session_pty_cleanup(Session *s)
2334 {
2335         PRIVSEP(session_pty_cleanup2(s));
2336 }
2337
2338 static char *
2339 sig2name(int sig)
2340 {
2341 #define SSH_SIG(x) if (sig == SIG ## x) return #x
2342         SSH_SIG(ABRT);
2343         SSH_SIG(ALRM);
2344         SSH_SIG(FPE);
2345         SSH_SIG(HUP);
2346         SSH_SIG(ILL);
2347         SSH_SIG(INT);
2348         SSH_SIG(KILL);
2349         SSH_SIG(PIPE);
2350         SSH_SIG(QUIT);
2351         SSH_SIG(SEGV);
2352         SSH_SIG(TERM);
2353         SSH_SIG(USR1);
2354         SSH_SIG(USR2);
2355 #undef  SSH_SIG
2356         return "SIG@openssh.com";
2357 }
2358
2359 static void
2360 session_close_x11(int id)
2361 {
2362         Channel *c;
2363
2364         if ((c = channel_by_id(id)) == NULL) {
2365                 debug("session_close_x11: x11 channel %d missing", id);
2366         } else {
2367                 /* Detach X11 listener */
2368                 debug("session_close_x11: detach x11 channel %d", id);
2369                 channel_cancel_cleanup(id);
2370                 if (c->ostate != CHAN_OUTPUT_CLOSED)
2371                         chan_mark_dead(c);
2372         }
2373 }
2374
2375 static void
2376 session_close_single_x11(int id, void *arg)
2377 {
2378         Session *s;
2379         u_int i;
2380
2381         debug3("session_close_single_x11: channel %d", id);
2382         channel_cancel_cleanup(id);
2383         if ((s  = session_by_x11_channel(id)) == NULL)
2384                 fatal("session_close_single_x11: no x11 channel %d", id);
2385         for (i = 0; s->x11_chanids[i] != -1; i++) {
2386                 debug("session_close_single_x11: session %d: "
2387                     "closing channel %d", s->self, s->x11_chanids[i]);
2388                 /*
2389                  * The channel "id" is already closing, but make sure we
2390                  * close all of its siblings.
2391                  */
2392                 if (s->x11_chanids[i] != id)
2393                         session_close_x11(s->x11_chanids[i]);
2394         }
2395         xfree(s->x11_chanids);
2396         s->x11_chanids = NULL;
2397         if (s->display) {
2398                 xfree(s->display);
2399                 s->display = NULL;
2400         }
2401         if (s->auth_proto) {
2402                 xfree(s->auth_proto);
2403                 s->auth_proto = NULL;
2404         }
2405         if (s->auth_data) {
2406                 xfree(s->auth_data);
2407                 s->auth_data = NULL;
2408         }
2409         if (s->auth_display) {
2410                 xfree(s->auth_display);
2411                 s->auth_display = NULL;
2412         }
2413 }
2414
2415 static void
2416 session_exit_message(Session *s, int status)
2417 {
2418         Channel *c;
2419
2420         if ((c = channel_lookup(s->chanid)) == NULL)
2421                 fatal("session_exit_message: session %d: no channel %d",
2422                     s->self, s->chanid);
2423         debug("session_exit_message: session %d channel %d pid %ld",
2424             s->self, s->chanid, (long)s->pid);
2425
2426         if (WIFEXITED(status)) {
2427                 channel_request_start(s->chanid, "exit-status", 0);
2428                 packet_put_int(WEXITSTATUS(status));
2429                 packet_send();
2430         } else if (WIFSIGNALED(status)) {
2431                 channel_request_start(s->chanid, "exit-signal", 0);
2432                 packet_put_cstring(sig2name(WTERMSIG(status)));
2433 #ifdef WCOREDUMP
2434                 packet_put_char(WCOREDUMP(status));
2435 #else /* WCOREDUMP */
2436                 packet_put_char(0);
2437 #endif /* WCOREDUMP */
2438                 packet_put_cstring("");
2439                 packet_put_cstring("");
2440                 packet_send();
2441         } else {
2442                 /* Some weird exit cause.  Just exit. */
2443                 packet_disconnect("wait returned status %04x.", status);
2444         }
2445
2446         /* disconnect channel */
2447         debug("session_exit_message: release channel %d", s->chanid);
2448
2449         /*
2450          * Adjust cleanup callback attachment to send close messages when
2451          * the channel gets EOF. The session will be then be closed
2452          * by session_close_by_channel when the childs close their fds.
2453          */
2454         channel_register_cleanup(c->self, session_close_by_channel, 1);
2455
2456         /*
2457          * emulate a write failure with 'chan_write_failed', nobody will be
2458          * interested in data we write.
2459          * Note that we must not call 'chan_read_failed', since there could
2460          * be some more data waiting in the pipe.
2461          */
2462         if (c->ostate != CHAN_OUTPUT_CLOSED)
2463                 chan_write_failed(c);
2464 }
2465
2466 void
2467 session_close(Session *s)
2468 {
2469         u_int i;
2470
2471         debug("session_close: session %d pid %ld", s->self, (long)s->pid);
2472         if (s->ttyfd != -1)
2473                 session_pty_cleanup(s);
2474         if (s->term)
2475                 xfree(s->term);
2476         if (s->display)
2477                 xfree(s->display);
2478         if (s->x11_chanids)
2479                 xfree(s->x11_chanids);
2480         if (s->auth_display)
2481                 xfree(s->auth_display);
2482         if (s->auth_data)
2483                 xfree(s->auth_data);
2484         if (s->auth_proto)
2485                 xfree(s->auth_proto);
2486         s->used = 0;
2487         if (s->env != NULL) {
2488                 for (i = 0; i < s->num_env; i++) {
2489                         xfree(s->env[i].name);
2490                         xfree(s->env[i].val);
2491                 }
2492                 xfree(s->env);
2493         }
2494         session_proctitle(s);
2495 }
2496
2497 void
2498 session_close_by_pid(pid_t pid, int status)
2499 {
2500         Session *s = session_by_pid(pid);
2501         if (s == NULL) {
2502                 debug("session_close_by_pid: no session for pid %ld",
2503                     (long)pid);
2504                 return;
2505         }
2506         if (s->chanid != -1)
2507                 session_exit_message(s, status);
2508         if (s->ttyfd != -1)
2509                 session_pty_cleanup(s);
2510         s->pid = 0;
2511 }
2512
2513 /*
2514  * this is called when a channel dies before
2515  * the session 'child' itself dies
2516  */
2517 void
2518 session_close_by_channel(int id, void *arg)
2519 {
2520         Session *s = session_by_channel(id);
2521         u_int i;
2522
2523         if (s == NULL) {
2524                 debug("session_close_by_channel: no session for id %d", id);
2525                 return;
2526         }
2527         debug("session_close_by_channel: channel %d child %ld",
2528             id, (long)s->pid);
2529         if (s->pid != 0) {
2530                 debug("session_close_by_channel: channel %d: has child", id);
2531                 /*
2532                  * delay detach of session, but release pty, since
2533                  * the fd's to the child are already closed
2534                  */
2535                 if (s->ttyfd != -1)
2536                         session_pty_cleanup(s);
2537                 return;
2538         }
2539         /* detach by removing callback */
2540         channel_cancel_cleanup(s->chanid);
2541
2542         /* Close any X11 listeners associated with this session */
2543         if (s->x11_chanids != NULL) {
2544                 for (i = 0; s->x11_chanids[i] != -1; i++) {
2545                         session_close_x11(s->x11_chanids[i]);
2546                         s->x11_chanids[i] = -1;
2547                 }
2548         }
2549
2550         s->chanid = -1;
2551         session_close(s);
2552 }
2553
2554 void
2555 session_destroy_all(void (*closefunc)(Session *))
2556 {
2557         int i;
2558         for (i = 0; i < MAX_SESSIONS; i++) {
2559                 Session *s = &sessions[i];
2560                 if (s->used) {
2561                         if (closefunc != NULL)
2562                                 closefunc(s);
2563                         else
2564                                 session_close(s);
2565                 }
2566         }
2567 }
2568
2569 static char *
2570 session_tty_list(void)
2571 {
2572         static char buf[1024];
2573         int i;
2574         char *cp;
2575
2576         buf[0] = '\0';
2577         for (i = 0; i < MAX_SESSIONS; i++) {
2578                 Session *s = &sessions[i];
2579                 if (s->used && s->ttyfd != -1) {
2580
2581                         if (strncmp(s->tty, "/dev/", 5) != 0) {
2582                                 cp = strrchr(s->tty, '/');
2583                                 cp = (cp == NULL) ? s->tty : cp + 1;
2584                         } else
2585                                 cp = s->tty + 5;
2586
2587                         if (buf[0] != '\0')
2588                                 strlcat(buf, ",", sizeof buf);
2589                         strlcat(buf, cp, sizeof buf);
2590                 }
2591         }
2592         if (buf[0] == '\0')
2593                 strlcpy(buf, "notty", sizeof buf);
2594         return buf;
2595 }
2596
2597 void
2598 session_proctitle(Session *s)
2599 {
2600         if (s->pw == NULL)
2601                 error("no user for session %d", s->self);
2602         else
2603                 setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
2604 }
2605
2606 int
2607 session_setup_x11fwd(Session *s)
2608 {
2609         struct stat st;
2610         char display[512], auth_display[512];
2611         char hostname[MAXHOSTNAMELEN];
2612         u_int i;
2613
2614         if (no_x11_forwarding_flag) {
2615                 packet_send_debug("X11 forwarding disabled in user configuration file.");
2616                 return 0;
2617         }
2618         if (!options.x11_forwarding) {
2619                 debug("X11 forwarding disabled in server configuration file.");
2620                 return 0;
2621         }
2622         if (!options.xauth_location ||
2623             (stat(options.xauth_location, &st) == -1)) {
2624                 packet_send_debug("No xauth program; cannot forward with spoofing.");
2625                 return 0;
2626         }
2627         if (options.use_login) {
2628                 packet_send_debug("X11 forwarding disabled; "
2629                     "not compatible with UseLogin=yes.");
2630                 return 0;
2631         }
2632         if (s->display != NULL) {
2633                 debug("X11 display already set.");
2634                 return 0;
2635         }
2636         if (x11_create_display_inet(options.x11_display_offset,
2637             options.x11_use_localhost, s->single_connection,
2638             &s->display_number, &s->x11_chanids, 
2639             options.hpn_disabled, options.hpn_buffer_size) == -1) {
2640                 debug("x11_create_display_inet failed.");
2641                 return 0;
2642         }
2643         for (i = 0; s->x11_chanids[i] != -1; i++) {
2644                 channel_register_cleanup(s->x11_chanids[i],
2645                     session_close_single_x11, 0);
2646         }
2647
2648         /* Set up a suitable value for the DISPLAY variable. */
2649         if (gethostname(hostname, sizeof(hostname)) < 0)
2650                 fatal("gethostname: %.100s", strerror(errno));
2651         /*
2652          * auth_display must be used as the displayname when the
2653          * authorization entry is added with xauth(1).  This will be
2654          * different than the DISPLAY string for localhost displays.
2655          */
2656         if (options.x11_use_localhost) {
2657                 snprintf(display, sizeof display, "localhost:%u.%u",
2658                     s->display_number, s->screen);
2659                 snprintf(auth_display, sizeof auth_display, "unix:%u.%u",
2660                     s->display_number, s->screen);
2661                 s->display = xstrdup(display);
2662                 s->auth_display = xstrdup(auth_display);
2663         } else {
2664 #ifdef IPADDR_IN_DISPLAY
2665                 struct hostent *he;
2666                 struct in_addr my_addr;
2667
2668                 he = gethostbyname(hostname);
2669                 if (he == NULL) {
2670                         error("Can't get IP address for X11 DISPLAY.");
2671                         packet_send_debug("Can't get IP address for X11 DISPLAY.");
2672                         return 0;
2673                 }
2674                 memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
2675                 snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr),
2676                     s->display_number, s->screen);
2677 #else
2678                 snprintf(display, sizeof display, "%.400s:%u.%u", hostname,
2679                     s->display_number, s->screen);
2680 #endif
2681                 s->display = xstrdup(display);
2682                 s->auth_display = xstrdup(display);
2683         }
2684
2685         return 1;
2686 }
2687
2688 static void
2689 do_authenticated2(Authctxt *authctxt)
2690 {
2691         server_loop2(authctxt);
2692 }
2693
2694 void
2695 do_cleanup(Authctxt *authctxt)
2696 {
2697         static int called = 0;
2698
2699         debug("do_cleanup");
2700
2701         /* no cleanup if we're in the child for login shell */
2702         if (is_child)
2703                 return;
2704
2705         /* avoid double cleanup */
2706         if (called)
2707                 return;
2708         called = 1;
2709
2710         if (authctxt == NULL || !authctxt->authenticated)
2711                 return;
2712 #ifdef KRB5
2713         if (options.kerberos_ticket_cleanup &&
2714             authctxt->krb5_ctx)
2715                 krb5_cleanup_proc(authctxt);
2716 #endif
2717
2718 #ifdef GSSAPI
2719         if (compat20 && options.gss_cleanup_creds)
2720                 ssh_gssapi_cleanup_creds();
2721 #endif
2722
2723 #ifdef USE_PAM
2724         if (options.use_pam) {
2725                 sshpam_cleanup();
2726                 sshpam_thread_cleanup();
2727         }
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 6.222094 seconds and 5 git commands to generate.