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