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