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 #include "includes.h" 36 RCSID("$OpenBSD: session.c,v 1.128 2002/02/16 00:51:44 markus Exp $"); 37 38 #include "ssh.h" 39 #include "ssh1.h" 40 #include "ssh2.h" 41 #include "xmalloc.h" 42 #include "sshpty.h" 43 #include "packet.h" 44 #include "buffer.h" 45 #include "mpaux.h" 46 #include "uidswap.h" 47 #include "compat.h" 48 #include "channels.h" 49 #include "bufaux.h" 50 #include "auth.h" 51 #include "auth-options.h" 52 #include "pathnames.h" 53 #include "log.h" 54 #include "servconf.h" 55 #include "sshlogin.h" 56 #include "serverloop.h" 57 #include "canohost.h" 58 #include "session.h" 59 60 /* types */ 61 62 #define TTYSZ 64 63 typedef struct Session Session; 64 struct Session { 65 int used; 66 int self; 67 struct passwd *pw; 68 Authctxt *authctxt; 69 pid_t pid; 70 /* tty */ 71 char *term; 72 int ptyfd, ttyfd, ptymaster; 73 int row, col, xpixel, ypixel; 74 char tty[TTYSZ]; 75 /* X11 */ 76 int display_number; 77 char *display; 78 int screen; 79 char *auth_display; 80 char *auth_proto; 81 char *auth_data; 82 int single_connection; 83 /* proto 2 */ 84 int chanid; 85 int is_subsystem; 86 }; 87 88 /* func */ 89 90 Session *session_new(void); 91 void session_set_fds(Session *, int, int, int); 92 static void session_pty_cleanup(void *); 93 void session_proctitle(Session *); 94 int session_setup_x11fwd(Session *); 95 void do_exec_pty(Session *, const char *); 96 void do_exec_no_pty(Session *, const char *); 97 void do_exec(Session *, const char *); 98 void do_login(Session *, const char *); 99 void do_child(Session *, const char *); 100 void do_motd(void); 101 int check_quietlogin(Session *, const char *); 102 103 static void do_authenticated1(Authctxt *); 104 static void do_authenticated2(Authctxt *); 105 106 static void session_close(Session *); 107 static int session_pty_req(Session *); 108 109 /* import */ 110 extern ServerOptions options; 111 extern char *__progname; 112 extern int log_stderr; 113 extern int debug_flag; 114 extern u_int utmp_len; 115 extern int startup_pipe; 116 extern void destroy_sensitive_data(void); 117 118 /* original command from peer. */ 119 const char *original_command = NULL; 120 121 /* data */ 122 #define MAX_SESSIONS 10 123 Session sessions[MAX_SESSIONS]; 124 125 #ifdef HAVE_LOGIN_CAP 126 static login_cap_t *lc; 127 #endif 128 129 void 130 do_authenticated(Authctxt *authctxt) 131 { 132 /* 133 * Cancel the alarm we set to limit the time taken for 134 * authentication. 135 */ 136 alarm(0); 137 if (startup_pipe != -1) { 138 close(startup_pipe); 139 startup_pipe = -1; 140 } 141 #ifdef HAVE_LOGIN_CAP 142 if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) { 143 error("unable to get login class"); 144 return; 145 } 146 #ifdef BSD_AUTH 147 if (auth_approval(NULL, lc, authctxt->pw->pw_name, "ssh") <= 0) { 148 packet_disconnect("Approval failure for %s", 149 authctxt->pw->pw_name); 150 } 151 #endif 152 #endif 153 /* setup the channel layer */ 154 if (!no_port_forwarding_flag && options.allow_tcp_forwarding) 155 channel_permit_all_opens(); 156 157 if (compat20) 158 do_authenticated2(authctxt); 159 else 160 do_authenticated1(authctxt); 161 162 /* remove agent socket */ 163 if (auth_get_socket_name()) 164 auth_sock_cleanup_proc(authctxt->pw); 165 #ifdef KRB4 166 if (options.kerberos_ticket_cleanup) 167 krb4_cleanup_proc(authctxt); 168 #endif 169 #ifdef KRB5 170 if (options.kerberos_ticket_cleanup) 171 krb5_cleanup_proc(authctxt); 172 #endif 173 } 174 175 /* 176 * Prepares for an interactive session. This is called after the user has 177 * been successfully authenticated. During this message exchange, pseudo 178 * terminals are allocated, X11, TCP/IP, and authentication agent forwardings 179 * are requested, etc. 180 */ 181 static void 182 do_authenticated1(Authctxt *authctxt) 183 { 184 Session *s; 185 char *command; 186 int success, type, screen_flag; 187 int compression_level = 0, enable_compression_after_reply = 0; 188 u_int proto_len, data_len, dlen; 189 190 s = session_new(); 191 s->authctxt = authctxt; 192 s->pw = authctxt->pw; 193 194 /* 195 * We stay in this loop until the client requests to execute a shell 196 * or a command. 197 */ 198 for (;;) { 199 success = 0; 200 201 /* Get a packet from the client. */ 202 type = packet_read(); 203 204 /* Process the packet. */ 205 switch (type) { 206 case SSH_CMSG_REQUEST_COMPRESSION: 207 compression_level = packet_get_int(); 208 packet_check_eom(); 209 if (compression_level < 1 || compression_level > 9) { 210 packet_send_debug("Received illegal compression level %d.", 211 compression_level); 212 break; 213 } 214 /* Enable compression after we have responded with SUCCESS. */ 215 enable_compression_after_reply = 1; 216 success = 1; 217 break; 218 219 case SSH_CMSG_REQUEST_PTY: 220 success = session_pty_req(s); 221 break; 222 223 case SSH_CMSG_X11_REQUEST_FORWARDING: 224 s->auth_proto = packet_get_string(&proto_len); 225 s->auth_data = packet_get_string(&data_len); 226 227 screen_flag = packet_get_protocol_flags() & 228 SSH_PROTOFLAG_SCREEN_NUMBER; 229 debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag); 230 231 if (packet_remaining() == 4) { 232 if (!screen_flag) 233 debug2("Buggy client: " 234 "X11 screen flag missing"); 235 s->screen = packet_get_int(); 236 } else { 237 s->screen = 0; 238 } 239 packet_check_eom(); 240 success = session_setup_x11fwd(s); 241 if (!success) { 242 xfree(s->auth_proto); 243 xfree(s->auth_data); 244 s->auth_proto = NULL; 245 s->auth_data = NULL; 246 } 247 break; 248 249 case SSH_CMSG_AGENT_REQUEST_FORWARDING: 250 if (no_agent_forwarding_flag || compat13) { 251 debug("Authentication agent forwarding not permitted for this authentication."); 252 break; 253 } 254 debug("Received authentication agent forwarding request."); 255 success = auth_input_request_forwarding(s->pw); 256 break; 257 258 case SSH_CMSG_PORT_FORWARD_REQUEST: 259 if (no_port_forwarding_flag) { 260 debug("Port forwarding not permitted for this authentication."); 261 break; 262 } 263 if (!options.allow_tcp_forwarding) { 264 debug("Port forwarding not permitted."); 265 break; 266 } 267 debug("Received TCP/IP port forwarding request."); 268 channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports); 269 success = 1; 270 break; 271 272 case SSH_CMSG_MAX_PACKET_SIZE: 273 if (packet_set_maxsize(packet_get_int()) > 0) 274 success = 1; 275 break; 276 277 #if defined(AFS) || defined(KRB5) 278 case SSH_CMSG_HAVE_KERBEROS_TGT: 279 if (!options.kerberos_tgt_passing) { 280 verbose("Kerberos TGT passing disabled."); 281 } else { 282 char *kdata = packet_get_string(&dlen); 283 packet_check_eom(); 284 285 /* XXX - 0x41, see creds_to_radix version */ 286 if (kdata[0] != 0x41) { 287 #ifdef KRB5 288 krb5_data tgt; 289 tgt.data = kdata; 290 tgt.length = dlen; 291 292 if (auth_krb5_tgt(s->authctxt, &tgt)) 293 success = 1; 294 else 295 verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user); 296 #endif /* KRB5 */ 297 } else { 298 #ifdef AFS 299 if (auth_krb4_tgt(s->authctxt, kdata)) 300 success = 1; 301 else 302 verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user); 303 #endif /* AFS */ 304 } 305 xfree(kdata); 306 } 307 break; 308 #endif /* AFS || KRB5 */ 309 310 #ifdef AFS 311 case SSH_CMSG_HAVE_AFS_TOKEN: 312 if (!options.afs_token_passing || !k_hasafs()) { 313 verbose("AFS token passing disabled."); 314 } else { 315 /* Accept AFS token. */ 316 char *token = packet_get_string(&dlen); 317 packet_check_eom(); 318 319 if (auth_afs_token(s->authctxt, token)) 320 success = 1; 321 else 322 verbose("AFS token refused for %.100s", 323 s->authctxt->user); 324 xfree(token); 325 } 326 break; 327 #endif /* AFS */ 328 329 case SSH_CMSG_EXEC_SHELL: 330 case SSH_CMSG_EXEC_CMD: 331 if (type == SSH_CMSG_EXEC_CMD) { 332 command = packet_get_string(&dlen); 333 debug("Exec command '%.500s'", command); 334 do_exec(s, command); 335 xfree(command); 336 } else { 337 do_exec(s, NULL); 338 } 339 packet_check_eom(); 340 session_close(s); 341 return; 342 343 default: 344 /* 345 * Any unknown messages in this phase are ignored, 346 * and a failure message is returned. 347 */ 348 log("Unknown packet type received after authentication: %d", type); 349 } 350 packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); 351 packet_send(); 352 packet_write_wait(); 353 354 /* Enable compression now that we have replied if appropriate. */ 355 if (enable_compression_after_reply) { 356 enable_compression_after_reply = 0; 357 packet_start_compression(compression_level); 358 } 359 } 360 } 361 362 /* 363 * This is called to fork and execute a command when we have no tty. This 364 * will call do_child from the child, and server_loop from the parent after 365 * setting up file descriptors and such. 366 */ 367 void 368 do_exec_no_pty(Session *s, const char *command) 369 { 370 int pid; 371 372 #ifdef USE_PIPES 373 int pin[2], pout[2], perr[2]; 374 /* Allocate pipes for communicating with the program. */ 375 if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) 376 packet_disconnect("Could not create pipes: %.100s", 377 strerror(errno)); 378 #else /* USE_PIPES */ 379 int inout[2], err[2]; 380 /* Uses socket pairs to communicate with the program. */ 381 if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || 382 socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) 383 packet_disconnect("Could not create socket pairs: %.100s", 384 strerror(errno)); 385 #endif /* USE_PIPES */ 386 if (s == NULL) 387 fatal("do_exec_no_pty: no session"); 388 389 session_proctitle(s); 390 391 /* Fork the child. */ 392 if ((pid = fork()) == 0) { 393 /* Child. Reinitialize the log since the pid has changed. */ 394 log_init(__progname, options.log_level, options.log_facility, log_stderr); 395 396 /* 397 * Create a new session and process group since the 4.4BSD 398 * setlogin() affects the entire process group. 399 */ 400 if (setsid() < 0) 401 error("setsid failed: %.100s", strerror(errno)); 402 403 #ifdef USE_PIPES 404 /* 405 * Redirect stdin. We close the parent side of the socket 406 * pair, and make the child side the standard input. 407 */ 408 close(pin[1]); 409 if (dup2(pin[0], 0) < 0) 410 perror("dup2 stdin"); 411 close(pin[0]); 412 413 /* Redirect stdout. */ 414 close(pout[0]); 415 if (dup2(pout[1], 1) < 0) 416 perror("dup2 stdout"); 417 close(pout[1]); 418 419 /* Redirect stderr. */ 420 close(perr[0]); 421 if (dup2(perr[1], 2) < 0) 422 perror("dup2 stderr"); 423 close(perr[1]); 424 #else /* USE_PIPES */ 425 /* 426 * Redirect stdin, stdout, and stderr. Stdin and stdout will 427 * use the same socket, as some programs (particularly rdist) 428 * seem to depend on it. 429 */ 430 close(inout[1]); 431 close(err[1]); 432 if (dup2(inout[0], 0) < 0) /* stdin */ 433 perror("dup2 stdin"); 434 if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */ 435 perror("dup2 stdout"); 436 if (dup2(err[0], 2) < 0) /* stderr */ 437 perror("dup2 stderr"); 438 #endif /* USE_PIPES */ 439 440 /* Do processing for the child (exec command etc). */ 441 do_child(s, command); 442 /* NOTREACHED */ 443 } 444 if (pid < 0) 445 packet_disconnect("fork failed: %.100s", strerror(errno)); 446 s->pid = pid; 447 /* Set interactive/non-interactive mode. */ 448 packet_set_interactive(s->display != NULL); 449 #ifdef USE_PIPES 450 /* We are the parent. Close the child sides of the pipes. */ 451 close(pin[0]); 452 close(pout[1]); 453 close(perr[1]); 454 455 if (compat20) { 456 session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]); 457 } else { 458 /* Enter the interactive session. */ 459 server_loop(pid, pin[1], pout[0], perr[0]); 460 /* server_loop has closed pin[1], pout[0], and perr[0]. */ 461 } 462 #else /* USE_PIPES */ 463 /* We are the parent. Close the child sides of the socket pairs. */ 464 close(inout[0]); 465 close(err[0]); 466 467 /* 468 * Enter the interactive session. Note: server_loop must be able to 469 * handle the case that fdin and fdout are the same. 470 */ 471 if (compat20) { 472 session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]); 473 } else { 474 server_loop(pid, inout[1], inout[1], err[1]); 475 /* server_loop has closed inout[1] and err[1]. */ 476 } 477 #endif /* USE_PIPES */ 478 } 479 480 /* 481 * This is called to fork and execute a command when we have a tty. This 482 * will call do_child from the child, and server_loop from the parent after 483 * setting up file descriptors, controlling tty, updating wtmp, utmp, 484 * lastlog, and other such operations. 485 */ 486 void 487 do_exec_pty(Session *s, const char *command) 488 { 489 int fdout, ptyfd, ttyfd, ptymaster; 490 pid_t pid; 491 492 if (s == NULL) 493 fatal("do_exec_pty: no session"); 494 ptyfd = s->ptyfd; 495 ttyfd = s->ttyfd; 496 497 /* Fork the child. */ 498 if ((pid = fork()) == 0) { 499 500 /* Child. Reinitialize the log because the pid has changed. */ 501 log_init(__progname, options.log_level, options.log_facility, log_stderr); 502 /* Close the master side of the pseudo tty. */ 503 close(ptyfd); 504 505 /* Make the pseudo tty our controlling tty. */ 506 pty_make_controlling_tty(&ttyfd, s->tty); 507 508 /* Redirect stdin/stdout/stderr from the pseudo tty. */ 509 if (dup2(ttyfd, 0) < 0) 510 error("dup2 stdin: %s", strerror(errno)); 511 if (dup2(ttyfd, 1) < 0) 512 error("dup2 stdout: %s", strerror(errno)); 513 if (dup2(ttyfd, 2) < 0) 514 error("dup2 stderr: %s", strerror(errno)); 515 516 /* Close the extra descriptor for the pseudo tty. */ 517 close(ttyfd); 518 519 /* record login, etc. similar to login(1) */ 520 if (!(options.use_login && command == NULL)) 521 do_login(s, command); 522 523 /* Do common processing for the child, such as execing the command. */ 524 do_child(s, command); 525 /* NOTREACHED */ 526 } 527 if (pid < 0) 528 packet_disconnect("fork failed: %.100s", strerror(errno)); 529 s->pid = pid; 530 531 /* Parent. Close the slave side of the pseudo tty. */ 532 close(ttyfd); 533 534 /* 535 * Create another descriptor of the pty master side for use as the 536 * standard input. We could use the original descriptor, but this 537 * simplifies code in server_loop. The descriptor is bidirectional. 538 */ 539 fdout = dup(ptyfd); 540 if (fdout < 0) 541 packet_disconnect("dup #1 failed: %.100s", strerror(errno)); 542 543 /* we keep a reference to the pty master */ 544 ptymaster = dup(ptyfd); 545 if (ptymaster < 0) 546 packet_disconnect("dup #2 failed: %.100s", strerror(errno)); 547 s->ptymaster = ptymaster; 548 549 /* Enter interactive session. */ 550 packet_set_interactive(1); 551 if (compat20) { 552 session_set_fds(s, ptyfd, fdout, -1); 553 } else { 554 server_loop(pid, ptyfd, fdout, -1); 555 /* server_loop _has_ closed ptyfd and fdout. */ 556 } 557 } 558 559 /* 560 * This is called to fork and execute a command. If another command is 561 * to be forced, execute that instead. 562 */ 563 void 564 do_exec(Session *s, const char *command) 565 { 566 if (forced_command) { 567 original_command = command; 568 command = forced_command; 569 debug("Forced command '%.900s'", command); 570 } 571 572 if (s->ttyfd != -1) 573 do_exec_pty(s, command); 574 else 575 do_exec_no_pty(s, command); 576 577 original_command = NULL; 578 } 579 580 581 /* administrative, login(1)-like work */ 582 void 583 do_login(Session *s, const char *command) 584 { 585 char *time_string; 586 char hostname[MAXHOSTNAMELEN]; 587 socklen_t fromlen; 588 struct sockaddr_storage from; 589 time_t last_login_time; 590 struct passwd * pw = s->pw; 591 pid_t pid = getpid(); 592 593 /* 594 * Get IP address of client. If the connection is not a socket, let 595 * the address be 0.0.0.0. 596 */ 597 memset(&from, 0, sizeof(from)); 598 if (packet_connection_is_on_socket()) { 599 fromlen = sizeof(from); 600 if (getpeername(packet_get_connection_in(), 601 (struct sockaddr *) & from, &fromlen) < 0) { 602 debug("getpeername: %.100s", strerror(errno)); 603 fatal_cleanup(); 604 } 605 } 606 607 /* Get the time and hostname when the user last logged in. */ 608 if (options.print_lastlog) { 609 hostname[0] = '\0'; 610 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, 611 hostname, sizeof(hostname)); 612 } 613 614 /* Record that there was a login on that tty from the remote host. */ 615 record_login(pid, s->tty, pw->pw_name, pw->pw_uid, 616 get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), 617 (struct sockaddr *)&from); 618 619 if (check_quietlogin(s, command)) 620 return; 621 622 if (options.print_lastlog && last_login_time != 0) { 623 time_string = ctime(&last_login_time); 624 if (strchr(time_string, '\n')) 625 *strchr(time_string, '\n') = 0; 626 if (strcmp(hostname, "") == 0) 627 printf("Last login: %s\r\n", time_string); 628 else 629 printf("Last login: %s from %s\r\n", time_string, hostname); 630 } 631 632 do_motd(); 633 } 634 635 /* 636 * Display the message of the day. 637 */ 638 void 639 do_motd(void) 640 { 641 FILE *f; 642 char buf[256]; 643 644 if (options.print_motd) { 645 #ifdef HAVE_LOGIN_CAP 646 f = fopen(login_getcapstr(lc, "welcome", "/etc/motd", 647 "/etc/motd"), "r"); 648 #else 649 f = fopen("/etc/motd", "r"); 650 #endif 651 if (f) { 652 while (fgets(buf, sizeof(buf), f)) 653 fputs(buf, stdout); 654 fclose(f); 655 } 656 } 657 } 658 659 660 /* 661 * Check for quiet login, either .hushlogin or command given. 662 */ 663 int 664 check_quietlogin(Session *s, const char *command) 665 { 666 char buf[256]; 667 struct passwd *pw = s->pw; 668 struct stat st; 669 670 /* Return 1 if .hushlogin exists or a command given. */ 671 if (command != NULL) 672 return 1; 673 snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); 674 #ifdef HAVE_LOGIN_CAP 675 if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0) 676 return 1; 677 #else 678 if (stat(buf, &st) >= 0) 679 return 1; 680 #endif 681 return 0; 682 } 683 684 /* 685 * Sets the value of the given variable in the environment. If the variable 686 * already exists, its value is overriden. 687 */ 688 static void 689 child_set_env(char ***envp, u_int *envsizep, const char *name, 690 const char *value) 691 { 692 u_int i, namelen; 693 char **env; 694 695 /* 696 * Find the slot where the value should be stored. If the variable 697 * already exists, we reuse the slot; otherwise we append a new slot 698 * at the end of the array, expanding if necessary. 699 */ 700 env = *envp; 701 namelen = strlen(name); 702 for (i = 0; env[i]; i++) 703 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') 704 break; 705 if (env[i]) { 706 /* Reuse the slot. */ 707 xfree(env[i]); 708 } else { 709 /* New variable. Expand if necessary. */ 710 if (i >= (*envsizep) - 1) { 711 (*envsizep) += 50; 712 env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); 713 } 714 /* Need to set the NULL pointer at end of array beyond the new slot. */ 715 env[i + 1] = NULL; 716 } 717 718 /* Allocate space and format the variable in the appropriate slot. */ 719 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); 720 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); 721 } 722 723 /* 724 * Reads environment variables from the given file and adds/overrides them 725 * into the environment. If the file does not exist, this does nothing. 726 * Otherwise, it must consist of empty lines, comments (line starts with '#') 727 * and assignments of the form name=value. No other forms are allowed. 728 */ 729 static void 730 read_environment_file(char ***env, u_int *envsize, 731 const char *filename) 732 { 733 FILE *f; 734 char buf[4096]; 735 char *cp, *value; 736 737 f = fopen(filename, "r"); 738 if (!f) 739 return; 740 741 while (fgets(buf, sizeof(buf), f)) { 742 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) 743 ; 744 if (!*cp || *cp == '#' || *cp == '\n') 745 continue; 746 if (strchr(cp, '\n')) 747 *strchr(cp, '\n') = '\0'; 748 value = strchr(cp, '='); 749 if (value == NULL) { 750 fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); 751 continue; 752 } 753 /* 754 * Replace the equals sign by nul, and advance value to 755 * the value string. 756 */ 757 *value = '\0'; 758 value++; 759 child_set_env(env, envsize, cp, value); 760 } 761 fclose(f); 762 } 763 764 static char ** 765 do_setup_env(Session *s, const char *shell) 766 { 767 char buf[256]; 768 u_int i, envsize; 769 char **env; 770 struct passwd *pw = s->pw; 771 772 /* Initialize the environment. */ 773 envsize = 100; 774 env = xmalloc(envsize * sizeof(char *)); 775 env[0] = NULL; 776 777 if (!options.use_login) { 778 /* Set basic environment. */ 779 child_set_env(&env, &envsize, "USER", pw->pw_name); 780 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); 781 child_set_env(&env, &envsize, "HOME", pw->pw_dir); 782 #ifdef HAVE_LOGIN_CAP 783 (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH); 784 child_set_env(&env, &envsize, "PATH", getenv("PATH")); 785 #else 786 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); 787 #endif 788 789 snprintf(buf, sizeof buf, "%.200s/%.50s", 790 _PATH_MAILDIR, pw->pw_name); 791 child_set_env(&env, &envsize, "MAIL", buf); 792 793 /* Normal systems set SHELL by default. */ 794 child_set_env(&env, &envsize, "SHELL", shell); 795 } 796 if (getenv("TZ")) 797 child_set_env(&env, &envsize, "TZ", getenv("TZ")); 798 799 /* Set custom environment options from RSA authentication. */ 800 if (!options.use_login) { 801 while (custom_environment) { 802 struct envstring *ce = custom_environment; 803 char *s = ce->s; 804 805 for (i = 0; s[i] != '=' && s[i]; i++) 806 ; 807 if (s[i] == '=') { 808 s[i] = 0; 809 child_set_env(&env, &envsize, s, s + i + 1); 810 } 811 custom_environment = ce->next; 812 xfree(ce->s); 813 xfree(ce); 814 } 815 } 816 817 snprintf(buf, sizeof buf, "%.50s %d %d", 818 get_remote_ipaddr(), get_remote_port(), get_local_port()); 819 child_set_env(&env, &envsize, "SSH_CLIENT", buf); 820 821 if (s->ttyfd != -1) 822 child_set_env(&env, &envsize, "SSH_TTY", s->tty); 823 if (s->term) 824 child_set_env(&env, &envsize, "TERM", s->term); 825 if (s->display) 826 child_set_env(&env, &envsize, "DISPLAY", s->display); 827 if (original_command) 828 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", 829 original_command); 830 #ifdef KRB4 831 if (s->authctxt->krb4_ticket_file) 832 child_set_env(&env, &envsize, "KRBTKFILE", 833 s->authctxt->krb4_ticket_file); 834 #endif 835 #ifdef KRB5 836 if (s->authctxt->krb5_ticket_file) 837 child_set_env(&env, &envsize, "KRB5CCNAME", 838 s->authctxt->krb5_ticket_file); 839 #endif 840 if (auth_get_socket_name() != NULL) 841 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, 842 auth_get_socket_name()); 843 844 /* read $HOME/.ssh/environment. */ 845 if (!options.use_login) { 846 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", 847 pw->pw_dir); 848 read_environment_file(&env, &envsize, buf); 849 } 850 if (debug_flag) { 851 /* dump the environment */ 852 fprintf(stderr, "Environment:\n"); 853 for (i = 0; env[i]; i++) 854 fprintf(stderr, " %.200s\n", env[i]); 855 } 856 return env; 857 } 858 859 /* 860 * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found 861 * first in this order). 862 */ 863 static void 864 do_rc_files(Session *s, const char *shell) 865 { 866 FILE *f = NULL; 867 char cmd[1024]; 868 int do_xauth; 869 struct stat st; 870 871 do_xauth = 872 s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL; 873 874 /* ignore _PATH_SSH_USER_RC for subsystems */ 875 if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) { 876 snprintf(cmd, sizeof cmd, "%s -c '%s %s'", 877 shell, _PATH_BSHELL, _PATH_SSH_USER_RC); 878 if (debug_flag) 879 fprintf(stderr, "Running %s\n", cmd); 880 f = popen(cmd, "w"); 881 if (f) { 882 if (do_xauth) 883 fprintf(f, "%s %s\n", s->auth_proto, 884 s->auth_data); 885 pclose(f); 886 } else 887 fprintf(stderr, "Could not run %s\n", 888 _PATH_SSH_USER_RC); 889 } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) { 890 if (debug_flag) 891 fprintf(stderr, "Running %s %s\n", _PATH_BSHELL, 892 _PATH_SSH_SYSTEM_RC); 893 f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w"); 894 if (f) { 895 if (do_xauth) 896 fprintf(f, "%s %s\n", s->auth_proto, 897 s->auth_data); 898 pclose(f); 899 } else 900 fprintf(stderr, "Could not run %s\n", 901 _PATH_SSH_SYSTEM_RC); 902 } else if (do_xauth && options.xauth_location != NULL) { 903 /* Add authority data to .Xauthority if appropriate. */ 904 if (debug_flag) { 905 fprintf(stderr, 906 "Running %.100s add " 907 "%.100s %.100s %.100s\n", 908 options.xauth_location, s->auth_display, 909 s->auth_proto, s->auth_data); 910 } 911 snprintf(cmd, sizeof cmd, "%s -q -", 912 options.xauth_location); 913 f = popen(cmd, "w"); 914 if (f) { 915 fprintf(f, "add %s %s %s\n", 916 s->auth_display, s->auth_proto, 917 s->auth_data); 918 pclose(f); 919 } else { 920 fprintf(stderr, "Could not run %s\n", 921 cmd); 922 } 923 } 924 } 925 926 static void 927 do_nologin(struct passwd *pw) 928 { 929 FILE *f = NULL; 930 char buf[1024]; 931 932 #ifdef HAVE_LOGIN_CAP 933 if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) 934 f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN, 935 _PATH_NOLOGIN), "r"); 936 #else 937 if (pw->pw_uid) 938 f = fopen(_PATH_NOLOGIN, "r"); 939 #endif 940 if (f) { 941 /* /etc/nologin exists. Print its contents and exit. */ 942 while (fgets(buf, sizeof(buf), f)) 943 fputs(buf, stderr); 944 fclose(f); 945 exit(254); 946 } 947 } 948 949 /* Set login name, uid, gid, and groups. */ 950 static void 951 do_setusercontext(struct passwd *pw) 952 { 953 if (getuid() == 0 || geteuid() == 0) { 954 #ifdef HAVE_LOGIN_CAP 955 if (setusercontext(lc, pw, pw->pw_uid, 956 (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { 957 perror("unable to set user context"); 958 exit(1); 959 } 960 #else 961 if (setlogin(pw->pw_name) < 0) 962 error("setlogin failed: %s", strerror(errno)); 963 if (setgid(pw->pw_gid) < 0) { 964 perror("setgid"); 965 exit(1); 966 } 967 /* Initialize the group list. */ 968 if (initgroups(pw->pw_name, pw->pw_gid) < 0) { 969 perror("initgroups"); 970 exit(1); 971 } 972 endgrent(); 973 974 /* Permanently switch to the desired uid. */ 975 permanently_set_uid(pw); 976 #endif 977 } 978 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) 979 fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); 980 } 981 982 /* 983 * Performs common processing for the child, such as setting up the 984 * environment, closing extra file descriptors, setting the user and group 985 * ids, and executing the command or shell. 986 */ 987 void 988 do_child(Session *s, const char *command) 989 { 990 extern char **environ; 991 char **env; 992 char *argv[10]; 993 const char *shell, *shell0, *hostname = NULL; 994 struct passwd *pw = s->pw; 995 u_int i; 996 997 /* remove hostkey from the child's memory */ 998 destroy_sensitive_data(); 999 1000 /* login(1) is only called if we execute the login shell */ 1001 if (options.use_login && command != NULL) 1002 options.use_login = 0; 1003 1004 /* 1005 * Login(1) does this as well, and it needs uid 0 for the "-h" 1006 * switch, so we let login(1) to this for us. 1007 */ 1008 if (!options.use_login) { 1009 do_nologin(pw); 1010 do_setusercontext(pw); 1011 } 1012 1013 /* 1014 * Get the shell from the password data. An empty shell field is 1015 * legal, and means /bin/sh. 1016 */ 1017 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; 1018 #ifdef HAVE_LOGIN_CAP 1019 shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); 1020 #endif 1021 1022 env = do_setup_env(s, shell); 1023 1024 /* we have to stash the hostname before we close our socket. */ 1025 if (options.use_login) 1026 hostname = get_remote_name_or_ip(utmp_len, 1027 options.verify_reverse_mapping); 1028 /* 1029 * Close the connection descriptors; note that this is the child, and 1030 * the server will still have the socket open, and it is important 1031 * that we do not shutdown it. Note that the descriptors cannot be 1032 * closed before building the environment, as we call 1033 * get_remote_ipaddr there. 1034 */ 1035 if (packet_get_connection_in() == packet_get_connection_out()) 1036 close(packet_get_connection_in()); 1037 else { 1038 close(packet_get_connection_in()); 1039 close(packet_get_connection_out()); 1040 } 1041 /* 1042 * Close all descriptors related to channels. They will still remain 1043 * open in the parent. 1044 */ 1045 /* XXX better use close-on-exec? -markus */ 1046 channel_close_all(); 1047 1048 /* 1049 * Close any extra file descriptors. Note that there may still be 1050 * descriptors left by system functions. They will be closed later. 1051 */ 1052 endpwent(); 1053 1054 /* 1055 * Close any extra open file descriptors so that we don\'t have them 1056 * hanging around in clients. Note that we want to do this after 1057 * initgroups, because at least on Solaris 2.3 it leaves file 1058 * descriptors open. 1059 */ 1060 for (i = 3; i < 64; i++) 1061 close(i); 1062 1063 /* 1064 * Must take new environment into use so that .ssh/rc, 1065 * /etc/ssh/sshrc and xauth are run in the proper environment. 1066 */ 1067 environ = env; 1068 1069 #ifdef AFS 1070 /* Try to get AFS tokens for the local cell. */ 1071 if (k_hasafs()) { 1072 char cell[64]; 1073 1074 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) 1075 krb_afslog(cell, 0); 1076 1077 krb_afslog(0, 0); 1078 } 1079 #endif /* AFS */ 1080 1081 /* Change current directory to the user\'s home directory. */ 1082 if (chdir(pw->pw_dir) < 0) { 1083 fprintf(stderr, "Could not chdir to home directory %s: %s\n", 1084 pw->pw_dir, strerror(errno)); 1085 #ifdef HAVE_LOGIN_CAP 1086 if (login_getcapbool(lc, "requirehome", 0)) 1087 exit(1); 1088 #endif 1089 } 1090 1091 if (!options.use_login) 1092 do_rc_files(s, shell); 1093 1094 /* restore SIGPIPE for child */ 1095 signal(SIGPIPE, SIG_DFL); 1096 1097 if (options.use_login) { 1098 /* Launch login(1). */ 1099 1100 execl("/usr/bin/login", "login", "-h", hostname, 1101 "-p", "-f", "--", pw->pw_name, (char *)NULL); 1102 1103 /* Login couldn't be executed, die. */ 1104 1105 perror("login"); 1106 exit(1); 1107 } 1108 1109 /* Get the last component of the shell name. */ 1110 if ((shell0 = strrchr(shell, '/')) != NULL) 1111 shell0++; 1112 else 1113 shell0 = shell; 1114 1115 /* 1116 * If we have no command, execute the shell. In this case, the shell 1117 * name to be passed in argv[0] is preceded by '-' to indicate that 1118 * this is a login shell. 1119 */ 1120 if (!command) { 1121 char argv0[256]; 1122 1123 /* Start the shell. Set initial character to '-'. */ 1124 argv0[0] = '-'; 1125 1126 if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1) 1127 >= sizeof(argv0) - 1) { 1128 errno = EINVAL; 1129 perror(shell); 1130 exit(1); 1131 } 1132 1133 /* Execute the shell. */ 1134 argv[0] = argv0; 1135 argv[1] = NULL; 1136 execve(shell, argv, env); 1137 1138 /* Executing the shell failed. */ 1139 perror(shell); 1140 exit(1); 1141 } 1142 /* 1143 * Execute the command using the user's shell. This uses the -c 1144 * option to execute the command. 1145 */ 1146 argv[0] = (char *) shell0; 1147 argv[1] = "-c"; 1148 argv[2] = (char *) command; 1149 argv[3] = NULL; 1150 execve(shell, argv, env); 1151 perror(shell); 1152 exit(1); 1153 } 1154 1155 Session * 1156 session_new(void) 1157 { 1158 int i; 1159 static int did_init = 0; 1160 if (!did_init) { 1161 debug("session_new: init"); 1162 for (i = 0; i < MAX_SESSIONS; i++) { 1163 sessions[i].used = 0; 1164 } 1165 did_init = 1; 1166 } 1167 for (i = 0; i < MAX_SESSIONS; i++) { 1168 Session *s = &sessions[i]; 1169 if (! s->used) { 1170 memset(s, 0, sizeof(*s)); 1171 s->chanid = -1; 1172 s->ptyfd = -1; 1173 s->ttyfd = -1; 1174 s->used = 1; 1175 s->self = i; 1176 debug("session_new: session %d", i); 1177 return s; 1178 } 1179 } 1180 return NULL; 1181 } 1182 1183 static void 1184 session_dump(void) 1185 { 1186 int i; 1187 for (i = 0; i < MAX_SESSIONS; i++) { 1188 Session *s = &sessions[i]; 1189 debug("dump: used %d session %d %p channel %d pid %d", 1190 s->used, 1191 s->self, 1192 s, 1193 s->chanid, 1194 s->pid); 1195 } 1196 } 1197 1198 int 1199 session_open(Authctxt *authctxt, int chanid) 1200 { 1201 Session *s = session_new(); 1202 debug("session_open: channel %d", chanid); 1203 if (s == NULL) { 1204 error("no more sessions"); 1205 return 0; 1206 } 1207 s->authctxt = authctxt; 1208 s->pw = authctxt->pw; 1209 if (s->pw == NULL) 1210 fatal("no user for session %d", s->self); 1211 debug("session_open: session %d: link with channel %d", s->self, chanid); 1212 s->chanid = chanid; 1213 return 1; 1214 } 1215 1216 static Session * 1217 session_by_channel(int id) 1218 { 1219 int i; 1220 for (i = 0; i < MAX_SESSIONS; i++) { 1221 Session *s = &sessions[i]; 1222 if (s->used && s->chanid == id) { 1223 debug("session_by_channel: session %d channel %d", i, id); 1224 return s; 1225 } 1226 } 1227 debug("session_by_channel: unknown channel %d", id); 1228 session_dump(); 1229 return NULL; 1230 } 1231 1232 static Session * 1233 session_by_pid(pid_t pid) 1234 { 1235 int i; 1236 debug("session_by_pid: pid %d", pid); 1237 for (i = 0; i < MAX_SESSIONS; i++) { 1238 Session *s = &sessions[i]; 1239 if (s->used && s->pid == pid) 1240 return s; 1241 } 1242 error("session_by_pid: unknown pid %d", pid); 1243 session_dump(); 1244 return NULL; 1245 } 1246 1247 static int 1248 session_window_change_req(Session *s) 1249 { 1250 s->col = packet_get_int(); 1251 s->row = packet_get_int(); 1252 s->xpixel = packet_get_int(); 1253 s->ypixel = packet_get_int(); 1254 packet_check_eom(); 1255 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1256 return 1; 1257 } 1258 1259 static int 1260 session_pty_req(Session *s) 1261 { 1262 u_int len; 1263 int n_bytes; 1264 1265 if (no_pty_flag) { 1266 debug("Allocating a pty not permitted for this authentication."); 1267 return 0; 1268 } 1269 if (s->ttyfd != -1) { 1270 packet_disconnect("Protocol error: you already have a pty."); 1271 return 0; 1272 } 1273 1274 s->term = packet_get_string(&len); 1275 1276 if (compat20) { 1277 s->col = packet_get_int(); 1278 s->row = packet_get_int(); 1279 } else { 1280 s->row = packet_get_int(); 1281 s->col = packet_get_int(); 1282 } 1283 s->xpixel = packet_get_int(); 1284 s->ypixel = packet_get_int(); 1285 1286 if (strcmp(s->term, "") == 0) { 1287 xfree(s->term); 1288 s->term = NULL; 1289 } 1290 1291 /* Allocate a pty and open it. */ 1292 debug("Allocating pty."); 1293 if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { 1294 if (s->term) 1295 xfree(s->term); 1296 s->term = NULL; 1297 s->ptyfd = -1; 1298 s->ttyfd = -1; 1299 error("session_pty_req: session %d alloc failed", s->self); 1300 return 0; 1301 } 1302 debug("session_pty_req: session %d alloc %s", s->self, s->tty); 1303 1304 /* for SSH1 the tty modes length is not given */ 1305 if (!compat20) 1306 n_bytes = packet_remaining(); 1307 tty_parse_modes(s->ttyfd, &n_bytes); 1308 1309 /* 1310 * Add a cleanup function to clear the utmp entry and record logout 1311 * time in case we call fatal() (e.g., the connection gets closed). 1312 */ 1313 fatal_add_cleanup(session_pty_cleanup, (void *)s); 1314 pty_setowner(s->pw, s->tty); 1315 1316 /* Set window size from the packet. */ 1317 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1318 1319 packet_check_eom(); 1320 session_proctitle(s); 1321 return 1; 1322 } 1323 1324 static int 1325 session_subsystem_req(Session *s) 1326 { 1327 struct stat st; 1328 u_int len; 1329 int success = 0; 1330 char *cmd, *subsys = packet_get_string(&len); 1331 int i; 1332 1333 packet_check_eom(); 1334 log("subsystem request for %.100s", subsys); 1335 1336 for (i = 0; i < options.num_subsystems; i++) { 1337 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 1338 cmd = options.subsystem_command[i]; 1339 if (stat(cmd, &st) < 0) { 1340 error("subsystem: cannot stat %s: %s", cmd, 1341 strerror(errno)); 1342 break; 1343 } 1344 debug("subsystem: exec() %s", cmd); 1345 s->is_subsystem = 1; 1346 do_exec(s, cmd); 1347 success = 1; 1348 break; 1349 } 1350 } 1351 1352 if (!success) 1353 log("subsystem request for %.100s failed, subsystem not found", 1354 subsys); 1355 1356 xfree(subsys); 1357 return success; 1358 } 1359 1360 static int 1361 session_x11_req(Session *s) 1362 { 1363 int success; 1364 1365 s->single_connection = packet_get_char(); 1366 s->auth_proto = packet_get_string(NULL); 1367 s->auth_data = packet_get_string(NULL); 1368 s->screen = packet_get_int(); 1369 packet_check_eom(); 1370 1371 success = session_setup_x11fwd(s); 1372 if (!success) { 1373 xfree(s->auth_proto); 1374 xfree(s->auth_data); 1375 s->auth_proto = NULL; 1376 s->auth_data = NULL; 1377 } 1378 return success; 1379 } 1380 1381 static int 1382 session_shell_req(Session *s) 1383 { 1384 packet_check_eom(); 1385 do_exec(s, NULL); 1386 return 1; 1387 } 1388 1389 static int 1390 session_exec_req(Session *s) 1391 { 1392 u_int len; 1393 char *command = packet_get_string(&len); 1394 packet_check_eom(); 1395 do_exec(s, command); 1396 xfree(command); 1397 return 1; 1398 } 1399 1400 static int 1401 session_auth_agent_req(Session *s) 1402 { 1403 static int called = 0; 1404 packet_check_eom(); 1405 if (no_agent_forwarding_flag) { 1406 debug("session_auth_agent_req: no_agent_forwarding_flag"); 1407 return 0; 1408 } 1409 if (called) { 1410 return 0; 1411 } else { 1412 called = 1; 1413 return auth_input_request_forwarding(s->pw); 1414 } 1415 } 1416 1417 int 1418 session_input_channel_req(Channel *c, const char *rtype) 1419 { 1420 int success = 0; 1421 Session *s; 1422 1423 if ((s = session_by_channel(c->self)) == NULL) { 1424 log("session_input_channel_req: no session %d req %.100s", 1425 c->self, rtype); 1426 return 0; 1427 } 1428 debug("session_input_channel_req: session %d req %s", s->self, rtype); 1429 1430 /* 1431 * a session is in LARVAL state until a shell, a command 1432 * or a subsystem is executed 1433 */ 1434 if (c->type == SSH_CHANNEL_LARVAL) { 1435 if (strcmp(rtype, "shell") == 0) { 1436 success = session_shell_req(s); 1437 } else if (strcmp(rtype, "exec") == 0) { 1438 success = session_exec_req(s); 1439 } else if (strcmp(rtype, "pty-req") == 0) { 1440 success = session_pty_req(s); 1441 } else if (strcmp(rtype, "x11-req") == 0) { 1442 success = session_x11_req(s); 1443 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { 1444 success = session_auth_agent_req(s); 1445 } else if (strcmp(rtype, "subsystem") == 0) { 1446 success = session_subsystem_req(s); 1447 } 1448 } 1449 if (strcmp(rtype, "window-change") == 0) { 1450 success = session_window_change_req(s); 1451 } 1452 return success; 1453 } 1454 1455 void 1456 session_set_fds(Session *s, int fdin, int fdout, int fderr) 1457 { 1458 if (!compat20) 1459 fatal("session_set_fds: called for proto != 2.0"); 1460 /* 1461 * now that have a child and a pipe to the child, 1462 * we can activate our channel and register the fd's 1463 */ 1464 if (s->chanid == -1) 1465 fatal("no channel for session %d", s->self); 1466 channel_set_fds(s->chanid, 1467 fdout, fdin, fderr, 1468 fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, 1469 1, 1470 CHAN_SES_WINDOW_DEFAULT); 1471 } 1472 1473 /* 1474 * Function to perform pty cleanup. Also called if we get aborted abnormally 1475 * (e.g., due to a dropped connection). 1476 */ 1477 static void 1478 session_pty_cleanup(void *session) 1479 { 1480 Session *s = session; 1481 1482 if (s == NULL) { 1483 error("session_pty_cleanup: no session"); 1484 return; 1485 } 1486 if (s->ttyfd == -1) 1487 return; 1488 1489 debug("session_pty_cleanup: session %d release %s", s->self, s->tty); 1490 1491 /* Record that the user has logged out. */ 1492 if (s->pid != 0) 1493 record_logout(s->pid, s->tty); 1494 1495 /* Release the pseudo-tty. */ 1496 pty_release(s->tty); 1497 1498 /* 1499 * Close the server side of the socket pairs. We must do this after 1500 * the pty cleanup, so that another process doesn't get this pty 1501 * while we're still cleaning up. 1502 */ 1503 if (close(s->ptymaster) < 0) 1504 error("close(s->ptymaster): %s", strerror(errno)); 1505 1506 /* unlink pty from session */ 1507 s->ttyfd = -1; 1508 } 1509 1510 static void 1511 session_exit_message(Session *s, int status) 1512 { 1513 Channel *c; 1514 1515 if ((c = channel_lookup(s->chanid)) == NULL) 1516 fatal("session_exit_message: session %d: no channel %d", 1517 s->self, s->chanid); 1518 debug("session_exit_message: session %d channel %d pid %d", 1519 s->self, s->chanid, s->pid); 1520 1521 if (WIFEXITED(status)) { 1522 channel_request_start(s->chanid, "exit-status", 0); 1523 packet_put_int(WEXITSTATUS(status)); 1524 packet_send(); 1525 } else if (WIFSIGNALED(status)) { 1526 channel_request_start(s->chanid, "exit-signal", 0); 1527 packet_put_int(WTERMSIG(status)); 1528 packet_put_char(WCOREDUMP(status)); 1529 packet_put_cstring(""); 1530 packet_put_cstring(""); 1531 packet_send(); 1532 } else { 1533 /* Some weird exit cause. Just exit. */ 1534 packet_disconnect("wait returned status %04x.", status); 1535 } 1536 1537 /* disconnect channel */ 1538 debug("session_exit_message: release channel %d", s->chanid); 1539 channel_cancel_cleanup(s->chanid); 1540 /* 1541 * emulate a write failure with 'chan_write_failed', nobody will be 1542 * interested in data we write. 1543 * Note that we must not call 'chan_read_failed', since there could 1544 * be some more data waiting in the pipe. 1545 */ 1546 if (c->ostate != CHAN_OUTPUT_CLOSED) 1547 chan_write_failed(c); 1548 s->chanid = -1; 1549 } 1550 1551 static void 1552 session_close(Session *s) 1553 { 1554 debug("session_close: session %d pid %d", s->self, s->pid); 1555 if (s->ttyfd != -1) { 1556 fatal_remove_cleanup(session_pty_cleanup, (void *)s); 1557 session_pty_cleanup(s); 1558 } 1559 if (s->term) 1560 xfree(s->term); 1561 if (s->display) 1562 xfree(s->display); 1563 if (s->auth_display) 1564 xfree(s->auth_display); 1565 if (s->auth_data) 1566 xfree(s->auth_data); 1567 if (s->auth_proto) 1568 xfree(s->auth_proto); 1569 s->used = 0; 1570 session_proctitle(s); 1571 } 1572 1573 void 1574 session_close_by_pid(pid_t pid, int status) 1575 { 1576 Session *s = session_by_pid(pid); 1577 if (s == NULL) { 1578 debug("session_close_by_pid: no session for pid %d", pid); 1579 return; 1580 } 1581 if (s->chanid != -1) 1582 session_exit_message(s, status); 1583 session_close(s); 1584 } 1585 1586 /* 1587 * this is called when a channel dies before 1588 * the session 'child' itself dies 1589 */ 1590 void 1591 session_close_by_channel(int id, void *arg) 1592 { 1593 Session *s = session_by_channel(id); 1594 if (s == NULL) { 1595 debug("session_close_by_channel: no session for id %d", id); 1596 return; 1597 } 1598 debug("session_close_by_channel: channel %d child %d", id, s->pid); 1599 if (s->pid != 0) { 1600 debug("session_close_by_channel: channel %d: has child", id); 1601 /* 1602 * delay detach of session, but release pty, since 1603 * the fd's to the child are already closed 1604 */ 1605 if (s->ttyfd != -1) { 1606 fatal_remove_cleanup(session_pty_cleanup, (void *)s); 1607 session_pty_cleanup(s); 1608 } 1609 return; 1610 } 1611 /* detach by removing callback */ 1612 channel_cancel_cleanup(s->chanid); 1613 s->chanid = -1; 1614 session_close(s); 1615 } 1616 1617 void 1618 session_destroy_all(void) 1619 { 1620 int i; 1621 for (i = 0; i < MAX_SESSIONS; i++) { 1622 Session *s = &sessions[i]; 1623 if (s->used) 1624 session_close(s); 1625 } 1626 } 1627 1628 static char * 1629 session_tty_list(void) 1630 { 1631 static char buf[1024]; 1632 int i; 1633 buf[0] = '\0'; 1634 for (i = 0; i < MAX_SESSIONS; i++) { 1635 Session *s = &sessions[i]; 1636 if (s->used && s->ttyfd != -1) { 1637 if (buf[0] != '\0') 1638 strlcat(buf, ",", sizeof buf); 1639 strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); 1640 } 1641 } 1642 if (buf[0] == '\0') 1643 strlcpy(buf, "notty", sizeof buf); 1644 return buf; 1645 } 1646 1647 void 1648 session_proctitle(Session *s) 1649 { 1650 if (s->pw == NULL) 1651 error("no user for session %d", s->self); 1652 else 1653 setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); 1654 } 1655 1656 int 1657 session_setup_x11fwd(Session *s) 1658 { 1659 struct stat st; 1660 char display[512], auth_display[512]; 1661 char hostname[MAXHOSTNAMELEN]; 1662 1663 if (no_x11_forwarding_flag) { 1664 packet_send_debug("X11 forwarding disabled in user configuration file."); 1665 return 0; 1666 } 1667 if (!options.x11_forwarding) { 1668 debug("X11 forwarding disabled in server configuration file."); 1669 return 0; 1670 } 1671 if (!options.xauth_location || 1672 (stat(options.xauth_location, &st) == -1)) { 1673 packet_send_debug("No xauth program; cannot forward with spoofing."); 1674 return 0; 1675 } 1676 if (options.use_login) { 1677 packet_send_debug("X11 forwarding disabled; " 1678 "not compatible with UseLogin=yes."); 1679 return 0; 1680 } 1681 if (s->display != NULL) { 1682 debug("X11 display already set."); 1683 return 0; 1684 } 1685 s->display_number = x11_create_display_inet(options.x11_display_offset, 1686 options.x11_use_localhost, s->single_connection); 1687 if (s->display_number == -1) { 1688 debug("x11_create_display_inet failed."); 1689 return 0; 1690 } 1691 1692 /* Set up a suitable value for the DISPLAY variable. */ 1693 if (gethostname(hostname, sizeof(hostname)) < 0) 1694 fatal("gethostname: %.100s", strerror(errno)); 1695 /* 1696 * auth_display must be used as the displayname when the 1697 * authorization entry is added with xauth(1). This will be 1698 * different than the DISPLAY string for localhost displays. 1699 */ 1700 if (options.x11_use_localhost) { 1701 snprintf(display, sizeof display, "localhost:%d.%d", 1702 s->display_number, s->screen); 1703 snprintf(auth_display, sizeof auth_display, "unix:%d.%d", 1704 s->display_number, s->screen); 1705 s->display = xstrdup(display); 1706 s->auth_display = xstrdup(auth_display); 1707 } else { 1708 snprintf(display, sizeof display, "%.400s:%d.%d", hostname, 1709 s->display_number, s->screen); 1710 s->display = xstrdup(display); 1711 s->auth_display = xstrdup(display); 1712 } 1713 1714 return 1; 1715 } 1716 1717 static void 1718 do_authenticated2(Authctxt *authctxt) 1719 { 1720 server_loop2(authctxt); 1721 } 1722