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