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