1 /* $NetBSD: ssh.c,v 1.12 2013/04/29 17:59:50 mlelstv Exp $ */ 2 /* $OpenBSD: ssh.c,v 1.372 2013/02/22 04:45:09 dtucker Exp $ */ 3 /* 4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 6 * All rights reserved 7 * Ssh client program. This program can be used to log into a remote machine. 8 * The software supports strong authentication, encryption, and forwarding 9 * of X11, TCP/IP, and authentication connections. 10 * 11 * As far as I am concerned, the code I have written for this software 12 * can be used freely for any purpose. Any derived versions of this 13 * software must be clearly marked as such, and if the derived work is 14 * incompatible with the protocol description in the RFC file, it must be 15 * called by a name other than "ssh" or "Secure Shell". 16 * 17 * Copyright (c) 1999 Niels Provos. All rights reserved. 18 * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved. 19 * 20 * Modified to work with SSL by Niels Provos <provos@citi.umich.edu> 21 * in Canada (German citizen). 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the above copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 33 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 34 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 36 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 37 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 41 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 */ 43 44 #include "includes.h" 45 __RCSID("$NetBSD: ssh.c,v 1.12 2013/04/29 17:59:50 mlelstv Exp $"); 46 #include <sys/types.h> 47 #include <sys/param.h> 48 #include <sys/ioctl.h> 49 #include <sys/param.h> 50 #include <sys/queue.h> 51 #include <sys/resource.h> 52 #include <sys/socket.h> 53 #include <sys/stat.h> 54 #include <sys/time.h> 55 #include <sys/wait.h> 56 57 #include <ctype.h> 58 #include <errno.h> 59 #include <fcntl.h> 60 #include <netdb.h> 61 #include <paths.h> 62 #include <pwd.h> 63 #include <signal.h> 64 #include <stddef.h> 65 #include <stdio.h> 66 #include <stdlib.h> 67 #include <string.h> 68 #include <unistd.h> 69 70 #include <openssl/evp.h> 71 #include <openssl/err.h> 72 73 #include "xmalloc.h" 74 #include "ssh.h" 75 #include "ssh1.h" 76 #include "ssh2.h" 77 #include "canohost.h" 78 #include "compat.h" 79 #include "cipher.h" 80 #include "packet.h" 81 #include "buffer.h" 82 #include "channels.h" 83 #include "key.h" 84 #include "authfd.h" 85 #include "authfile.h" 86 #include "pathnames.h" 87 #include "dispatch.h" 88 #include "clientloop.h" 89 #include "log.h" 90 #include "readconf.h" 91 #include "sshconnect.h" 92 #include "misc.h" 93 #include "kex.h" 94 #include "mac.h" 95 #include "sshpty.h" 96 #include "match.h" 97 #include "msg.h" 98 #include "uidswap.h" 99 #include "roaming.h" 100 #include "version.h" 101 102 #ifdef ENABLE_PKCS11 103 #include "ssh-pkcs11.h" 104 #endif 105 106 extern char *__progname; 107 108 /* Flag indicating whether debug mode is on. May be set on the command line. */ 109 int debug_flag = 0; 110 111 /* Flag indicating whether a tty should be requested */ 112 int tty_flag = 0; 113 114 /* don't exec a shell */ 115 int no_shell_flag = 0; 116 117 /* 118 * Flag indicating that nothing should be read from stdin. This can be set 119 * on the command line. 120 */ 121 int stdin_null_flag = 0; 122 123 /* 124 * Flag indicating that the current process should be backgrounded and 125 * a new slave launched in the foreground for ControlPersist. 126 */ 127 int need_controlpersist_detach = 0; 128 129 /* Copies of flags for ControlPersist foreground slave */ 130 int ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty; 131 132 /* 133 * Flag indicating that ssh should fork after authentication. This is useful 134 * so that the passphrase can be entered manually, and then ssh goes to the 135 * background. 136 */ 137 int fork_after_authentication_flag = 0; 138 139 /* forward stdio to remote host and port */ 140 char *stdio_forward_host = NULL; 141 int stdio_forward_port = 0; 142 143 /* 144 * General data structure for command line options and options configurable 145 * in configuration files. See readconf.h. 146 */ 147 Options options; 148 149 /* optional user configfile */ 150 char *config = NULL; 151 152 /* 153 * Name of the host we are connecting to. This is the name given on the 154 * command line, or the HostName specified for the user-supplied name in a 155 * configuration file. 156 */ 157 char *host; 158 159 /* socket address the host resolves to */ 160 struct sockaddr_storage hostaddr; 161 162 /* Private host keys. */ 163 Sensitive sensitive_data; 164 165 /* Original real UID. */ 166 uid_t original_real_uid; 167 uid_t original_effective_uid; 168 169 /* command to be executed */ 170 Buffer command; 171 172 /* Should we execute a command or invoke a subsystem? */ 173 int subsystem_flag = 0; 174 175 /* # of replies received for global requests */ 176 static int remote_forward_confirms_received = 0; 177 178 /* mux.c */ 179 extern int muxserver_sock; 180 extern u_int muxclient_command; 181 182 183 /* Prints a help message to the user. This function never returns. */ 184 185 __dead static void 186 usage(void) 187 { 188 fprintf(stderr, 189 "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" 190 " [-D [bind_address:]port] [-e escape_char] [-F configfile]\n" 191 " [-I pkcs11] [-i identity_file]\n" 192 " [-L [bind_address:]port:host:hostport]\n" 193 " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" 194 " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" 195 " [-W host:port] [-w local_tun[:remote_tun]]\n" 196 " [user@]hostname [command]\n" 197 ); 198 exit(255); 199 } 200 201 static int ssh_session(void); 202 static int ssh_session2(void); 203 static void load_public_identity_files(void); 204 static void main_sigchld_handler(int); 205 206 /* from muxclient.c */ 207 void muxclient(const char *); 208 void muxserver_listen(void); 209 210 /* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */ 211 static void 212 tilde_expand_paths(char **paths, u_int num_paths) 213 { 214 u_int i; 215 char *cp; 216 217 for (i = 0; i < num_paths; i++) { 218 cp = tilde_expand_filename(paths[i], original_real_uid); 219 xfree(paths[i]); 220 paths[i] = cp; 221 } 222 } 223 224 /* 225 * Main program for the ssh client. 226 */ 227 int 228 main(int ac, char **av) 229 { 230 int i, r, opt, exit_status, use_syslog; 231 char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg; 232 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 233 struct stat st; 234 struct passwd *pw; 235 int dummy, timeout_ms; 236 extern int optind, optreset; 237 extern char *optarg; 238 struct servent *sp; 239 Forward fwd; 240 241 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 242 sanitise_stdfd(); 243 244 /* 245 * Discard other fds that are hanging around. These can cause problem 246 * with backgrounded ssh processes started by ControlPersist. 247 */ 248 closefrom(STDERR_FILENO + 1); 249 250 /* 251 * Save the original real uid. It will be needed later (uid-swapping 252 * may clobber the real uid). 253 */ 254 original_real_uid = getuid(); 255 original_effective_uid = geteuid(); 256 257 /* 258 * Use uid-swapping to give up root privileges for the duration of 259 * option processing. We will re-instantiate the rights when we are 260 * ready to create the privileged port, and will permanently drop 261 * them when the port has been created (actually, when the connection 262 * has been made, as we may need to create the port several times). 263 */ 264 PRIV_END; 265 266 /* If we are installed setuid root be careful to not drop core. */ 267 if (original_real_uid != original_effective_uid) { 268 struct rlimit rlim; 269 rlim.rlim_cur = rlim.rlim_max = 0; 270 if (setrlimit(RLIMIT_CORE, &rlim) < 0) 271 fatal("setrlimit failed: %.100s", strerror(errno)); 272 } 273 /* Get user data. */ 274 pw = getpwuid(original_real_uid); 275 if (!pw) { 276 logit("You don't exist, go away!"); 277 exit(255); 278 } 279 /* Take a copy of the returned structure. */ 280 pw = pwcopy(pw); 281 282 /* 283 * Set our umask to something reasonable, as some files are created 284 * with the default umask. This will make them world-readable but 285 * writable only by the owner, which is ok for all files for which we 286 * don't set the modes explicitly. 287 */ 288 umask(022); 289 290 /* 291 * Initialize option structure to indicate that no values have been 292 * set. 293 */ 294 initialize_options(&options); 295 296 /* Parse command-line arguments. */ 297 host = NULL; 298 use_syslog = 0; 299 argv0 = av[0]; 300 301 again: 302 while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" 303 "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) { 304 switch (opt) { 305 case '1': 306 options.protocol = SSH_PROTO_1; 307 break; 308 case '2': 309 options.protocol = SSH_PROTO_2; 310 break; 311 case '4': 312 options.address_family = AF_INET; 313 break; 314 case '6': 315 options.address_family = AF_INET6; 316 break; 317 case 'n': 318 stdin_null_flag = 1; 319 break; 320 case 'f': 321 fork_after_authentication_flag = 1; 322 stdin_null_flag = 1; 323 break; 324 case 'x': 325 options.forward_x11 = 0; 326 break; 327 case 'X': 328 options.forward_x11 = 1; 329 break; 330 case 'y': 331 use_syslog = 1; 332 break; 333 case 'Y': 334 options.forward_x11 = 1; 335 options.forward_x11_trusted = 1; 336 break; 337 case 'g': 338 options.gateway_ports = 1; 339 break; 340 case 'O': 341 if (stdio_forward_host != NULL) 342 fatal("Cannot specify multiplexing " 343 "command with -W"); 344 else if (muxclient_command != 0) 345 fatal("Multiplexing command already specified"); 346 if (strcmp(optarg, "check") == 0) 347 muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; 348 else if (strcmp(optarg, "forward") == 0) 349 muxclient_command = SSHMUX_COMMAND_FORWARD; 350 else if (strcmp(optarg, "exit") == 0) 351 muxclient_command = SSHMUX_COMMAND_TERMINATE; 352 else if (strcmp(optarg, "stop") == 0) 353 muxclient_command = SSHMUX_COMMAND_STOP; 354 else if (strcmp(optarg, "cancel") == 0) 355 muxclient_command = SSHMUX_COMMAND_CANCEL_FWD; 356 else 357 fatal("Invalid multiplex command."); 358 break; 359 case 'P': /* deprecated */ 360 options.use_privileged_port = 0; 361 break; 362 case 'a': 363 options.forward_agent = 0; 364 break; 365 case 'A': 366 options.forward_agent = 1; 367 break; 368 case 'k': 369 options.gss_deleg_creds = 0; 370 break; 371 case 'K': 372 options.gss_authentication = 1; 373 options.gss_deleg_creds = 1; 374 break; 375 case 'i': 376 if (stat(optarg, &st) < 0) { 377 fprintf(stderr, "Warning: Identity file %s " 378 "not accessible: %s.\n", optarg, 379 strerror(errno)); 380 break; 381 } 382 add_identity_file(&options, NULL, optarg, 1); 383 break; 384 case 'I': 385 #ifdef ENABLE_PKCS11 386 options.pkcs11_provider = xstrdup(optarg); 387 #else 388 fprintf(stderr, "no support for PKCS#11.\n"); 389 #endif 390 break; 391 case 't': 392 if (options.request_tty == REQUEST_TTY_YES) 393 options.request_tty = REQUEST_TTY_FORCE; 394 else 395 options.request_tty = REQUEST_TTY_YES; 396 break; 397 case 'v': 398 if (debug_flag == 0) { 399 debug_flag = 1; 400 options.log_level = SYSLOG_LEVEL_DEBUG1; 401 } else { 402 if (options.log_level < SYSLOG_LEVEL_DEBUG3) 403 options.log_level++; 404 break; 405 } 406 /* FALLTHROUGH */ 407 case 'V': 408 fprintf(stderr, "%s, %s\n", 409 SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); 410 if (opt == 'V') 411 exit(0); 412 break; 413 case 'w': 414 if (options.tun_open == -1) 415 options.tun_open = SSH_TUNMODE_DEFAULT; 416 options.tun_local = a2tun(optarg, &options.tun_remote); 417 if (options.tun_local == SSH_TUNID_ERR) { 418 fprintf(stderr, 419 "Bad tun device '%s'\n", optarg); 420 exit(255); 421 } 422 break; 423 case 'W': 424 if (stdio_forward_host != NULL) 425 fatal("stdio forward already specified"); 426 if (muxclient_command != 0) 427 fatal("Cannot specify stdio forward with -O"); 428 if (parse_forward(&fwd, optarg, 1, 0)) { 429 stdio_forward_host = fwd.listen_host; 430 stdio_forward_port = fwd.listen_port; 431 xfree(fwd.connect_host); 432 } else { 433 fprintf(stderr, 434 "Bad stdio forwarding specification '%s'\n", 435 optarg); 436 exit(255); 437 } 438 options.request_tty = REQUEST_TTY_NO; 439 no_shell_flag = 1; 440 options.clear_forwardings = 1; 441 options.exit_on_forward_failure = 1; 442 break; 443 case 'q': 444 options.log_level = SYSLOG_LEVEL_QUIET; 445 break; 446 case 'e': 447 if (optarg[0] == '^' && optarg[2] == 0 && 448 (u_char) optarg[1] >= 64 && 449 (u_char) optarg[1] < 128) 450 options.escape_char = (u_char) optarg[1] & 31; 451 else if (strlen(optarg) == 1) 452 options.escape_char = (u_char) optarg[0]; 453 else if (strcmp(optarg, "none") == 0) 454 options.escape_char = SSH_ESCAPECHAR_NONE; 455 else { 456 fprintf(stderr, "Bad escape character '%s'.\n", 457 optarg); 458 exit(255); 459 } 460 break; 461 case 'c': 462 if (ciphers_valid(optarg)) { 463 /* SSH2 only */ 464 options.ciphers = xstrdup(optarg); 465 options.cipher = SSH_CIPHER_INVALID; 466 } else { 467 /* SSH1 only */ 468 options.cipher = cipher_number(optarg); 469 if (options.cipher == -1) { 470 fprintf(stderr, 471 "Unknown cipher type '%s'\n", 472 optarg); 473 exit(255); 474 } 475 if (options.cipher == SSH_CIPHER_3DES) 476 options.ciphers = __UNCONST("3des-cbc"); 477 else if (options.cipher == SSH_CIPHER_BLOWFISH) 478 options.ciphers = 479 __UNCONST("blowfish-cbc"); 480 else 481 options.ciphers = (char *)-1; 482 } 483 break; 484 case 'm': 485 if (mac_valid(optarg)) 486 options.macs = xstrdup(optarg); 487 else { 488 fprintf(stderr, "Unknown mac type '%s'\n", 489 optarg); 490 exit(255); 491 } 492 break; 493 case 'M': 494 if (options.control_master == SSHCTL_MASTER_YES) 495 options.control_master = SSHCTL_MASTER_ASK; 496 else 497 options.control_master = SSHCTL_MASTER_YES; 498 break; 499 case 'p': 500 options.port = a2port(optarg); 501 if (options.port <= 0) { 502 fprintf(stderr, "Bad port '%s'\n", optarg); 503 exit(255); 504 } 505 break; 506 case 'l': 507 options.user = optarg; 508 break; 509 510 case 'L': 511 if (parse_forward(&fwd, optarg, 0, 0)) 512 add_local_forward(&options, &fwd); 513 else { 514 fprintf(stderr, 515 "Bad local forwarding specification '%s'\n", 516 optarg); 517 exit(255); 518 } 519 break; 520 521 case 'R': 522 if (parse_forward(&fwd, optarg, 0, 1)) { 523 add_remote_forward(&options, &fwd); 524 } else { 525 fprintf(stderr, 526 "Bad remote forwarding specification " 527 "'%s'\n", optarg); 528 exit(255); 529 } 530 break; 531 532 case 'D': 533 if (parse_forward(&fwd, optarg, 1, 0)) { 534 add_local_forward(&options, &fwd); 535 } else { 536 fprintf(stderr, 537 "Bad dynamic forwarding specification " 538 "'%s'\n", optarg); 539 exit(255); 540 } 541 break; 542 543 case 'C': 544 options.compression = 1; 545 break; 546 case 'N': 547 no_shell_flag = 1; 548 options.request_tty = REQUEST_TTY_NO; 549 break; 550 case 'T': 551 options.request_tty = REQUEST_TTY_NO; 552 /* ensure that the user doesn't try to backdoor a */ 553 /* null cipher switch on an interactive session */ 554 /* so explicitly disable it no matter what */ 555 options.none_switch = 0; 556 break; 557 case 'o': 558 dummy = 1; 559 line = xstrdup(optarg); 560 if (process_config_line(&options, host ? host : "", 561 line, "command-line", 0, &dummy, SSHCONF_USERCONF) 562 != 0) 563 exit(255); 564 xfree(line); 565 break; 566 case 's': 567 subsystem_flag = 1; 568 break; 569 case 'S': 570 if (options.control_path != NULL) 571 free(options.control_path); 572 options.control_path = xstrdup(optarg); 573 break; 574 case 'b': 575 options.bind_address = optarg; 576 break; 577 case 'F': 578 config = optarg; 579 break; 580 default: 581 usage(); 582 } 583 } 584 585 ac -= optind; 586 av += optind; 587 588 if (ac > 0 && !host) { 589 if (strrchr(*av, '@')) { 590 p = xstrdup(*av); 591 cp = strrchr(p, '@'); 592 if (cp == NULL || cp == p) 593 usage(); 594 options.user = p; 595 *cp = '\0'; 596 host = ++cp; 597 } else 598 host = *av; 599 if (ac > 1) { 600 optind = optreset = 1; 601 goto again; 602 } 603 ac--, av++; 604 } 605 606 /* Check that we got a host name. */ 607 if (!host) 608 usage(); 609 610 OpenSSL_add_all_algorithms(); 611 ERR_load_crypto_strings(); 612 613 /* Initialize the command to execute on remote host. */ 614 buffer_init(&command); 615 616 /* 617 * Save the command to execute on the remote host in a buffer. There 618 * is no limit on the length of the command, except by the maximum 619 * packet size. Also sets the tty flag if there is no command. 620 */ 621 if (!ac) { 622 /* No command specified - execute shell on a tty. */ 623 if (subsystem_flag) { 624 fprintf(stderr, 625 "You must specify a subsystem to invoke.\n"); 626 usage(); 627 } 628 } else { 629 /* A command has been specified. Store it into the buffer. */ 630 for (i = 0; i < ac; i++) { 631 if (i) 632 buffer_append(&command, " ", 1); 633 buffer_append(&command, av[i], strlen(av[i])); 634 } 635 } 636 637 /* Cannot fork to background if no command. */ 638 if (fork_after_authentication_flag && buffer_len(&command) == 0 && 639 !no_shell_flag) 640 fatal("Cannot fork into background without a command " 641 "to execute."); 642 643 /* 644 * Initialize "log" output. Since we are the client all output 645 * actually goes to stderr. 646 */ 647 log_init(argv0, 648 options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, 649 SYSLOG_FACILITY_USER, !use_syslog); 650 651 /* 652 * Read per-user configuration file. Ignore the system wide config 653 * file if the user specifies a config file on the command line. 654 */ 655 if (config != NULL) { 656 if (!read_config_file(config, host, &options, SSHCONF_USERCONF)) 657 fatal("Can't open user config file %.100s: " 658 "%.100s", config, strerror(errno)); 659 } else { 660 r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, 661 _PATH_SSH_USER_CONFFILE); 662 if (r > 0 && (size_t)r < sizeof(buf)) 663 (void)read_config_file(buf, host, &options, 664 SSHCONF_CHECKPERM|SSHCONF_USERCONF); 665 666 /* Read systemwide configuration file after user config. */ 667 (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, 668 &options, 0); 669 } 670 671 /* Fill configuration defaults. */ 672 fill_default_options(&options); 673 674 channel_set_af(options.address_family); 675 676 /* reinit */ 677 log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); 678 679 if (options.request_tty == REQUEST_TTY_YES || 680 options.request_tty == REQUEST_TTY_FORCE) 681 tty_flag = 1; 682 683 /* Allocate a tty by default if no command specified. */ 684 if (buffer_len(&command) == 0) 685 tty_flag = options.request_tty != REQUEST_TTY_NO; 686 687 /* Force no tty */ 688 if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0) 689 tty_flag = 0; 690 /* Do not allocate a tty if stdin is not a tty. */ 691 if ((!isatty(fileno(stdin)) || stdin_null_flag) && 692 options.request_tty != REQUEST_TTY_FORCE) { 693 if (tty_flag) 694 logit("Pseudo-terminal will not be allocated because " 695 "stdin is not a terminal."); 696 tty_flag = 0; 697 } 698 699 if (options.user == NULL) 700 options.user = xstrdup(pw->pw_name); 701 702 /* Get default port if port has not been set. */ 703 if (options.port == 0) { 704 sp = getservbyname(SSH_SERVICE_NAME, "tcp"); 705 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; 706 } 707 708 /* preserve host name given on command line for %n expansion */ 709 host_arg = host; 710 if (options.hostname != NULL) { 711 host = percent_expand(options.hostname, 712 "h", host, (char *)NULL); 713 } 714 715 if (gethostname(thishost, sizeof(thishost)) == -1) 716 fatal("gethostname: %s", strerror(errno)); 717 strlcpy(shorthost, thishost, sizeof(shorthost)); 718 shorthost[strcspn(thishost, ".")] = '\0'; 719 snprintf(portstr, sizeof(portstr), "%d", options.port); 720 721 if (options.local_command != NULL) { 722 debug3("expanding LocalCommand: %s", options.local_command); 723 cp = options.local_command; 724 options.local_command = percent_expand(cp, "d", pw->pw_dir, 725 "h", host, "l", thishost, "n", host_arg, "r", options.user, 726 "p", portstr, "u", pw->pw_name, "L", shorthost, 727 (char *)NULL); 728 debug3("expanded LocalCommand: %s", options.local_command); 729 xfree(cp); 730 } 731 732 /* force lowercase for hostkey matching */ 733 if (options.host_key_alias != NULL) { 734 for (p = options.host_key_alias; *p; p++) 735 if (isupper((unsigned char)*p)) 736 *p = (char)tolower((unsigned char)*p); 737 } 738 739 if (options.proxy_command != NULL && 740 strcmp(options.proxy_command, "none") == 0) { 741 xfree(options.proxy_command); 742 options.proxy_command = NULL; 743 } 744 if (options.control_path != NULL && 745 strcmp(options.control_path, "none") == 0) { 746 xfree(options.control_path); 747 options.control_path = NULL; 748 } 749 750 if (options.control_path != NULL) { 751 cp = tilde_expand_filename(options.control_path, 752 original_real_uid); 753 xfree(options.control_path); 754 options.control_path = percent_expand(cp, "h", host, 755 "l", thishost, "n", host_arg, "r", options.user, 756 "p", portstr, "u", pw->pw_name, "L", shorthost, 757 (char *)NULL); 758 xfree(cp); 759 } 760 if (muxclient_command != 0 && options.control_path == NULL) 761 fatal("No ControlPath specified for \"-O\" command"); 762 if (options.control_path != NULL) 763 muxclient(options.control_path); 764 765 timeout_ms = options.connection_timeout * 1000; 766 767 /* Open a connection to the remote host. */ 768 if (ssh_connect(host, &hostaddr, options.port, 769 options.address_family, options.connection_attempts, &timeout_ms, 770 options.tcp_keep_alive, 771 original_effective_uid == 0 && options.use_privileged_port, 772 options.proxy_command) != 0) 773 exit(255); 774 775 if (timeout_ms > 0) 776 debug3("timeout: %d ms remain after connect", timeout_ms); 777 778 /* 779 * If we successfully made the connection, load the host private key 780 * in case we will need it later for combined rsa-rhosts 781 * authentication. This must be done before releasing extra 782 * privileges, because the file is only readable by root. 783 * If we cannot access the private keys, load the public keys 784 * instead and try to execute the ssh-keysign helper instead. 785 */ 786 sensitive_data.nkeys = 0; 787 sensitive_data.keys = NULL; 788 sensitive_data.external_keysign = 0; 789 if (options.rhosts_rsa_authentication || 790 options.hostbased_authentication) { 791 sensitive_data.nkeys = 7; 792 sensitive_data.keys = xcalloc(sensitive_data.nkeys, 793 sizeof(Key)); 794 795 PRIV_START; 796 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, 797 _PATH_HOST_KEY_FILE, "", NULL, NULL); 798 sensitive_data.keys[1] = key_load_private_cert(KEY_DSA, 799 _PATH_HOST_DSA_KEY_FILE, "", NULL); 800 sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA, 801 _PATH_HOST_ECDSA_KEY_FILE, "", NULL); 802 sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, 803 _PATH_HOST_RSA_KEY_FILE, "", NULL); 804 sensitive_data.keys[4] = key_load_private_type(KEY_DSA, 805 _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); 806 sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA, 807 _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); 808 sensitive_data.keys[6] = key_load_private_type(KEY_RSA, 809 _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); 810 PRIV_END; 811 812 if (options.hostbased_authentication == 1 && 813 sensitive_data.keys[0] == NULL && 814 sensitive_data.keys[4] == NULL && 815 sensitive_data.keys[5] == NULL && 816 sensitive_data.keys[6] == NULL) { 817 sensitive_data.keys[1] = key_load_cert( 818 _PATH_HOST_DSA_KEY_FILE); 819 sensitive_data.keys[2] = key_load_cert( 820 _PATH_HOST_ECDSA_KEY_FILE); 821 sensitive_data.keys[3] = key_load_cert( 822 _PATH_HOST_RSA_KEY_FILE); 823 sensitive_data.keys[4] = key_load_public( 824 _PATH_HOST_DSA_KEY_FILE, NULL); 825 sensitive_data.keys[5] = key_load_public( 826 _PATH_HOST_ECDSA_KEY_FILE, NULL); 827 sensitive_data.keys[6] = key_load_public( 828 _PATH_HOST_RSA_KEY_FILE, NULL); 829 sensitive_data.external_keysign = 1; 830 } 831 } 832 /* 833 * Get rid of any extra privileges that we may have. We will no 834 * longer need them. Also, extra privileges could make it very hard 835 * to read identity files and other non-world-readable files from the 836 * user's home directory if it happens to be on a NFS volume where 837 * root is mapped to nobody. 838 */ 839 if (original_effective_uid == 0) { 840 PRIV_START; 841 permanently_set_uid(pw); 842 } 843 844 /* 845 * Now that we are back to our own permissions, create ~/.ssh 846 * directory if it doesn't already exist. 847 */ 848 if (config == NULL) { 849 r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir, 850 strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); 851 if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) 852 if (mkdir(buf, 0700) < 0) 853 error("Could not create directory '%.200s'.", 854 buf); 855 } 856 857 /* load options.identity_files */ 858 load_public_identity_files(); 859 860 /* Expand ~ in known host file names. */ 861 tilde_expand_paths(options.system_hostfiles, 862 options.num_system_hostfiles); 863 tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles); 864 865 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ 866 signal(SIGCHLD, main_sigchld_handler); 867 868 /* Log into the remote system. Never returns if the login fails. */ 869 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, 870 options.port, pw, timeout_ms); 871 872 if (packet_connection_is_on_socket()) { 873 verbose("Authenticated to %s ([%s]:%d).", host, 874 get_remote_ipaddr(), get_remote_port()); 875 } else { 876 verbose("Authenticated to %s (via proxy).", host); 877 } 878 879 /* We no longer need the private host keys. Clear them now. */ 880 if (sensitive_data.nkeys != 0) { 881 for (i = 0; i < sensitive_data.nkeys; i++) { 882 if (sensitive_data.keys[i] != NULL) { 883 /* Destroys contents safely */ 884 debug3("clear hostkey %d", i); 885 key_free(sensitive_data.keys[i]); 886 sensitive_data.keys[i] = NULL; 887 } 888 } 889 xfree(sensitive_data.keys); 890 } 891 for (i = 0; i < options.num_identity_files; i++) { 892 if (options.identity_files[i]) { 893 xfree(options.identity_files[i]); 894 options.identity_files[i] = NULL; 895 } 896 if (options.identity_keys[i]) { 897 key_free(options.identity_keys[i]); 898 options.identity_keys[i] = NULL; 899 } 900 } 901 902 exit_status = compat20 ? ssh_session2() : ssh_session(); 903 packet_close(); 904 905 if (options.control_path != NULL && muxserver_sock != -1) 906 unlink(options.control_path); 907 908 /* Kill ProxyCommand if it is running. */ 909 ssh_kill_proxy_command(); 910 911 return exit_status; 912 } 913 914 static void 915 control_persist_detach(void) 916 { 917 pid_t pid; 918 int devnull; 919 920 debug("%s: backgrounding master process", __func__); 921 922 /* 923 * master (current process) into the background, and make the 924 * foreground process a client of the backgrounded master. 925 */ 926 switch ((pid = fork())) { 927 case -1: 928 fatal("%s: fork: %s", __func__, strerror(errno)); 929 case 0: 930 /* Child: master process continues mainloop */ 931 break; 932 default: 933 /* Parent: set up mux slave to connect to backgrounded master */ 934 debug2("%s: background process is %ld", __func__, (long)pid); 935 stdin_null_flag = ostdin_null_flag; 936 options.request_tty = orequest_tty; 937 tty_flag = otty_flag; 938 close(muxserver_sock); 939 muxserver_sock = -1; 940 options.control_master = SSHCTL_MASTER_NO; 941 muxclient(options.control_path); 942 /* muxclient() doesn't return on success. */ 943 fatal("Failed to connect to new control master"); 944 } 945 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { 946 error("%s: open(\"/dev/null\"): %s", __func__, 947 strerror(errno)); 948 } else { 949 if (dup2(devnull, STDIN_FILENO) == -1 || 950 dup2(devnull, STDOUT_FILENO) == -1) 951 error("%s: dup2: %s", __func__, strerror(errno)); 952 if (devnull > STDERR_FILENO) 953 close(devnull); 954 } 955 setproctitle("%s [mux]", options.control_path); 956 } 957 958 /* Do fork() after authentication. Used by "ssh -f" */ 959 static void 960 fork_postauth(void) 961 { 962 if (need_controlpersist_detach) 963 control_persist_detach(); 964 debug("forking to background"); 965 fork_after_authentication_flag = 0; 966 if (daemon(1, 1) < 0) 967 fatal("daemon() failed: %.200s", strerror(errno)); 968 } 969 970 /* Callback for remote forward global requests */ 971 static void 972 ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) 973 { 974 Forward *rfwd = (Forward *)ctxt; 975 976 /* XXX verbose() on failure? */ 977 debug("remote forward %s for: listen %d, connect %s:%d", 978 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 979 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); 980 if (rfwd->listen_port == 0) { 981 if (type == SSH2_MSG_REQUEST_SUCCESS) { 982 rfwd->allocated_port = packet_get_int(); 983 logit("Allocated port %u for remote forward to %s:%d", 984 rfwd->allocated_port, 985 rfwd->connect_host, rfwd->connect_port); 986 channel_update_permitted_opens(rfwd->handle, 987 rfwd->allocated_port); 988 } else { 989 channel_update_permitted_opens(rfwd->handle, -1); 990 } 991 } 992 993 if (type == SSH2_MSG_REQUEST_FAILURE) { 994 if (options.exit_on_forward_failure) 995 fatal("Error: remote port forwarding failed for " 996 "listen port %d", rfwd->listen_port); 997 else 998 logit("Warning: remote port forwarding failed for " 999 "listen port %d", rfwd->listen_port); 1000 } 1001 if (++remote_forward_confirms_received == options.num_remote_forwards) { 1002 debug("All remote forwarding requests processed"); 1003 if (fork_after_authentication_flag) 1004 fork_postauth(); 1005 } 1006 } 1007 1008 __dead static void 1009 client_cleanup_stdio_fwd(int id, void *arg) 1010 { 1011 debug("stdio forwarding: done"); 1012 cleanup_exit(0); 1013 } 1014 1015 static void 1016 ssh_init_stdio_forwarding(void) 1017 { 1018 Channel *c; 1019 int in, out; 1020 1021 if (stdio_forward_host == NULL) 1022 return; 1023 if (!compat20) 1024 fatal("stdio forwarding require Protocol 2"); 1025 1026 debug3("%s: %s:%d", __func__, stdio_forward_host, stdio_forward_port); 1027 1028 if ((in = dup(STDIN_FILENO)) < 0 || 1029 (out = dup(STDOUT_FILENO)) < 0) 1030 fatal("channel_connect_stdio_fwd: dup() in/out failed"); 1031 if ((c = channel_connect_stdio_fwd(stdio_forward_host, 1032 stdio_forward_port, in, out)) == NULL) 1033 fatal("%s: channel_connect_stdio_fwd failed", __func__); 1034 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); 1035 } 1036 1037 static void 1038 ssh_init_forwarding(void) 1039 { 1040 int success = 0; 1041 int i; 1042 1043 /* Initiate local TCP/IP port forwardings. */ 1044 for (i = 0; i < options.num_local_forwards; i++) { 1045 debug("Local connections to %.200s:%d forwarded to remote " 1046 "address %.200s:%d", 1047 (options.local_forwards[i].listen_host == NULL) ? 1048 (options.gateway_ports ? "*" : "LOCALHOST") : 1049 options.local_forwards[i].listen_host, 1050 options.local_forwards[i].listen_port, 1051 options.local_forwards[i].connect_host, 1052 options.local_forwards[i].connect_port); 1053 success += channel_setup_local_fwd_listener( 1054 options.local_forwards[i].listen_host, 1055 options.local_forwards[i].listen_port, 1056 options.local_forwards[i].connect_host, 1057 options.local_forwards[i].connect_port, 1058 options.gateway_ports); 1059 } 1060 if (i > 0 && success != i && options.exit_on_forward_failure) 1061 fatal("Could not request local forwarding."); 1062 if (i > 0 && success == 0) 1063 error("Could not request local forwarding."); 1064 1065 /* Initiate remote TCP/IP port forwardings. */ 1066 for (i = 0; i < options.num_remote_forwards; i++) { 1067 debug("Remote connections from %.200s:%d forwarded to " 1068 "local address %.200s:%d", 1069 (options.remote_forwards[i].listen_host == NULL) ? 1070 "LOCALHOST" : options.remote_forwards[i].listen_host, 1071 options.remote_forwards[i].listen_port, 1072 options.remote_forwards[i].connect_host, 1073 options.remote_forwards[i].connect_port); 1074 options.remote_forwards[i].handle = 1075 channel_request_remote_forwarding( 1076 options.remote_forwards[i].listen_host, 1077 options.remote_forwards[i].listen_port, 1078 options.remote_forwards[i].connect_host, 1079 options.remote_forwards[i].connect_port); 1080 if (options.remote_forwards[i].handle < 0) { 1081 if (options.exit_on_forward_failure) 1082 fatal("Could not request remote forwarding."); 1083 else 1084 logit("Warning: Could not request remote " 1085 "forwarding."); 1086 } else { 1087 client_register_global_confirm(ssh_confirm_remote_forward, 1088 &options.remote_forwards[i]); 1089 } 1090 } 1091 1092 /* Initiate tunnel forwarding. */ 1093 if (options.tun_open != SSH_TUNMODE_NO) { 1094 if (client_request_tun_fwd(options.tun_open, 1095 options.tun_local, options.tun_remote) == -1) { 1096 if (options.exit_on_forward_failure) 1097 fatal("Could not request tunnel forwarding."); 1098 else 1099 error("Could not request tunnel forwarding."); 1100 } 1101 } 1102 } 1103 1104 static void 1105 check_agent_present(void) 1106 { 1107 if (options.forward_agent) { 1108 /* Clear agent forwarding if we don't have an agent. */ 1109 if (!ssh_agent_present()) 1110 options.forward_agent = 0; 1111 } 1112 } 1113 1114 static int 1115 ssh_session(void) 1116 { 1117 int type; 1118 int interactive = 0; 1119 int have_tty = 0; 1120 struct winsize ws; 1121 const char *display; 1122 1123 /* Enable compression if requested. */ 1124 if (options.compression) { 1125 debug("Requesting compression at level %d.", 1126 options.compression_level); 1127 1128 if (options.compression_level < 1 || 1129 options.compression_level > 9) 1130 fatal("Compression level must be from 1 (fast) to " 1131 "9 (slow, best)."); 1132 1133 /* Send the request. */ 1134 packet_start(SSH_CMSG_REQUEST_COMPRESSION); 1135 packet_put_int(options.compression_level); 1136 packet_send(); 1137 packet_write_wait(); 1138 type = packet_read(); 1139 if (type == SSH_SMSG_SUCCESS) 1140 packet_start_compression(options.compression_level); 1141 else if (type == SSH_SMSG_FAILURE) 1142 logit("Warning: Remote host refused compression."); 1143 else 1144 packet_disconnect("Protocol error waiting for " 1145 "compression response."); 1146 } 1147 /* Allocate a pseudo tty if appropriate. */ 1148 if (tty_flag) { 1149 const char *dp; 1150 debug("Requesting pty."); 1151 1152 /* Start the packet. */ 1153 packet_start(SSH_CMSG_REQUEST_PTY); 1154 1155 /* Store TERM in the packet. There is no limit on the 1156 length of the string. */ 1157 dp = getenv("TERM"); 1158 if (!dp) 1159 dp = ""; 1160 packet_put_cstring(dp); 1161 1162 /* Store window size in the packet. */ 1163 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) 1164 memset(&ws, 0, sizeof(ws)); 1165 packet_put_int((u_int)ws.ws_row); 1166 packet_put_int((u_int)ws.ws_col); 1167 packet_put_int((u_int)ws.ws_xpixel); 1168 packet_put_int((u_int)ws.ws_ypixel); 1169 1170 /* Store tty modes in the packet. */ 1171 tty_make_modes(fileno(stdin), NULL); 1172 1173 /* Send the packet, and wait for it to leave. */ 1174 packet_send(); 1175 packet_write_wait(); 1176 1177 /* Read response from the server. */ 1178 type = packet_read(); 1179 if (type == SSH_SMSG_SUCCESS) { 1180 interactive = 1; 1181 have_tty = 1; 1182 } else if (type == SSH_SMSG_FAILURE) 1183 logit("Warning: Remote host failed or refused to " 1184 "allocate a pseudo tty."); 1185 else 1186 packet_disconnect("Protocol error waiting for pty " 1187 "request response."); 1188 } 1189 /* Request X11 forwarding if enabled and DISPLAY is set. */ 1190 display = getenv("DISPLAY"); 1191 if (options.forward_x11 && display != NULL) { 1192 char *proto, *data; 1193 /* Get reasonable local authentication information. */ 1194 client_x11_get_proto(display, options.xauth_location, 1195 options.forward_x11_trusted, 1196 options.forward_x11_timeout, 1197 &proto, &data); 1198 /* Request forwarding with authentication spoofing. */ 1199 debug("Requesting X11 forwarding with authentication " 1200 "spoofing."); 1201 x11_request_forwarding_with_spoofing(0, display, proto, 1202 data, 0); 1203 /* Read response from the server. */ 1204 type = packet_read(); 1205 if (type == SSH_SMSG_SUCCESS) { 1206 interactive = 1; 1207 } else if (type == SSH_SMSG_FAILURE) { 1208 logit("Warning: Remote host denied X11 forwarding."); 1209 } else { 1210 packet_disconnect("Protocol error waiting for X11 " 1211 "forwarding"); 1212 } 1213 } 1214 /* Tell the packet module whether this is an interactive session. */ 1215 packet_set_interactive(interactive, 1216 options.ip_qos_interactive, options.ip_qos_bulk); 1217 1218 /* Request authentication agent forwarding if appropriate. */ 1219 check_agent_present(); 1220 1221 if (options.forward_agent) { 1222 debug("Requesting authentication agent forwarding."); 1223 auth_request_forwarding(); 1224 1225 /* Read response from the server. */ 1226 type = packet_read(); 1227 packet_check_eom(); 1228 if (type != SSH_SMSG_SUCCESS) 1229 logit("Warning: Remote host denied authentication agent forwarding."); 1230 } 1231 1232 /* Initiate port forwardings. */ 1233 ssh_init_stdio_forwarding(); 1234 ssh_init_forwarding(); 1235 1236 /* Execute a local command */ 1237 if (options.local_command != NULL && 1238 options.permit_local_command) 1239 ssh_local_cmd(options.local_command); 1240 1241 /* 1242 * If requested and we are not interested in replies to remote 1243 * forwarding requests, then let ssh continue in the background. 1244 */ 1245 if (fork_after_authentication_flag) { 1246 if (options.exit_on_forward_failure && 1247 options.num_remote_forwards > 0) { 1248 debug("deferring postauth fork until remote forward " 1249 "confirmation received"); 1250 } else 1251 fork_postauth(); 1252 } 1253 1254 /* 1255 * If a command was specified on the command line, execute the 1256 * command now. Otherwise request the server to start a shell. 1257 */ 1258 if (buffer_len(&command) > 0) { 1259 int len = buffer_len(&command); 1260 if (len > 900) 1261 len = 900; 1262 debug("Sending command: %.*s", len, 1263 (u_char *)buffer_ptr(&command)); 1264 packet_start(SSH_CMSG_EXEC_CMD); 1265 packet_put_string(buffer_ptr(&command), buffer_len(&command)); 1266 packet_send(); 1267 packet_write_wait(); 1268 } else { 1269 debug("Requesting shell."); 1270 packet_start(SSH_CMSG_EXEC_SHELL); 1271 packet_send(); 1272 packet_write_wait(); 1273 } 1274 1275 /* Enter the interactive session. */ 1276 return client_loop(have_tty, tty_flag ? 1277 options.escape_char : SSH_ESCAPECHAR_NONE, 0); 1278 } 1279 1280 /* request pty/x11/agent/tcpfwd/shell for channel */ 1281 static void 1282 ssh_session2_setup(int id, int success, void *arg) 1283 { 1284 extern char **environ; 1285 const char *display; 1286 int interactive = tty_flag; 1287 1288 if (!success) 1289 return; /* No need for error message, channels code sens one */ 1290 1291 display = getenv("DISPLAY"); 1292 if (options.forward_x11 && display != NULL) { 1293 char *proto, *data; 1294 /* Get reasonable local authentication information. */ 1295 client_x11_get_proto(display, options.xauth_location, 1296 options.forward_x11_trusted, 1297 options.forward_x11_timeout, &proto, &data); 1298 /* Request forwarding with authentication spoofing. */ 1299 debug("Requesting X11 forwarding with authentication " 1300 "spoofing."); 1301 x11_request_forwarding_with_spoofing(id, display, proto, 1302 data, 1); 1303 client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); 1304 /* XXX exit_on_forward_failure */ 1305 interactive = 1; 1306 } 1307 1308 check_agent_present(); 1309 if (options.forward_agent) { 1310 debug("Requesting authentication agent forwarding."); 1311 channel_request_start(id, "auth-agent-req@openssh.com", 0); 1312 packet_send(); 1313 } 1314 1315 /* Tell the packet module whether this is an interactive session. */ 1316 packet_set_interactive(interactive, 1317 options.ip_qos_interactive, options.ip_qos_bulk); 1318 1319 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1320 NULL, fileno(stdin), &command, environ); 1321 } 1322 1323 /* open new channel for a session */ 1324 static int 1325 ssh_session2_open(void) 1326 { 1327 Channel *c; 1328 int window, packetmax, in, out, err; 1329 int sock; 1330 int socksize; 1331 socklen_t socksizelen = sizeof(int); 1332 1333 if (stdin_null_flag) { 1334 in = open(_PATH_DEVNULL, O_RDONLY); 1335 } else { 1336 in = dup(STDIN_FILENO); 1337 } 1338 out = dup(STDOUT_FILENO); 1339 err = dup(STDERR_FILENO); 1340 1341 if (in < 0 || out < 0 || err < 0) 1342 fatal("dup() in/out/err failed"); 1343 1344 /* enable nonblocking unless tty */ 1345 if (!isatty(in)) 1346 set_nonblock(in); 1347 if (!isatty(out)) 1348 set_nonblock(out); 1349 if (!isatty(err)) 1350 set_nonblock(err); 1351 1352 /* we need to check to see if what they want to do about buffer */ 1353 /* sizes here. In a hpn to nonhpn connection we want to limit */ 1354 /* the window size to something reasonable in case the far side */ 1355 /* has the large window bug. In hpn to hpn connection we want to */ 1356 /* use the max window size but allow the user to override it */ 1357 /* lastly if they disabled hpn then use the ssh std window size */ 1358 1359 /* so why don't we just do a getsockopt() here and set the */ 1360 /* ssh window to that? In the case of a autotuning receive */ 1361 /* window the window would get stuck at the initial buffer */ 1362 /* size generally less than 96k. Therefore we need to set the */ 1363 /* maximum ssh window size to the maximum hpn buffer size */ 1364 /* unless the user has specifically set the tcprcvbufpoll */ 1365 /* to no. In which case we *can* just set the window to the */ 1366 /* minimum of the hpn buffer size and tcp receive buffer size */ 1367 1368 if (tty_flag) 1369 options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; 1370 else 1371 options.hpn_buffer_size = 2*1024*1024; 1372 1373 if (datafellows & SSH_BUG_LARGEWINDOW) 1374 { 1375 debug("HPN to Non-HPN Connection"); 1376 } 1377 else 1378 { 1379 if (options.tcp_rcv_buf_poll <= 0) 1380 { 1381 sock = socket(AF_INET, SOCK_STREAM, 0); 1382 getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 1383 &socksize, &socksizelen); 1384 close(sock); 1385 debug("socksize %d", socksize); 1386 options.hpn_buffer_size = socksize; 1387 debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size); 1388 } 1389 else 1390 { 1391 if (options.tcp_rcv_buf > 0) 1392 { 1393 /*create a socket but don't connect it */ 1394 /* we use that the get the rcv socket size */ 1395 sock = socket(AF_INET, SOCK_STREAM, 0); 1396 /* if they are using the tcp_rcv_buf option */ 1397 /* attempt to set the buffer size to that */ 1398 if (options.tcp_rcv_buf) 1399 setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, 1400 sizeof(options.tcp_rcv_buf)); 1401 getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 1402 &socksize, &socksizelen); 1403 close(sock); 1404 debug("socksize %d", socksize); 1405 options.hpn_buffer_size = socksize; 1406 debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size); 1407 } 1408 } 1409 1410 } 1411 1412 debug("Final hpn_buffer_size = %d", options.hpn_buffer_size); 1413 1414 window = options.hpn_buffer_size; 1415 1416 channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size); 1417 1418 packetmax = CHAN_SES_PACKET_DEFAULT; 1419 if (tty_flag) { 1420 window = 4*CHAN_SES_PACKET_DEFAULT; 1421 window >>= 1; 1422 packetmax >>= 1; 1423 } 1424 c = channel_new( 1425 "session", SSH_CHANNEL_OPENING, in, out, err, 1426 window, packetmax, CHAN_EXTENDED_WRITE, 1427 "client-session", /*nonblock*/0); 1428 1429 if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) { 1430 c->dynamic_window = 1; 1431 debug ("Enabled Dynamic Window Scaling\n"); 1432 } 1433 debug3("ssh_session2_open: channel_new: %d", c->self); 1434 1435 channel_send_open(c->self); 1436 if (!no_shell_flag) 1437 channel_register_open_confirm(c->self, 1438 ssh_session2_setup, NULL); 1439 1440 return c->self; 1441 } 1442 1443 static int 1444 ssh_session2(void) 1445 { 1446 int id = -1; 1447 1448 /* XXX should be pre-session */ 1449 if (!options.control_persist) 1450 ssh_init_stdio_forwarding(); 1451 ssh_init_forwarding(); 1452 1453 /* Start listening for multiplex clients */ 1454 muxserver_listen(); 1455 1456 /* 1457 * If we are in control persist mode and have a working mux listen 1458 * socket, then prepare to background ourselves and have a foreground 1459 * client attach as a control slave. 1460 * NB. we must save copies of the flags that we override for 1461 * the backgrounding, since we defer attachment of the slave until 1462 * after the connection is fully established (in particular, 1463 * async rfwd replies have been received for ExitOnForwardFailure). 1464 */ 1465 if (options.control_persist && muxserver_sock != -1) { 1466 ostdin_null_flag = stdin_null_flag; 1467 ono_shell_flag = no_shell_flag; 1468 orequest_tty = options.request_tty; 1469 otty_flag = tty_flag; 1470 stdin_null_flag = 1; 1471 no_shell_flag = 1; 1472 tty_flag = 0; 1473 if (!fork_after_authentication_flag) 1474 need_controlpersist_detach = 1; 1475 fork_after_authentication_flag = 1; 1476 } 1477 /* 1478 * ControlPersist mux listen socket setup failed, attempt the 1479 * stdio forward setup that we skipped earlier. 1480 */ 1481 if (options.control_persist && muxserver_sock == -1) 1482 ssh_init_stdio_forwarding(); 1483 1484 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1485 id = ssh_session2_open(); 1486 1487 /* If we don't expect to open a new session, then disallow it */ 1488 if (options.control_master == SSHCTL_MASTER_NO && 1489 (datafellows & SSH_NEW_OPENSSH)) { 1490 debug("Requesting no-more-sessions@openssh.com"); 1491 packet_start(SSH2_MSG_GLOBAL_REQUEST); 1492 packet_put_cstring("no-more-sessions@openssh.com"); 1493 packet_put_char(0); 1494 packet_send(); 1495 } 1496 1497 /* Execute a local command */ 1498 if (options.local_command != NULL && 1499 options.permit_local_command) 1500 ssh_local_cmd(options.local_command); 1501 1502 /* 1503 * If requested and we are not interested in replies to remote 1504 * forwarding requests, then let ssh continue in the background. 1505 */ 1506 if (fork_after_authentication_flag) { 1507 if (options.exit_on_forward_failure && 1508 options.num_remote_forwards > 0) { 1509 debug("deferring postauth fork until remote forward " 1510 "confirmation received"); 1511 } else 1512 fork_postauth(); 1513 } 1514 1515 if (options.use_roaming) 1516 request_roaming(); 1517 1518 return client_loop(tty_flag, tty_flag ? 1519 options.escape_char : SSH_ESCAPECHAR_NONE, id); 1520 } 1521 1522 static void 1523 load_public_identity_files(void) 1524 { 1525 char *filename, *cp, thishost[NI_MAXHOST]; 1526 char *pwdir = NULL, *pwname = NULL; 1527 int i = 0; 1528 Key *public; 1529 struct passwd *pw; 1530 u_int n_ids; 1531 char *identity_files[SSH_MAX_IDENTITY_FILES]; 1532 Key *identity_keys[SSH_MAX_IDENTITY_FILES]; 1533 #ifdef ENABLE_PKCS11 1534 Key **keys; 1535 int nkeys; 1536 #endif /* PKCS11 */ 1537 1538 n_ids = 0; 1539 bzero(identity_files, sizeof(identity_files)); 1540 bzero(identity_keys, sizeof(identity_keys)); 1541 1542 #ifdef ENABLE_PKCS11 1543 if (options.pkcs11_provider != NULL && 1544 options.num_identity_files < SSH_MAX_IDENTITY_FILES && 1545 (pkcs11_init(!options.batch_mode) == 0) && 1546 (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, 1547 &keys)) > 0) { 1548 for (i = 0; i < nkeys; i++) { 1549 if (n_ids >= SSH_MAX_IDENTITY_FILES) { 1550 key_free(keys[i]); 1551 continue; 1552 } 1553 identity_keys[n_ids] = keys[i]; 1554 identity_files[n_ids] = 1555 xstrdup(options.pkcs11_provider); /* XXX */ 1556 n_ids++; 1557 } 1558 xfree(keys); 1559 } 1560 #endif /* ENABLE_PKCS11 */ 1561 if ((pw = getpwuid(original_real_uid)) == NULL) 1562 fatal("load_public_identity_files: getpwuid failed"); 1563 pwname = xstrdup(pw->pw_name); 1564 pwdir = xstrdup(pw->pw_dir); 1565 if (gethostname(thishost, sizeof(thishost)) == -1) 1566 fatal("load_public_identity_files: gethostname: %s", 1567 strerror(errno)); 1568 for (i = 0; i < options.num_identity_files; i++) { 1569 if (n_ids >= SSH_MAX_IDENTITY_FILES) { 1570 xfree(options.identity_files[i]); 1571 continue; 1572 } 1573 cp = tilde_expand_filename(options.identity_files[i], 1574 original_real_uid); 1575 filename = percent_expand(cp, "d", pwdir, 1576 "u", pwname, "l", thishost, "h", host, 1577 "r", options.user, (char *)NULL); 1578 xfree(cp); 1579 public = key_load_public(filename, NULL); 1580 debug("identity file %s type %d", filename, 1581 public ? public->type : -1); 1582 xfree(options.identity_files[i]); 1583 identity_files[n_ids] = filename; 1584 identity_keys[n_ids] = public; 1585 1586 if (++n_ids >= SSH_MAX_IDENTITY_FILES) 1587 continue; 1588 1589 /* Try to add the certificate variant too */ 1590 xasprintf(&cp, "%s-cert", filename); 1591 public = key_load_public(cp, NULL); 1592 debug("identity file %s type %d", cp, 1593 public ? public->type : -1); 1594 if (public == NULL) { 1595 xfree(cp); 1596 continue; 1597 } 1598 if (!key_is_cert(public)) { 1599 debug("%s: key %s type %s is not a certificate", 1600 __func__, cp, key_type(public)); 1601 key_free(public); 1602 xfree(cp); 1603 continue; 1604 } 1605 identity_keys[n_ids] = public; 1606 /* point to the original path, most likely the private key */ 1607 identity_files[n_ids] = xstrdup(filename); 1608 n_ids++; 1609 } 1610 options.num_identity_files = n_ids; 1611 memcpy(options.identity_files, identity_files, sizeof(identity_files)); 1612 memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); 1613 1614 bzero(pwname, strlen(pwname)); 1615 xfree(pwname); 1616 bzero(pwdir, strlen(pwdir)); 1617 xfree(pwdir); 1618 } 1619 1620 static void 1621 main_sigchld_handler(int sig) 1622 { 1623 int save_errno = errno; 1624 pid_t pid; 1625 int status; 1626 1627 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || 1628 (pid < 0 && errno == EINTR)) 1629 ; 1630 1631 signal(sig, main_sigchld_handler); 1632 errno = save_errno; 1633 } 1634 1635