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