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.99 2001/07/09 07:04:53 deraadt 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 #ifdef AFS 855 /* Try to get AFS tokens for the local cell. */ 856 if (k_hasafs()) { 857 char cell[64]; 858 859 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) 860 krb_afslog(cell, 0); 861 862 krb_afslog(0, 0); 863 } 864 #endif /* AFS */ 865 866 /* Initialize the environment. */ 867 envsize = 100; 868 env = xmalloc(envsize * sizeof(char *)); 869 env[0] = NULL; 870 871 if (!options.use_login) { 872 /* Set basic environment. */ 873 child_set_env(&env, &envsize, "USER", pw->pw_name); 874 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); 875 child_set_env(&env, &envsize, "HOME", pw->pw_dir); 876 #ifdef HAVE_LOGIN_CAP 877 (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH); 878 child_set_env(&env, &envsize, "PATH", getenv("PATH")); 879 #else 880 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); 881 #endif 882 883 snprintf(buf, sizeof buf, "%.200s/%.50s", 884 _PATH_MAILDIR, pw->pw_name); 885 child_set_env(&env, &envsize, "MAIL", buf); 886 887 /* Normal systems set SHELL by default. */ 888 child_set_env(&env, &envsize, "SHELL", shell); 889 } 890 if (getenv("TZ")) 891 child_set_env(&env, &envsize, "TZ", getenv("TZ")); 892 893 /* Set custom environment options from RSA authentication. */ 894 while (custom_environment) { 895 struct envstring *ce = custom_environment; 896 char *s = ce->s; 897 int i; 898 for (i = 0; s[i] != '=' && s[i]; i++); 899 if (s[i] == '=') { 900 s[i] = 0; 901 child_set_env(&env, &envsize, s, s + i + 1); 902 } 903 custom_environment = ce->next; 904 xfree(ce->s); 905 xfree(ce); 906 } 907 908 snprintf(buf, sizeof buf, "%.50s %d %d", 909 get_remote_ipaddr(), get_remote_port(), get_local_port()); 910 child_set_env(&env, &envsize, "SSH_CLIENT", buf); 911 912 if (s->ttyfd != -1) 913 child_set_env(&env, &envsize, "SSH_TTY", s->tty); 914 if (s->term) 915 child_set_env(&env, &envsize, "TERM", s->term); 916 if (s->display) 917 child_set_env(&env, &envsize, "DISPLAY", s->display); 918 if (original_command) 919 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", 920 original_command); 921 #ifdef KRB4 922 if (s->authctxt->krb4_ticket_file) 923 child_set_env(&env, &envsize, "KRBTKFILE", 924 s->authctxt->krb4_ticket_file); 925 #endif 926 #ifdef KRB5 927 if (s->authctxt->krb5_ticket_file) 928 child_set_env(&env, &envsize, "KRB5CCNAME", 929 s->authctxt->krb5_ticket_file); 930 #endif 931 if (auth_get_socket_name() != NULL) 932 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, 933 auth_get_socket_name()); 934 935 /* read $HOME/.ssh/environment. */ 936 if (!options.use_login) { 937 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", 938 pw->pw_dir); 939 read_environment_file(&env, &envsize, buf); 940 } 941 if (debug_flag) { 942 /* dump the environment */ 943 fprintf(stderr, "Environment:\n"); 944 for (i = 0; env[i]; i++) 945 fprintf(stderr, " %.200s\n", env[i]); 946 } 947 /* we have to stash the hostname before we close our socket. */ 948 if (options.use_login) 949 hostname = get_remote_name_or_ip(utmp_len, 950 options.reverse_mapping_check); 951 /* 952 * Close the connection descriptors; note that this is the child, and 953 * the server will still have the socket open, and it is important 954 * that we do not shutdown it. Note that the descriptors cannot be 955 * closed before building the environment, as we call 956 * get_remote_ipaddr there. 957 */ 958 if (packet_get_connection_in() == packet_get_connection_out()) 959 close(packet_get_connection_in()); 960 else { 961 close(packet_get_connection_in()); 962 close(packet_get_connection_out()); 963 } 964 /* 965 * Close all descriptors related to channels. They will still remain 966 * open in the parent. 967 */ 968 /* XXX better use close-on-exec? -markus */ 969 channel_close_all(); 970 971 /* 972 * Close any extra file descriptors. Note that there may still be 973 * descriptors left by system functions. They will be closed later. 974 */ 975 endpwent(); 976 977 /* 978 * Close any extra open file descriptors so that we don\'t have them 979 * hanging around in clients. Note that we want to do this after 980 * initgroups, because at least on Solaris 2.3 it leaves file 981 * descriptors open. 982 */ 983 for (i = 3; i < 64; i++) 984 close(i); 985 986 /* Change current directory to the user\'s home directory. */ 987 if (chdir(pw->pw_dir) < 0) { 988 fprintf(stderr, "Could not chdir to home directory %s: %s\n", 989 pw->pw_dir, strerror(errno)); 990 #ifdef HAVE_LOGIN_CAP 991 if (login_getcapbool(lc, "requirehome", 0)) 992 exit(1); 993 #endif 994 } 995 996 /* 997 * Must take new environment into use so that .ssh/rc, /etc/sshrc and 998 * xauth are run in the proper environment. 999 */ 1000 environ = env; 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 /* 1091 * Check for mail if we have a tty and it was enabled 1092 * in server options. 1093 */ 1094 if (s->ttyfd != -1 && options.check_mail) { 1095 char *mailbox; 1096 struct stat mailstat; 1097 1098 mailbox = getenv("MAIL"); 1099 if (mailbox != NULL) { 1100 if (stat(mailbox, &mailstat) != 0 || 1101 mailstat.st_size == 0) 1102 printf("No mail.\n"); 1103 else if (mailstat.st_mtime < mailstat.st_atime) 1104 printf("You have mail.\n"); 1105 else 1106 printf("You have new mail.\n"); 1107 } 1108 } 1109 /* Start the shell. Set initial character to '-'. */ 1110 buf[0] = '-'; 1111 strncpy(buf + 1, cp, sizeof(buf) - 1); 1112 buf[sizeof(buf) - 1] = 0; 1113 1114 /* Execute the shell. */ 1115 argv[0] = buf; 1116 argv[1] = NULL; 1117 execve(shell, argv, env); 1118 1119 /* Executing the shell failed. */ 1120 perror(shell); 1121 exit(1); 1122 1123 } else { 1124 /* Launch login(1). */ 1125 1126 execl("/usr/bin/login", "login", "-h", hostname, 1127 "-p", "-f", "--", pw->pw_name, (char *)NULL); 1128 1129 /* Login couldn't be executed, die. */ 1130 1131 perror("login"); 1132 exit(1); 1133 } 1134 } 1135 /* 1136 * Execute the command using the user's shell. This uses the -c 1137 * option to execute the command. 1138 */ 1139 argv[0] = (char *) cp; 1140 argv[1] = "-c"; 1141 argv[2] = (char *) command; 1142 argv[3] = NULL; 1143 execve(shell, argv, env); 1144 perror(shell); 1145 exit(1); 1146 } 1147 1148 Session * 1149 session_new(void) 1150 { 1151 int i; 1152 static int did_init = 0; 1153 if (!did_init) { 1154 debug("session_new: init"); 1155 for(i = 0; i < MAX_SESSIONS; i++) { 1156 sessions[i].used = 0; 1157 } 1158 did_init = 1; 1159 } 1160 for(i = 0; i < MAX_SESSIONS; i++) { 1161 Session *s = &sessions[i]; 1162 if (! s->used) { 1163 memset(s, 0, sizeof(*s)); 1164 s->chanid = -1; 1165 s->ptyfd = -1; 1166 s->ttyfd = -1; 1167 s->used = 1; 1168 s->self = i; 1169 debug("session_new: session %d", i); 1170 return s; 1171 } 1172 } 1173 return NULL; 1174 } 1175 1176 static void 1177 session_dump(void) 1178 { 1179 int i; 1180 for(i = 0; i < MAX_SESSIONS; i++) { 1181 Session *s = &sessions[i]; 1182 debug("dump: used %d session %d %p channel %d pid %d", 1183 s->used, 1184 s->self, 1185 s, 1186 s->chanid, 1187 s->pid); 1188 } 1189 } 1190 1191 int 1192 session_open(Authctxt *authctxt, int chanid) 1193 { 1194 Session *s = session_new(); 1195 debug("session_open: channel %d", chanid); 1196 if (s == NULL) { 1197 error("no more sessions"); 1198 return 0; 1199 } 1200 s->authctxt = authctxt; 1201 s->pw = authctxt->pw; 1202 if (s->pw == NULL) 1203 fatal("no user for session %d", s->self); 1204 debug("session_open: session %d: link with channel %d", s->self, chanid); 1205 s->chanid = chanid; 1206 return 1; 1207 } 1208 1209 static Session * 1210 session_by_channel(int id) 1211 { 1212 int i; 1213 for(i = 0; i < MAX_SESSIONS; i++) { 1214 Session *s = &sessions[i]; 1215 if (s->used && s->chanid == id) { 1216 debug("session_by_channel: session %d channel %d", i, id); 1217 return s; 1218 } 1219 } 1220 debug("session_by_channel: unknown channel %d", id); 1221 session_dump(); 1222 return NULL; 1223 } 1224 1225 static Session * 1226 session_by_pid(pid_t pid) 1227 { 1228 int i; 1229 debug("session_by_pid: pid %d", pid); 1230 for(i = 0; i < MAX_SESSIONS; i++) { 1231 Session *s = &sessions[i]; 1232 if (s->used && s->pid == pid) 1233 return s; 1234 } 1235 error("session_by_pid: unknown pid %d", pid); 1236 session_dump(); 1237 return NULL; 1238 } 1239 1240 static int 1241 session_window_change_req(Session *s) 1242 { 1243 s->col = packet_get_int(); 1244 s->row = packet_get_int(); 1245 s->xpixel = packet_get_int(); 1246 s->ypixel = packet_get_int(); 1247 packet_done(); 1248 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1249 return 1; 1250 } 1251 1252 static int 1253 session_pty_req(Session *s) 1254 { 1255 u_int len; 1256 int n_bytes; 1257 1258 if (no_pty_flag) { 1259 debug("Allocating a pty not permitted for this authentication."); 1260 return 0; 1261 } 1262 if (s->ttyfd != -1) { 1263 packet_disconnect("Protocol error: you already have a pty."); 1264 return 0; 1265 } 1266 1267 s->term = packet_get_string(&len); 1268 1269 if (compat20) { 1270 s->col = packet_get_int(); 1271 s->row = packet_get_int(); 1272 } else { 1273 s->row = packet_get_int(); 1274 s->col = packet_get_int(); 1275 } 1276 s->xpixel = packet_get_int(); 1277 s->ypixel = packet_get_int(); 1278 1279 if (strcmp(s->term, "") == 0) { 1280 xfree(s->term); 1281 s->term = NULL; 1282 } 1283 1284 /* Allocate a pty and open it. */ 1285 debug("Allocating pty."); 1286 if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { 1287 if (s->term) 1288 xfree(s->term); 1289 s->term = NULL; 1290 s->ptyfd = -1; 1291 s->ttyfd = -1; 1292 error("session_pty_req: session %d alloc failed", s->self); 1293 return 0; 1294 } 1295 debug("session_pty_req: session %d alloc %s", s->self, s->tty); 1296 1297 /* for SSH1 the tty modes length is not given */ 1298 if (!compat20) 1299 n_bytes = packet_remaining(); 1300 tty_parse_modes(s->ttyfd, &n_bytes); 1301 1302 /* 1303 * Add a cleanup function to clear the utmp entry and record logout 1304 * time in case we call fatal() (e.g., the connection gets closed). 1305 */ 1306 fatal_add_cleanup(session_pty_cleanup, (void *)s); 1307 pty_setowner(s->pw, s->tty); 1308 1309 /* Set window size from the packet. */ 1310 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1311 1312 packet_done(); 1313 session_proctitle(s); 1314 return 1; 1315 } 1316 1317 static int 1318 session_subsystem_req(Session *s) 1319 { 1320 u_int len; 1321 int success = 0; 1322 char *subsys = packet_get_string(&len); 1323 int i; 1324 1325 packet_done(); 1326 log("subsystem request for %s", subsys); 1327 1328 for (i = 0; i < options.num_subsystems; i++) { 1329 if(strcmp(subsys, options.subsystem_name[i]) == 0) { 1330 debug("subsystem: exec() %s", options.subsystem_command[i]); 1331 s->is_subsystem = 1; 1332 do_exec_no_pty(s, options.subsystem_command[i]); 1333 success = 1; 1334 } 1335 } 1336 1337 if (!success) 1338 log("subsystem request for %s failed, subsystem not found", subsys); 1339 1340 xfree(subsys); 1341 return success; 1342 } 1343 1344 static int 1345 session_x11_req(Session *s) 1346 { 1347 int success; 1348 1349 s->single_connection = packet_get_char(); 1350 s->auth_proto = packet_get_string(NULL); 1351 s->auth_data = packet_get_string(NULL); 1352 s->screen = packet_get_int(); 1353 packet_done(); 1354 1355 success = session_setup_x11fwd(s); 1356 if (!success) { 1357 xfree(s->auth_proto); 1358 xfree(s->auth_data); 1359 s->auth_proto = NULL; 1360 s->auth_data = NULL; 1361 } 1362 return success; 1363 } 1364 1365 static int 1366 session_shell_req(Session *s) 1367 { 1368 packet_done(); 1369 do_exec(s, NULL); 1370 return 1; 1371 } 1372 1373 static int 1374 session_exec_req(Session *s) 1375 { 1376 u_int len; 1377 char *command = packet_get_string(&len); 1378 packet_done(); 1379 do_exec(s, command); 1380 xfree(command); 1381 return 1; 1382 } 1383 1384 static int 1385 session_auth_agent_req(Session *s) 1386 { 1387 static int called = 0; 1388 packet_done(); 1389 if (no_agent_forwarding_flag) { 1390 debug("session_auth_agent_req: no_agent_forwarding_flag"); 1391 return 0; 1392 } 1393 if (called) { 1394 return 0; 1395 } else { 1396 called = 1; 1397 return auth_input_request_forwarding(s->pw); 1398 } 1399 } 1400 1401 void 1402 session_input_channel_req(int id, void *arg) 1403 { 1404 u_int len; 1405 int reply; 1406 int success = 0; 1407 char *rtype; 1408 Session *s; 1409 Channel *c; 1410 1411 rtype = packet_get_string(&len); 1412 reply = packet_get_char(); 1413 1414 s = session_by_channel(id); 1415 if (s == NULL) 1416 fatal("session_input_channel_req: channel %d: no session", id); 1417 c = channel_lookup(id); 1418 if (c == NULL) 1419 fatal("session_input_channel_req: channel %d: bad channel", id); 1420 1421 debug("session_input_channel_req: session %d channel %d request %s reply %d", 1422 s->self, id, rtype, reply); 1423 1424 /* 1425 * a session is in LARVAL state until a shell, a command 1426 * or a subsystem is executed 1427 */ 1428 if (c->type == SSH_CHANNEL_LARVAL) { 1429 if (strcmp(rtype, "shell") == 0) { 1430 success = session_shell_req(s); 1431 } else if (strcmp(rtype, "exec") == 0) { 1432 success = session_exec_req(s); 1433 } else if (strcmp(rtype, "pty-req") == 0) { 1434 success = session_pty_req(s); 1435 } else if (strcmp(rtype, "x11-req") == 0) { 1436 success = session_x11_req(s); 1437 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { 1438 success = session_auth_agent_req(s); 1439 } else if (strcmp(rtype, "subsystem") == 0) { 1440 success = session_subsystem_req(s); 1441 } 1442 } 1443 if (strcmp(rtype, "window-change") == 0) { 1444 success = session_window_change_req(s); 1445 } 1446 1447 if (reply) { 1448 packet_start(success ? 1449 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 1450 packet_put_int(c->remote_id); 1451 packet_send(); 1452 } 1453 xfree(rtype); 1454 } 1455 1456 void 1457 session_set_fds(Session *s, int fdin, int fdout, int fderr) 1458 { 1459 if (!compat20) 1460 fatal("session_set_fds: called for proto != 2.0"); 1461 /* 1462 * now that have a child and a pipe to the child, 1463 * we can activate our channel and register the fd's 1464 */ 1465 if (s->chanid == -1) 1466 fatal("no channel for session %d", s->self); 1467 channel_set_fds(s->chanid, 1468 fdout, fdin, fderr, 1469 fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, 1470 1); 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 1507 static void 1508 session_exit_message(Session *s, int status) 1509 { 1510 Channel *c; 1511 if (s == NULL) 1512 fatal("session_close: no session"); 1513 c = channel_lookup(s->chanid); 1514 if (c == NULL) 1515 fatal("session_exit_message: session %d: no channel %d", 1516 s->self, s->chanid); 1517 debug("session_exit_message: session %d channel %d pid %d", 1518 s->self, s->chanid, s->pid); 1519 1520 if (WIFEXITED(status)) { 1521 channel_request_start(s->chanid, 1522 "exit-status", 0); 1523 packet_put_int(WEXITSTATUS(status)); 1524 packet_send(); 1525 } else if (WIFSIGNALED(status)) { 1526 channel_request_start(s->chanid, 1527 "exit-signal", 0); 1528 packet_put_int(WTERMSIG(status)); 1529 packet_put_char(WCOREDUMP(status)); 1530 packet_put_cstring(""); 1531 packet_put_cstring(""); 1532 packet_send(); 1533 } else { 1534 /* Some weird exit cause. Just exit. */ 1535 packet_disconnect("wait returned status %04x.", status); 1536 } 1537 1538 /* disconnect channel */ 1539 debug("session_exit_message: release channel %d", s->chanid); 1540 channel_cancel_cleanup(s->chanid); 1541 /* 1542 * emulate a write failure with 'chan_write_failed', nobody will be 1543 * interested in data we write. 1544 * Note that we must not call 'chan_read_failed', since there could 1545 * be some more data waiting in the pipe. 1546 */ 1547 if (c->ostate != CHAN_OUTPUT_CLOSED) 1548 chan_write_failed(c); 1549 s->chanid = -1; 1550 } 1551 1552 static void 1553 session_close(Session *s) 1554 { 1555 debug("session_close: session %d pid %d", s->self, s->pid); 1556 if (s->ttyfd != -1) { 1557 fatal_remove_cleanup(session_pty_cleanup, (void *)s); 1558 session_pty_cleanup(s); 1559 } 1560 if (s->term) 1561 xfree(s->term); 1562 if (s->display) 1563 xfree(s->display); 1564 if (s->auth_data) 1565 xfree(s->auth_data); 1566 if (s->auth_proto) 1567 xfree(s->auth_proto); 1568 s->used = 0; 1569 session_proctitle(s); 1570 } 1571 1572 void 1573 session_close_by_pid(pid_t pid, int status) 1574 { 1575 Session *s = session_by_pid(pid); 1576 if (s == NULL) { 1577 debug("session_close_by_pid: no session for pid %d", pid); 1578 return; 1579 } 1580 if (s->chanid != -1) 1581 session_exit_message(s, status); 1582 session_close(s); 1583 } 1584 1585 int 1586 session_have_children(void) 1587 { 1588 int i; 1589 1590 for(i = 0; i < MAX_SESSIONS; i++) { 1591 Session *s = &sessions[i]; 1592 if (s->used && s->pid != -1) { 1593 debug("session_have_children: id %d pid %d", i, s->pid); 1594 return 1; 1595 } 1596 } 1597 debug("session_have_children: no more children"); 1598 return 0; 1599 } 1600 1601 /* 1602 * this is called when a channel dies before 1603 * the session 'child' itself dies 1604 */ 1605 void 1606 session_close_by_channel(int id, void *arg) 1607 { 1608 Session *s = session_by_channel(id); 1609 if (s == NULL) { 1610 debug("session_close_by_channel: no session for channel %d", id); 1611 return; 1612 } 1613 /* disconnect channel */ 1614 channel_cancel_cleanup(s->chanid); 1615 s->chanid = -1; 1616 1617 debug("session_close_by_channel: channel %d kill %d", id, s->pid); 1618 if (s->pid == 0) { 1619 /* close session immediately */ 1620 session_close(s); 1621 } else { 1622 /* notify child, delay session cleanup */ 1623 if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0) 1624 error("session_close_by_channel: kill %d: %s", 1625 s->pid, strerror(errno)); 1626 } 1627 } 1628 1629 static char * 1630 session_tty_list(void) 1631 { 1632 static char buf[1024]; 1633 int i; 1634 buf[0] = '\0'; 1635 for(i = 0; i < MAX_SESSIONS; i++) { 1636 Session *s = &sessions[i]; 1637 if (s->used && s->ttyfd != -1) { 1638 if (buf[0] != '\0') 1639 strlcat(buf, ",", sizeof buf); 1640 strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); 1641 } 1642 } 1643 if (buf[0] == '\0') 1644 strlcpy(buf, "notty", sizeof buf); 1645 return buf; 1646 } 1647 1648 void 1649 session_proctitle(Session *s) 1650 { 1651 if (s->pw == NULL) 1652 error("no user for session %d", s->self); 1653 else 1654 setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); 1655 } 1656 1657 int 1658 session_setup_x11fwd(Session *s) 1659 { 1660 struct stat st; 1661 1662 if (no_x11_forwarding_flag) { 1663 packet_send_debug("X11 forwarding disabled in user configuration file."); 1664 return 0; 1665 } 1666 if (!options.x11_forwarding) { 1667 debug("X11 forwarding disabled in server configuration file."); 1668 return 0; 1669 } 1670 if (!options.xauth_location || 1671 (stat(options.xauth_location, &st) == -1)) { 1672 packet_send_debug("No xauth program; cannot forward with spoofing."); 1673 return 0; 1674 } 1675 if (options.use_login) { 1676 packet_send_debug("X11 forwarding disabled; " 1677 "not compatible with UseLogin=yes."); 1678 return 0; 1679 } 1680 if (s->display != NULL) { 1681 debug("X11 display already set."); 1682 return 0; 1683 } 1684 s->display = x11_create_display_inet(s->screen, options.x11_display_offset); 1685 if (s->display == NULL) { 1686 debug("x11_create_display_inet failed."); 1687 return 0; 1688 } 1689 return 1; 1690 } 1691 1692 static void 1693 do_authenticated2(Authctxt *authctxt) 1694 { 1695 server_loop2(authctxt); 1696 } 1697