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