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 2004 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]; 1037 u_int i, envsize; 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 snprintf(buf, sizeof buf, "%.200s/%.50s", 1089 _PATH_MAILDIR, pw->pw_name); 1090 child_set_env(&env, &envsize, "MAIL", buf); 1091 1092 /* Normal systems set SHELL by default. */ 1093 child_set_env(&env, &envsize, "SHELL", shell); 1094 1095 #ifdef HAVE_DEFOPEN 1096 deflt_do_setup_env(s, shell, &env, &envsize); 1097 #endif /* HAVE_DEFOPEN */ 1098 } 1099 1100 #define PASS_ENV(x) \ 1101 if (getenv(x)) \ 1102 child_set_env(&env, &envsize, x, getenv(x)); 1103 1104 if (getenv("TZ")) 1105 child_set_env(&env, &envsize, "TZ", getenv("TZ")); 1106 1107 PASS_ENV("LANG") 1108 PASS_ENV("LC_ALL") 1109 PASS_ENV("LC_CTYPE") 1110 PASS_ENV("LC_COLLATE") 1111 PASS_ENV("LC_CTIME") 1112 PASS_ENV("LC_NUMERIC") 1113 PASS_ENV("LC_MONETARY") 1114 PASS_ENV("LC_MESSAGES") 1115 1116 #undef PASS_ENV 1117 1118 if (s->env != NULL) 1119 copy_environment(s->env, &env, &envsize); 1120 1121 /* Set custom environment options from RSA authentication. */ 1122 if (!options.use_login) { 1123 while (custom_environment) { 1124 struct envstring *ce = custom_environment; 1125 char *str = ce->s; 1126 1127 for (i = 0; str[i] != '=' && str[i]; i++) 1128 ; 1129 if (str[i] == '=') { 1130 str[i] = 0; 1131 child_set_env(&env, &envsize, str, str + i + 1); 1132 } 1133 custom_environment = ce->next; 1134 xfree(ce->s); 1135 xfree(ce); 1136 } 1137 } 1138 1139 /* SSH_CLIENT deprecated */ 1140 snprintf(buf, sizeof buf, "%.50s %d %d", 1141 get_remote_ipaddr(), get_remote_port(), get_local_port()); 1142 child_set_env(&env, &envsize, "SSH_CLIENT", buf); 1143 1144 snprintf(buf, sizeof buf, "%.50s %d %.50s %d", 1145 get_remote_ipaddr(), get_remote_port(), 1146 get_local_ipaddr(packet_get_connection_in()), get_local_port()); 1147 child_set_env(&env, &envsize, "SSH_CONNECTION", buf); 1148 1149 if (s->ttyfd != -1) 1150 child_set_env(&env, &envsize, "SSH_TTY", s->tty); 1151 if (s->term) 1152 child_set_env(&env, &envsize, "TERM", s->term); 1153 if (s->display) 1154 child_set_env(&env, &envsize, "DISPLAY", s->display); 1155 if (original_command) 1156 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", 1157 original_command); 1158 1159 #ifdef _UNICOS 1160 if (cray_tmpdir[0] != '\0') 1161 child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir); 1162 #endif /* _UNICOS */ 1163 1164 #ifdef _AIX 1165 { 1166 char *cp; 1167 1168 if ((cp = getenv("AUTHSTATE")) != NULL) 1169 child_set_env(&env, &envsize, "AUTHSTATE", cp); 1170 if ((cp = getenv("KRB5CCNAME")) != NULL) 1171 child_set_env(&env, &envsize, "KRB5CCNAME", cp); 1172 read_environment_file(&env, &envsize, "/etc/environment"); 1173 } 1174 #endif 1175 #ifdef KRB4 1176 if (s->authctxt->krb4_ticket_file) 1177 child_set_env(&env, &envsize, "KRBTKFILE", 1178 s->authctxt->krb4_ticket_file); 1179 #endif 1180 #ifdef KRB5 1181 if (s->authctxt->krb5_ticket_file) 1182 child_set_env(&env, &envsize, "KRB5CCNAME", 1183 s->authctxt->krb5_ticket_file); 1184 #endif 1185 #ifdef USE_PAM 1186 /* 1187 * Pull in any environment variables that may have 1188 * been set by PAM. 1189 */ 1190 { 1191 char **p; 1192 1193 p = fetch_pam_environment(s->authctxt); 1194 copy_environment(p, &env, &envsize); 1195 free_pam_environment(p); 1196 } 1197 #endif /* USE_PAM */ 1198 1199 if (auth_sock_name != NULL) 1200 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, 1201 auth_sock_name); 1202 1203 /* read $HOME/.ssh/environment. */ 1204 if (options.permit_user_env && !options.use_login) { 1205 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", 1206 strcmp(pw->pw_dir, "/") ? pw->pw_dir : ""); 1207 read_environment_file(&env, &envsize, buf); 1208 } 1209 if (debug_flag) { 1210 /* dump the environment */ 1211 fprintf(stderr, gettext("Environment:\n")); 1212 for (i = 0; env[i]; i++) 1213 fprintf(stderr, " %.200s\n", env[i]); 1214 } 1215 return env; 1216 } 1217 1218 /* 1219 * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found 1220 * first in this order). 1221 */ 1222 static void 1223 do_rc_files(Session *s, const char *shell) 1224 { 1225 FILE *f = NULL; 1226 char cmd[1024]; 1227 int do_xauth; 1228 struct stat st; 1229 1230 do_xauth = 1231 s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL; 1232 1233 /* ignore _PATH_SSH_USER_RC for subsystems */ 1234 if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) { 1235 snprintf(cmd, sizeof cmd, "%s -c '%s %s'", 1236 shell, _PATH_BSHELL, _PATH_SSH_USER_RC); 1237 if (debug_flag) 1238 fprintf(stderr, "Running %s\n", cmd); 1239 f = popen(cmd, "w"); 1240 if (f) { 1241 if (do_xauth) 1242 fprintf(f, "%s %s\n", s->auth_proto, 1243 s->auth_data); 1244 pclose(f); 1245 } else 1246 fprintf(stderr, "Could not run %s\n", 1247 _PATH_SSH_USER_RC); 1248 } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) { 1249 if (debug_flag) 1250 fprintf(stderr, "Running %s %s\n", _PATH_BSHELL, 1251 _PATH_SSH_SYSTEM_RC); 1252 f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w"); 1253 if (f) { 1254 if (do_xauth) 1255 fprintf(f, "%s %s\n", s->auth_proto, 1256 s->auth_data); 1257 pclose(f); 1258 } else 1259 fprintf(stderr, "Could not run %s\n", 1260 _PATH_SSH_SYSTEM_RC); 1261 } else if (do_xauth && options.xauth_location != NULL) { 1262 /* Add authority data to .Xauthority if appropriate. */ 1263 if (debug_flag) { 1264 fprintf(stderr, 1265 "Running %.500s add " 1266 "%.100s %.100s %.100s\n", 1267 options.xauth_location, s->auth_display, 1268 s->auth_proto, s->auth_data); 1269 } 1270 snprintf(cmd, sizeof cmd, "%s -q -", 1271 options.xauth_location); 1272 f = popen(cmd, "w"); 1273 if (f) { 1274 fprintf(f, "add %s %s %s\n", 1275 s->auth_display, s->auth_proto, 1276 s->auth_data); 1277 pclose(f); 1278 } else { 1279 fprintf(stderr, "Could not run %s\n", 1280 cmd); 1281 } 1282 } 1283 } 1284 1285 static void 1286 do_nologin(struct passwd *pw) 1287 { 1288 FILE *f = NULL; 1289 char buf[1024]; 1290 1291 #ifdef HAVE_LOGIN_CAP 1292 if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) 1293 f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN, 1294 _PATH_NOLOGIN), "r"); 1295 #else 1296 if (pw->pw_uid) 1297 f = fopen(_PATH_NOLOGIN, "r"); 1298 #endif 1299 if (f) { 1300 /* /etc/nologin exists. Print its contents and exit. */ 1301 log("User %.100s not allowed because %s exists", 1302 pw->pw_name, _PATH_NOLOGIN); 1303 while (fgets(buf, sizeof(buf), f)) 1304 fputs(buf, stderr); 1305 fclose(f); 1306 exit(254); 1307 } 1308 } 1309 1310 /* Set login name, uid, gid, and groups. */ 1311 void 1312 do_setusercontext(struct passwd *pw) 1313 { 1314 #ifdef HAVE_CYGWIN 1315 if (is_winnt) { 1316 #else /* HAVE_CYGWIN */ 1317 if (getuid() == 0 || geteuid() == 0) { 1318 #endif /* HAVE_CYGWIN */ 1319 #ifdef HAVE_SETPCRED 1320 setpcred(pw->pw_name); 1321 #endif /* HAVE_SETPCRED */ 1322 #ifdef HAVE_LOGIN_CAP 1323 # ifdef __bsdi__ 1324 setpgid(0, 0); 1325 # endif 1326 if (setusercontext(lc, pw, pw->pw_uid, 1327 (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { 1328 perror("unable to set user context"); 1329 exit(1); 1330 } 1331 #else 1332 # if defined(HAVE_GETLUID) && defined(HAVE_SETLUID) 1333 /* Sets login uid for accounting */ 1334 if (getluid() == -1 && setluid(pw->pw_uid) == -1) 1335 error("setluid: %s", strerror(errno)); 1336 # endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */ 1337 1338 if (setlogin(pw->pw_name) < 0) 1339 error("setlogin failed: %s", strerror(errno)); 1340 if (setgid(pw->pw_gid) < 0) { 1341 perror("setgid"); 1342 exit(1); 1343 } 1344 /* Initialize the group list. */ 1345 if (initgroups(pw->pw_name, pw->pw_gid) < 0) { 1346 perror("initgroups"); 1347 exit(1); 1348 } 1349 endgrent(); 1350 # if 0 1351 # ifdef USE_PAM 1352 /* 1353 * PAM credentials may take the form of supplementary groups. 1354 * These will have been wiped by the above initgroups() call. 1355 * Reestablish them here. 1356 */ 1357 do_pam_setcred(0); 1358 # endif /* USE_PAM */ 1359 # endif /* 0 */ 1360 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) 1361 irix_setusercontext(pw); 1362 # endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 1363 # ifdef _AIX 1364 aix_usrinfo(pw); 1365 # endif /* _AIX */ 1366 /* Permanently switch to the desired uid. */ 1367 permanently_set_uid(pw); 1368 #endif 1369 } 1370 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) 1371 fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); 1372 } 1373 1374 static void 1375 launch_login(struct passwd *pw, const char *hostname) 1376 { 1377 /* Launch login(1). */ 1378 1379 execl(LOGIN_PROGRAM, "login", "-h", hostname, 1380 #ifdef xxxLOGIN_NEEDS_TERM 1381 (s->term ? s->term : "unknown"), 1382 #endif /* LOGIN_NEEDS_TERM */ 1383 #ifdef LOGIN_NO_ENDOPT 1384 "-p", "-f", pw->pw_name, (char *)NULL); 1385 #else 1386 "-p", "-f", "--", pw->pw_name, (char *)NULL); 1387 #endif 1388 1389 /* Login couldn't be executed, die. */ 1390 1391 perror("login"); 1392 exit(1); 1393 } 1394 1395 /* 1396 * Performs common processing for the child, such as setting up the 1397 * environment, closing extra file descriptors, setting the user and group 1398 * ids, and executing the command or shell. 1399 */ 1400 void 1401 do_child(Session *s, const char *command) 1402 { 1403 extern char **environ; 1404 char **env; 1405 char *argv[10]; 1406 const char *shell, *shell0, *hostname = NULL; 1407 struct passwd *pw = s->pw; 1408 1409 /* remove hostkey from the child's memory */ 1410 destroy_sensitive_data(); 1411 1412 /* login(1) is only called if we execute the login shell */ 1413 if (options.use_login && command != NULL) 1414 options.use_login = 0; 1415 1416 #ifdef _UNICOS 1417 cray_setup(pw->pw_uid, pw->pw_name, command); 1418 #endif /* _UNICOS */ 1419 1420 /* 1421 * Login(1) does this as well, and it needs uid 0 for the "-h" 1422 * switch, so we let login(1) to this for us. 1423 */ 1424 if (!options.use_login) { 1425 #ifdef HAVE_OSF_SIA 1426 session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty); 1427 if (!check_quietlogin(s, command)) 1428 do_motd(); 1429 #else /* HAVE_OSF_SIA */ 1430 do_nologin(pw); 1431 do_setusercontext(pw); 1432 #endif /* HAVE_OSF_SIA */ 1433 } 1434 1435 /* 1436 * Get the shell from the password data. An empty shell field is 1437 * legal, and means /bin/sh. 1438 */ 1439 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; 1440 #ifdef HAVE_LOGIN_CAP 1441 shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); 1442 #endif 1443 1444 env = do_setup_env(s, shell); 1445 1446 /* we have to stash the hostname before we close our socket. */ 1447 if (options.use_login) 1448 hostname = get_remote_name_or_ip(utmp_len, 1449 options.verify_reverse_mapping); 1450 /* 1451 * Close the connection descriptors; note that this is the child, and 1452 * the server will still have the socket open, and it is important 1453 * that we do not shutdown it. Note that the descriptors cannot be 1454 * closed before building the environment, as we call 1455 * get_remote_ipaddr there. 1456 */ 1457 if (packet_get_connection_in() == packet_get_connection_out()) 1458 close(packet_get_connection_in()); 1459 else { 1460 close(packet_get_connection_in()); 1461 close(packet_get_connection_out()); 1462 } 1463 /* 1464 * Close all descriptors related to channels. They will still remain 1465 * open in the parent. 1466 */ 1467 /* XXX better use close-on-exec? -markus */ 1468 channel_close_all(); 1469 1470 /* 1471 * Close any extra file descriptors. Note that there may still be 1472 * descriptors left by system functions. They will be closed later. 1473 */ 1474 endpwent(); 1475 1476 /* 1477 * Close any extra open file descriptors so that we don\'t have them 1478 * hanging around in clients. Note that we want to do this after 1479 * initgroups, because at least on Solaris 2.3 it leaves file 1480 * descriptors open. 1481 */ 1482 closefrom(STDERR_FILENO + 1); 1483 1484 /* 1485 * Must take new environment into use so that .ssh/rc, 1486 * /etc/ssh/sshrc and xauth are run in the proper environment. 1487 */ 1488 environ = env; 1489 1490 #ifdef AFS 1491 /* Try to get AFS tokens for the local cell. */ 1492 if (k_hasafs()) { 1493 char cell[64]; 1494 1495 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) 1496 krb_afslog(cell, 0); 1497 1498 krb_afslog(0, 0); 1499 } 1500 #endif /* AFS */ 1501 1502 /* Change current directory to the user\'s home directory. */ 1503 if (chdir(pw->pw_dir) < 0) { 1504 fprintf(stderr, 1505 gettext("Could not chdir to home directory %s: %s\n"), 1506 pw->pw_dir, strerror(errno)); 1507 #ifdef HAVE_LOGIN_CAP 1508 if (login_getcapbool(lc, "requirehome", 0)) 1509 exit(1); 1510 #endif 1511 } 1512 1513 if (!options.use_login) 1514 do_rc_files(s, shell); 1515 1516 /* restore SIGPIPE for child */ 1517 signal(SIGPIPE, SIG_DFL); 1518 1519 if (options.use_login) { 1520 launch_login(pw, hostname); 1521 /* NEVERREACHED */ 1522 } 1523 1524 /* Get the last component of the shell name. */ 1525 if ((shell0 = strrchr(shell, '/')) != NULL) 1526 shell0++; 1527 else 1528 shell0 = shell; 1529 1530 /* 1531 * If we have no command, execute the shell. In this case, the shell 1532 * name to be passed in argv[0] is preceded by '-' to indicate that 1533 * this is a login shell. 1534 */ 1535 if (!command) { 1536 char argv0[256]; 1537 1538 /* Start the shell. Set initial character to '-'. */ 1539 argv0[0] = '-'; 1540 1541 if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1) 1542 >= sizeof(argv0) - 1) { 1543 errno = EINVAL; 1544 perror(shell); 1545 exit(1); 1546 } 1547 1548 /* Execute the shell. */ 1549 argv[0] = argv0; 1550 argv[1] = NULL; 1551 execve(shell, argv, env); 1552 1553 /* Executing the shell failed. */ 1554 perror(shell); 1555 exit(1); 1556 } 1557 /* 1558 * Execute the command using the user's shell. This uses the -c 1559 * option to execute the command. 1560 */ 1561 argv[0] = (char *) shell0; 1562 argv[1] = "-c"; 1563 argv[2] = (char *) command; 1564 argv[3] = NULL; 1565 execve(shell, argv, env); 1566 perror(shell); 1567 exit(1); 1568 } 1569 1570 Session * 1571 session_new(void) 1572 { 1573 int i; 1574 static int did_init = 0; 1575 if (!did_init) { 1576 debug("session_new: init"); 1577 for (i = 0; i < MAX_SESSIONS; i++) { 1578 sessions[i].used = 0; 1579 } 1580 did_init = 1; 1581 } 1582 for (i = 0; i < MAX_SESSIONS; i++) { 1583 Session *s = &sessions[i]; 1584 if (! s->used) { 1585 memset(s, 0, sizeof(*s)); 1586 s->chanid = -1; 1587 s->ptyfd = -1; 1588 s->ttyfd = -1; 1589 s->used = 1; 1590 s->self = i; 1591 s->env = NULL; 1592 debug("session_new: session %d", i); 1593 return s; 1594 } 1595 } 1596 return NULL; 1597 } 1598 1599 static void 1600 session_dump(void) 1601 { 1602 int i; 1603 for (i = 0; i < MAX_SESSIONS; i++) { 1604 Session *s = &sessions[i]; 1605 debug("dump: used %d session %d %p channel %d pid %ld", 1606 s->used, 1607 s->self, 1608 s, 1609 s->chanid, 1610 (long)s->pid); 1611 } 1612 } 1613 1614 int 1615 session_open(Authctxt *authctxt, int chanid) 1616 { 1617 Session *s = session_new(); 1618 debug("session_open: channel %d", chanid); 1619 if (s == NULL) { 1620 error("no more sessions"); 1621 return 0; 1622 } 1623 s->authctxt = authctxt; 1624 s->pw = authctxt->pw; 1625 if (s->pw == NULL) 1626 fatal("no user for session %d", s->self); 1627 debug("session_open: session %d: link with channel %d", s->self, chanid); 1628 s->chanid = chanid; 1629 return 1; 1630 } 1631 1632 #ifndef lint 1633 Session * 1634 session_by_tty(char *tty) 1635 { 1636 int i; 1637 for (i = 0; i < MAX_SESSIONS; i++) { 1638 Session *s = &sessions[i]; 1639 if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { 1640 debug("session_by_tty: session %d tty %s", i, tty); 1641 return s; 1642 } 1643 } 1644 debug("session_by_tty: unknown tty %.100s", tty); 1645 session_dump(); 1646 return NULL; 1647 } 1648 #endif /* lint */ 1649 1650 static Session * 1651 session_by_channel(int id) 1652 { 1653 int i; 1654 for (i = 0; i < MAX_SESSIONS; i++) { 1655 Session *s = &sessions[i]; 1656 if (s->used && s->chanid == id) { 1657 debug("session_by_channel: session %d channel %d", i, id); 1658 return s; 1659 } 1660 } 1661 debug("session_by_channel: unknown channel %d", id); 1662 session_dump(); 1663 return NULL; 1664 } 1665 1666 static Session * 1667 session_by_pid(pid_t pid) 1668 { 1669 int i; 1670 debug("session_by_pid: pid %ld", (long)pid); 1671 for (i = 0; i < MAX_SESSIONS; i++) { 1672 Session *s = &sessions[i]; 1673 if (s->used && s->pid == pid) 1674 return s; 1675 } 1676 error("session_by_pid: unknown pid %ld", (long)pid); 1677 session_dump(); 1678 return NULL; 1679 } 1680 1681 static int 1682 session_window_change_req(Session *s) 1683 { 1684 s->col = packet_get_int(); 1685 s->row = packet_get_int(); 1686 s->xpixel = packet_get_int(); 1687 s->ypixel = packet_get_int(); 1688 packet_check_eom(); 1689 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1690 return 1; 1691 } 1692 1693 static int 1694 session_pty_req(Session *s) 1695 { 1696 u_int len; 1697 int n_bytes; 1698 1699 if (no_pty_flag) { 1700 debug("Allocating a pty not permitted for this authentication."); 1701 return 0; 1702 } 1703 if (s->ttyfd != -1) { 1704 packet_disconnect("Protocol error: you already have a pty."); 1705 return 0; 1706 } 1707 /* Get the time and hostname when the user last logged in. */ 1708 if (options.print_lastlog) { 1709 s->hostname[0] = '\0'; 1710 s->last_login_time = get_last_login_time(s->pw->pw_uid, 1711 s->pw->pw_name, s->hostname, sizeof(s->hostname)); 1712 1713 /* 1714 * PAM may update the last login date. 1715 * 1716 * Ideally PAM would also show the last login date as a 1717 * PAM_TEXT_INFO conversation message, and then we could just 1718 * always force the use of keyboard-interactive just so we can 1719 * pass any such PAM prompts and messages from the account and 1720 * session stacks, but skip pam_authenticate() if other userauth 1721 * has succeeded and the user's password isn't expired. 1722 * 1723 * Unfortunately this depends on support for keyboard- 1724 * interactive in the client, and support for lastlog messages 1725 * in some PAM module. 1726 * 1727 * As it is Solaris updates the lastlog in PAM, but does 1728 * not show the lastlog date in PAM. If and when this state of 1729 * affairs changes this hack can be reconsidered, and, maybe, 1730 * removed. 1731 * 1732 * So we're stuck with a crude hack: get the lastlog 1733 * time before calling pam_open_session() and store it 1734 * in the Authctxt and then use it here once. After 1735 * that, if the client opens any more pty sessions we'll 1736 * show the last lastlog entry since userauth. 1737 */ 1738 if (s->authctxt != NULL && s->authctxt->last_login_time > 0) { 1739 s->last_login_time = s->authctxt->last_login_time; 1740 (void) strlcpy(s->hostname, 1741 s->authctxt->last_login_host, 1742 sizeof(s->hostname)); 1743 s->authctxt->last_login_time = 0; 1744 s->authctxt->last_login_host[0] = '\0'; 1745 } 1746 } 1747 1748 s->term = packet_get_string(&len); 1749 1750 if (compat20) { 1751 s->col = packet_get_int(); 1752 s->row = packet_get_int(); 1753 } else { 1754 s->row = packet_get_int(); 1755 s->col = packet_get_int(); 1756 } 1757 s->xpixel = packet_get_int(); 1758 s->ypixel = packet_get_int(); 1759 1760 if (strcmp(s->term, "") == 0) { 1761 xfree(s->term); 1762 s->term = NULL; 1763 } 1764 1765 /* Allocate a pty and open it. */ 1766 debug("Allocating pty."); 1767 if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) { 1768 if (s->term) 1769 xfree(s->term); 1770 s->term = NULL; 1771 s->ptyfd = -1; 1772 s->ttyfd = -1; 1773 error("session_pty_req: session %d alloc failed", s->self); 1774 return 0; 1775 } 1776 debug("session_pty_req: session %d alloc %s", s->self, s->tty); 1777 1778 /* for SSH1 the tty modes length is not given */ 1779 if (!compat20) 1780 n_bytes = packet_remaining(); 1781 tty_parse_modes(s->ttyfd, &n_bytes); 1782 1783 /* 1784 * Add a cleanup function to clear the utmp entry and record logout 1785 * time in case we call fatal() (e.g., the connection gets closed). 1786 */ 1787 fatal_add_cleanup(session_pty_cleanup, (void *)s); 1788 if (!use_privsep) 1789 pty_setowner(s->pw, s->tty); 1790 1791 /* Set window size from the packet. */ 1792 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1793 1794 packet_check_eom(); 1795 session_proctitle(s); 1796 return 1; 1797 } 1798 1799 static int 1800 session_subsystem_req(Session *s) 1801 { 1802 struct stat st; 1803 u_int len; 1804 int success = 0; 1805 char *cmd, *subsys = packet_get_string(&len); 1806 int i; 1807 1808 packet_check_eom(); 1809 log("subsystem request for %.100s", subsys); 1810 1811 for (i = 0; i < options.num_subsystems; i++) { 1812 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 1813 cmd = options.subsystem_command[i]; 1814 if (stat(cmd, &st) < 0) { 1815 error("subsystem: cannot stat %s: %s", cmd, 1816 strerror(errno)); 1817 break; 1818 } 1819 debug("subsystem: exec() %s", cmd); 1820 s->is_subsystem = 1; 1821 do_exec(s, cmd); 1822 success = 1; 1823 break; 1824 } 1825 } 1826 1827 if (!success) 1828 log("subsystem request for %.100s failed, subsystem not found", 1829 subsys); 1830 1831 xfree(subsys); 1832 return success; 1833 } 1834 1835 static int 1836 session_x11_req(Session *s) 1837 { 1838 int success; 1839 1840 s->single_connection = packet_get_char(); 1841 s->auth_proto = packet_get_string(NULL); 1842 s->auth_data = packet_get_string(NULL); 1843 s->screen = packet_get_int(); 1844 packet_check_eom(); 1845 1846 success = session_setup_x11fwd(s); 1847 if (!success) { 1848 xfree(s->auth_proto); 1849 xfree(s->auth_data); 1850 s->auth_proto = NULL; 1851 s->auth_data = NULL; 1852 } 1853 return success; 1854 } 1855 1856 static int 1857 session_shell_req(Session *s) 1858 { 1859 packet_check_eom(); 1860 do_exec(s, NULL); 1861 return 1; 1862 } 1863 1864 static int 1865 session_exec_req(Session *s) 1866 { 1867 u_int len; 1868 char *command = packet_get_string(&len); 1869 packet_check_eom(); 1870 do_exec(s, command); 1871 xfree(command); 1872 return 1; 1873 } 1874 1875 static int 1876 session_auth_agent_req(Session *s) 1877 { 1878 static int called = 0; 1879 packet_check_eom(); 1880 if (no_agent_forwarding_flag) { 1881 debug("session_auth_agent_req: no_agent_forwarding_flag"); 1882 return 0; 1883 } 1884 if (called) { 1885 return 0; 1886 } else { 1887 called = 1; 1888 return auth_input_request_forwarding(s->pw); 1889 } 1890 } 1891 1892 static int 1893 session_loc_env_check(char *var, char *val) 1894 { 1895 char *current; 1896 int cat, ret; 1897 1898 if (strcmp(var, "LANG") == 0) 1899 cat = LC_ALL; 1900 else if (strcmp(var, "LC_ALL") == 0) 1901 cat = LC_ALL; 1902 else if (strcmp(var, "LC_CTYPE") == 0) 1903 cat = LC_CTYPE; 1904 else if (strcmp(var, "LC_COLLATE") == 0) 1905 cat = LC_COLLATE; 1906 else if (strcmp(var, "LC_TIME") == 0) 1907 cat = LC_TIME; 1908 else if (strcmp(var, "LC_NUMERIC") == 0) 1909 cat = LC_NUMERIC; 1910 else if (strcmp(var, "LC_MONETARY") == 0) 1911 cat = LC_MONETARY; 1912 else if (strcmp(var, "LC_MESSAGES") == 0) 1913 cat = LC_MESSAGES; 1914 1915 if ((current = setlocale(cat, NULL)) != NULL) 1916 current = xstrdup(current); 1917 1918 ret = (setlocale(cat, val) != NULL); 1919 (void) setlocale(cat, current); 1920 return (ret); 1921 } 1922 1923 static int 1924 session_env_req(Session *s) 1925 { 1926 Channel *c; 1927 char *var, *val, *e; 1928 char **p; 1929 size_t len; 1930 int ret = 0; 1931 1932 /* Get var/val from the rest of this packet */ 1933 var = packet_get_string(NULL); 1934 val = packet_get_string(NULL); 1935 1936 /* 1937 * We'll need the channel ID for the packet_send_debug messages, 1938 * so get it now. 1939 */ 1940 if ((c = channel_lookup(s->chanid)) == NULL) 1941 goto done; /* shouldn't happen! */ 1942 1943 debug2("Received request for environment variable %s=%s", var, val); 1944 1945 /* For now allow only LANG and LC_* */ 1946 if (strcmp(var, "LANG") != 0 && strncmp(var, "LC_", 3) != 0) { 1947 debug2("Rejecting request for environment variable %s", var); 1948 goto done; 1949 } 1950 1951 if (!session_loc_env_check(var, val)) { 1952 packet_send_debug(gettext("Missing locale support for %s=%s"), 1953 var, val); 1954 goto done; 1955 } 1956 1957 packet_send_debug(gettext("Channel %d set: %s=%s"), c->remote_id, 1958 var, val); 1959 1960 /* 1961 * Always append new environment variables without regard to old 1962 * ones being overriden. The way these are actually added to 1963 * the environment of the session process later settings 1964 * override earlier ones; see copy_environment(). 1965 */ 1966 if (s->env == NULL) { 1967 char **env; 1968 1969 env = xmalloc(sizeof (char **) * 2); 1970 memset(env, 0, sizeof (char **) * 2); 1971 1972 s->env = env; 1973 p = env; 1974 } else { 1975 for (p = s->env; *p != NULL ; p++); 1976 1977 s->env = xrealloc(s->env, (p - s->env + 2) * sizeof (char **)); 1978 1979 for (p = s->env; *p != NULL ; p++); 1980 } 1981 1982 len = snprintf(NULL, 0, "%s=%s", var, val); 1983 e = xmalloc(len + 1); 1984 (void) snprintf(e, len + 1, "%s=%s", var, val); 1985 1986 (*p++) = e; 1987 *p = NULL; 1988 1989 ret = 1; 1990 1991 done: 1992 xfree(var); 1993 xfree(val); 1994 1995 return (ret); 1996 } 1997 1998 static void 1999 session_free_env(char ***envp) 2000 { 2001 char **env, **p; 2002 2003 if (envp == NULL || *envp == NULL) 2004 return; 2005 2006 env = *envp; 2007 2008 *envp = NULL; 2009 2010 for (p = env; *p != NULL; p++) 2011 xfree(*p); 2012 2013 xfree(env); 2014 } 2015 2016 int 2017 session_input_channel_req(Channel *c, const char *rtype) 2018 { 2019 int success = 0; 2020 Session *s; 2021 2022 if ((s = session_by_channel(c->self)) == NULL) { 2023 log("session_input_channel_req: no session %d req %.100s", 2024 c->self, rtype); 2025 return 0; 2026 } 2027 debug("session_input_channel_req: session %d req %s", s->self, rtype); 2028 2029 /* 2030 * a session is in LARVAL state until a shell, a command 2031 * or a subsystem is executed 2032 */ 2033 if (c->type == SSH_CHANNEL_LARVAL) { 2034 if (strcmp(rtype, "shell") == 0) { 2035 success = session_shell_req(s); 2036 } else if (strcmp(rtype, "exec") == 0) { 2037 success = session_exec_req(s); 2038 } else if (strcmp(rtype, "pty-req") == 0) { 2039 success = session_pty_req(s); 2040 } else if (strcmp(rtype, "x11-req") == 0) { 2041 success = session_x11_req(s); 2042 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { 2043 success = session_auth_agent_req(s); 2044 } else if (strcmp(rtype, "subsystem") == 0) { 2045 success = session_subsystem_req(s); 2046 } else if (strcmp(rtype, "env") == 0) { 2047 success = session_env_req(s); 2048 } 2049 } 2050 if (strcmp(rtype, "window-change") == 0) { 2051 success = session_window_change_req(s); 2052 } 2053 return success; 2054 } 2055 2056 void 2057 session_set_fds(Session *s, int fdin, int fdout, int fderr) 2058 { 2059 if (!compat20) 2060 fatal("session_set_fds: called for proto != 2.0"); 2061 /* 2062 * now that have a child and a pipe to the child, 2063 * we can activate our channel and register the fd's 2064 */ 2065 if (s->chanid == -1) 2066 fatal("no channel for session %d", s->self); 2067 channel_set_fds(s->chanid, 2068 fdout, fdin, fderr, 2069 fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, 2070 1, 2071 CHAN_SES_WINDOW_DEFAULT); 2072 } 2073 2074 /* 2075 * Function to perform pty cleanup. Also called if we get aborted abnormally 2076 * (e.g., due to a dropped connection). 2077 */ 2078 void 2079 session_pty_cleanup2(void *session) 2080 { 2081 Session *s = session; 2082 2083 if (s == NULL) { 2084 error("session_pty_cleanup: no session"); 2085 return; 2086 } 2087 if (s->ttyfd == -1) 2088 return; 2089 2090 debug("session_pty_cleanup: session %d release %s", s->self, s->tty); 2091 2092 #ifdef USE_PAM 2093 session_do_pam(s, 0); 2094 #endif /* USE_PAM */ 2095 2096 /* Record that the user has logged out. */ 2097 if (s->pid != 0) { 2098 debug3("Recording SSHv2 channel login in utmpx/wtmpx"); 2099 #ifdef ALTPRIVSEP 2100 altprivsep_record_logout(s->pid); 2101 #else /* ALTPRIVSEP */ 2102 record_logout(s->pid, s->tty, NULL, s->pw->pw_name); 2103 #endif /* ALTPRIVSEP */ 2104 } 2105 2106 /* Release the pseudo-tty. */ 2107 if (getuid() == 0) 2108 pty_release(s->tty); 2109 2110 /* 2111 * Close the server side of the socket pairs. We must do this after 2112 * the pty cleanup, so that another process doesn't get this pty 2113 * while we're still cleaning up. 2114 */ 2115 if (close(s->ptymaster) < 0) 2116 error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); 2117 2118 /* unlink pty from session */ 2119 s->ttyfd = -1; 2120 } 2121 2122 void 2123 session_pty_cleanup(void *session) 2124 { 2125 PRIVSEP(session_pty_cleanup2(session)); 2126 } 2127 2128 static char * 2129 sig2name(int sig) 2130 { 2131 #define SSH_SIG(x) if (sig == SIG ## x) return #x 2132 SSH_SIG(ABRT); 2133 SSH_SIG(ALRM); 2134 SSH_SIG(FPE); 2135 SSH_SIG(HUP); 2136 SSH_SIG(ILL); 2137 SSH_SIG(INT); 2138 SSH_SIG(KILL); 2139 SSH_SIG(PIPE); 2140 SSH_SIG(QUIT); 2141 SSH_SIG(SEGV); 2142 SSH_SIG(TERM); 2143 SSH_SIG(USR1); 2144 SSH_SIG(USR2); 2145 #undef SSH_SIG 2146 return "SIG@openssh.com"; 2147 } 2148 2149 static void 2150 session_exit_message(Session *s, int status) 2151 { 2152 Channel *c; 2153 2154 if ((c = channel_lookup(s->chanid)) == NULL) 2155 fatal("session_exit_message: session %d: no channel %d", 2156 s->self, s->chanid); 2157 debug("session_exit_message: session %d channel %d pid %ld", 2158 s->self, s->chanid, (long)s->pid); 2159 2160 if (WIFEXITED(status)) { 2161 channel_request_start(s->chanid, "exit-status", 0); 2162 packet_put_int(WEXITSTATUS(status)); 2163 packet_send(); 2164 } else if (WIFSIGNALED(status)) { 2165 channel_request_start(s->chanid, "exit-signal", 0); 2166 packet_put_cstring(sig2name(WTERMSIG(status))); 2167 #ifdef WCOREDUMP 2168 packet_put_char(WCOREDUMP(status)); 2169 #else /* WCOREDUMP */ 2170 packet_put_char(0); 2171 #endif /* WCOREDUMP */ 2172 packet_put_cstring(""); 2173 packet_put_cstring(""); 2174 packet_send(); 2175 } else { 2176 /* Some weird exit cause. Just exit. */ 2177 packet_disconnect("wait returned status %04x.", status); 2178 } 2179 2180 /* Ok to close channel now */ 2181 channel_set_wait_for_exit(s->chanid, 0); 2182 2183 /* disconnect channel */ 2184 debug("session_exit_message: release channel %d", s->chanid); 2185 channel_cancel_cleanup(s->chanid); 2186 /* 2187 * emulate a write failure with 'chan_write_failed', nobody will be 2188 * interested in data we write. 2189 * Note that we must not call 'chan_read_failed', since there could 2190 * be some more data waiting in the pipe. 2191 */ 2192 if (c->ostate != CHAN_OUTPUT_CLOSED) 2193 chan_write_failed(c); 2194 s->chanid = -1; 2195 } 2196 2197 void 2198 session_close(Session *s) 2199 { 2200 debug("session_close: session %d pid %ld", s->self, (long)s->pid); 2201 if (s->ttyfd != -1) { 2202 fatal_remove_cleanup(session_pty_cleanup, (void *)s); 2203 session_pty_cleanup(s); 2204 } 2205 if (s->term) 2206 xfree(s->term); 2207 if (s->display) 2208 xfree(s->display); 2209 if (s->auth_display) 2210 xfree(s->auth_display); 2211 if (s->auth_data) 2212 xfree(s->auth_data); 2213 if (s->auth_proto) 2214 xfree(s->auth_proto); 2215 if (s->command) 2216 xfree(s->command); 2217 session_free_env(&s->env); 2218 s->used = 0; 2219 session_proctitle(s); 2220 } 2221 2222 void 2223 session_close_by_pid(pid_t pid, int status) 2224 { 2225 Session *s = session_by_pid(pid); 2226 if (s == NULL) { 2227 debug("session_close_by_pid: no session for pid %ld", 2228 (long)pid); 2229 return; 2230 } 2231 if (s->chanid != -1) 2232 session_exit_message(s, status); 2233 session_close(s); 2234 } 2235 2236 /* 2237 * this is called when a channel dies before 2238 * the session 'child' itself dies 2239 */ 2240 void 2241 session_close_by_channel(int id, void *arg) 2242 { 2243 Session *s = session_by_channel(id); 2244 if (s == NULL) { 2245 debug("session_close_by_channel: no session for id %d", id); 2246 return; 2247 } 2248 debug("session_close_by_channel: channel %d child %ld", 2249 id, (long)s->pid); 2250 if (s->pid != 0) { 2251 debug("session_close_by_channel: channel %d: has child", id); 2252 /* 2253 * delay detach of session, but release pty, since 2254 * the fd's to the child are already closed 2255 */ 2256 if (s->ttyfd != -1) { 2257 fatal_remove_cleanup(session_pty_cleanup, (void *)s); 2258 session_pty_cleanup(s); 2259 } 2260 return; 2261 } 2262 /* detach by removing callback */ 2263 channel_cancel_cleanup(s->chanid); 2264 s->chanid = -1; 2265 session_close(s); 2266 } 2267 2268 void 2269 session_destroy_all(void (*closefunc)(Session *)) 2270 { 2271 int i; 2272 for (i = 0; i < MAX_SESSIONS; i++) { 2273 Session *s = &sessions[i]; 2274 if (s->used) { 2275 if (closefunc != NULL) 2276 closefunc(s); 2277 else 2278 session_close(s); 2279 } 2280 } 2281 } 2282 2283 static char * 2284 session_tty_list(void) 2285 { 2286 static char buf[1024]; 2287 int i; 2288 buf[0] = '\0'; 2289 for (i = 0; i < MAX_SESSIONS; i++) { 2290 Session *s = &sessions[i]; 2291 if (s->used && s->ttyfd != -1) { 2292 if (buf[0] != '\0') 2293 strlcat(buf, ",", sizeof buf); 2294 strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); 2295 } 2296 } 2297 if (buf[0] == '\0') 2298 strlcpy(buf, "notty", sizeof buf); 2299 return buf; 2300 } 2301 2302 void 2303 session_proctitle(Session *s) 2304 { 2305 if (s->pw == NULL) 2306 error("no user for session %d", s->self); 2307 else 2308 setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); 2309 } 2310 2311 int 2312 session_setup_x11fwd(Session *s) 2313 { 2314 struct stat st; 2315 char display[512], auth_display[512]; 2316 char hostname[MAXHOSTNAMELEN]; 2317 2318 if (no_x11_forwarding_flag) { 2319 packet_send_debug("X11 forwarding disabled in user configuration file."); 2320 return 0; 2321 } 2322 if (!options.x11_forwarding) { 2323 debug("X11 forwarding disabled in server configuration file."); 2324 return 0; 2325 } 2326 if (!options.xauth_location || 2327 (stat(options.xauth_location, &st) == -1)) { 2328 packet_send_debug("No xauth program; cannot forward with spoofing."); 2329 return 0; 2330 } 2331 if (options.use_login) { 2332 packet_send_debug("X11 forwarding disabled; " 2333 "not compatible with UseLogin=yes."); 2334 return 0; 2335 } 2336 if (s->display != NULL) { 2337 debug("X11 display already set."); 2338 return 0; 2339 } 2340 if (x11_create_display_inet(options.x11_display_offset, 2341 options.x11_use_localhost, s->single_connection, 2342 &s->display_number) == -1) { 2343 debug("x11_create_display_inet failed."); 2344 return 0; 2345 } 2346 2347 /* Set up a suitable value for the DISPLAY variable. */ 2348 if (gethostname(hostname, sizeof(hostname)) < 0) 2349 fatal("gethostname: %.100s", strerror(errno)); 2350 /* 2351 * auth_display must be used as the displayname when the 2352 * authorization entry is added with xauth(1). This will be 2353 * different than the DISPLAY string for localhost displays. 2354 */ 2355 if (options.x11_use_localhost) { 2356 snprintf(display, sizeof display, "localhost:%u.%u", 2357 s->display_number, s->screen); 2358 snprintf(auth_display, sizeof auth_display, "unix:%u.%u", 2359 s->display_number, s->screen); 2360 s->display = xstrdup(display); 2361 s->auth_display = xstrdup(auth_display); 2362 } else { 2363 #ifdef IPADDR_IN_DISPLAY 2364 struct hostent *he; 2365 struct in_addr my_addr; 2366 2367 he = gethostbyname(hostname); 2368 if (he == NULL) { 2369 error("Can't get IP address for X11 DISPLAY."); 2370 packet_send_debug("Can't get IP address for X11 DISPLAY."); 2371 return 0; 2372 } 2373 memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); 2374 snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr), 2375 s->display_number, s->screen); 2376 #else 2377 snprintf(display, sizeof display, "%.400s:%u.%u", hostname, 2378 s->display_number, s->screen); 2379 #endif 2380 s->display = xstrdup(display); 2381 s->auth_display = xstrdup(display); 2382 } 2383 2384 return 1; 2385 } 2386 2387 #ifdef USE_PAM 2388 int session_do_pam_conv(int, struct pam_message **, 2389 struct pam_response **, void *); 2390 2391 static struct pam_conv session_pam_conv = { 2392 session_do_pam_conv, 2393 NULL 2394 }; 2395 2396 static void 2397 session_do_pam(Session *s, int do_open) 2398 { 2399 int pam_retval; 2400 char *where, *old_tty, *old_tty_copy = NULL; 2401 struct pam_conv old_conv, *old_conv_ptr; 2402 2403 if (!s || !s->authctxt || !s->authctxt->pam || !s->authctxt->pam->h) 2404 return; 2405 2406 /* Save current PAM item values */ 2407 where = "getting PAM_CONV"; 2408 pam_retval = pam_get_item(s->authctxt->pam->h, PAM_CONV, 2409 (void **) &old_conv_ptr); 2410 if (pam_retval != PAM_SUCCESS) 2411 goto done; 2412 old_conv = *old_conv_ptr; 2413 2414 where = "getting PAM_TTY"; 2415 pam_retval = pam_get_item(s->authctxt->pam->h, PAM_TTY, 2416 (void **) &old_tty); 2417 if (pam_retval != PAM_SUCCESS) 2418 goto done; 2419 old_tty_copy = xstrdup(old_tty); 2420 2421 /* Change PAM_TTY and PAM_CONV items */ 2422 where = "setting PAM_TTY"; 2423 pam_retval = pam_set_item(s->authctxt->pam->h, PAM_TTY, s->tty); 2424 if (pam_retval != PAM_SUCCESS) 2425 goto done; 2426 2427 where = "setting PAM_CONV"; 2428 session_pam_conv.appdata_ptr = s; 2429 pam_retval = pam_set_item(s->authctxt->pam->h, 2430 PAM_CONV, &session_pam_conv); 2431 if (pam_retval != PAM_SUCCESS) 2432 goto done; 2433 2434 /* Call pam_open/close_session() */ 2435 if (do_open) { 2436 where = "calling pam_open_session()"; 2437 pam_retval = pam_open_session(s->authctxt->pam->h, 0); 2438 } 2439 else { 2440 where = "calling pam_close_session()"; 2441 pam_retval = pam_close_session(s->authctxt->pam->h, 0); 2442 } 2443 2444 /* Reset PAM_TTY and PAM_CONV items to previous values */ 2445 where = "setting PAM_TTY"; 2446 pam_retval = pam_set_item(s->authctxt->pam->h, PAM_TTY, old_tty_copy); 2447 if (pam_retval != PAM_SUCCESS) 2448 goto done; 2449 2450 where = "setting PAM_CONV"; 2451 pam_retval = pam_set_item(s->authctxt->pam->h, PAM_CONV, &old_conv); 2452 if (pam_retval != PAM_SUCCESS) 2453 goto done; 2454 2455 session_pam_conv.appdata_ptr = NULL; 2456 2457 done: 2458 if (old_tty_copy) 2459 xfree(old_tty_copy); 2460 2461 if (pam_retval == PAM_SUCCESS) 2462 return; 2463 2464 /* fatal()? probably not... */ 2465 log("PAM failed[%d] while %s: %s", pam_retval, where, 2466 PAM_STRERROR(s->authctxt->pam->h, pam_retval)); 2467 } 2468 2469 int 2470 session_do_pam_conv(int num_prompts, 2471 struct pam_message **prompts, 2472 struct pam_response **resp, 2473 void *app_data) 2474 { 2475 Session *s = (Session *) app_data; 2476 2477 struct pam_response *reply; 2478 int count; 2479 char *prompt; 2480 2481 if (channel_lookup(s->chanid) == NULL) 2482 return PAM_CONV_ERR; 2483 2484 /* PAM will free this later */ 2485 reply = xmalloc(num_prompts * sizeof(*reply)); 2486 2487 (void) memset(reply, 0, num_prompts * sizeof(*reply)); 2488 for (count = 0; count < num_prompts; count++) { 2489 switch(PAM_MSG_MEMBER(prompts, count, msg_style)) { 2490 case PAM_TEXT_INFO: 2491 /* Write to stdout of channel */ 2492 prompt = PAM_MSG_MEMBER(prompts, count, msg); 2493 if (prompt != NULL && s->ttyfd != -1) { 2494 debug2("session_do_pam_conv: text info " 2495 "prompt: %s", prompt); 2496 (void) write(s->ttyfd, prompt, strlen(prompt)); 2497 (void) write(s->ttyfd, "\n", 1); 2498 } 2499 reply[count].resp = xstrdup(""); 2500 reply[count].resp_retcode = PAM_SUCCESS; 2501 break; 2502 case PAM_ERROR_MSG: 2503 /* Write to stderr of channel */ 2504 prompt = PAM_MSG_MEMBER(prompts, count, msg); 2505 if (prompt != NULL && s->ttyfd != -1) { 2506 debug2("session_do_pam_conv: error " 2507 "prompt: %s", prompt); 2508 (void) write(s->ttyfd, prompt, strlen(prompt)); 2509 (void) write(s->ttyfd, "\n", 1); 2510 } 2511 reply[count].resp = xstrdup(""); 2512 reply[count].resp_retcode = PAM_SUCCESS; 2513 break; 2514 case PAM_PROMPT_ECHO_ON: 2515 case PAM_PROMPT_ECHO_OFF: 2516 /* 2517 * XXX Someday add support for echo on/off prompts 2518 * here on sessions with ttys. 2519 */ 2520 default: 2521 xfree(reply); 2522 return PAM_CONV_ERR; 2523 } 2524 } 2525 2526 *resp = reply; 2527 2528 return PAM_SUCCESS; 2529 } 2530 #endif /* USE_PAM */ 2531 2532 static void 2533 do_authenticated2(Authctxt *authctxt) 2534 { 2535 server_loop2(authctxt); 2536 } 2537