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