1 /* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * Ssh client program. This program can be used to log into a remote machine. 6 * The software supports strong authentication, encryption, and forwarding 7 * of X11, TCP/IP, and authentication connections. 8 * 9 * As far as I am concerned, the code I have written for this software 10 * can be used freely for any purpose. Any derived versions of this 11 * software must be clearly marked as such, and if the derived work is 12 * incompatible with the protocol description in the RFC file, it must be 13 * called by a name other than "ssh" or "Secure Shell". 14 * 15 * Copyright (c) 1999 Niels Provos. All rights reserved. 16 * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved. 17 * 18 * Modified to work with SSL by Niels Provos <provos@citi.umich.edu> 19 * in Canada (German citizen). 20 * 21 * Redistribution and use in source and binary forms, with or without 22 * modification, are permitted provided that the following conditions 23 * are met: 24 * 1. Redistributions of source code must retain the above copyright 25 * notice, this list of conditions and the following disclaimer. 26 * 2. Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in the 28 * documentation and/or other materials provided with the distribution. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 33 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 */ 41 42 #include "includes.h" 43 RCSID("$OpenBSD: ssh.c,v 1.234 2005/03/10 22:01:06 deraadt Exp $"); 44 RCSID("$FreeBSD$"); 45 46 #include <openssl/evp.h> 47 #include <openssl/err.h> 48 49 #include "ssh.h" 50 #include "ssh1.h" 51 #include "ssh2.h" 52 #include "compat.h" 53 #include "cipher.h" 54 #include "xmalloc.h" 55 #include "packet.h" 56 #include "buffer.h" 57 #include "bufaux.h" 58 #include "channels.h" 59 #include "key.h" 60 #include "authfd.h" 61 #include "authfile.h" 62 #include "pathnames.h" 63 #include "dispatch.h" 64 #include "clientloop.h" 65 #include "log.h" 66 #include "readconf.h" 67 #include "sshconnect.h" 68 #include "misc.h" 69 #include "kex.h" 70 #include "mac.h" 71 #include "sshpty.h" 72 #include "match.h" 73 #include "msg.h" 74 #include "monitor_fdpass.h" 75 #include "uidswap.h" 76 77 #ifdef SMARTCARD 78 #include "scard.h" 79 #endif 80 81 extern char *__progname; 82 83 /* Flag indicating whether debug mode is on. This can be set on the command line. */ 84 int debug_flag = 0; 85 86 /* Flag indicating whether a tty should be allocated */ 87 int tty_flag = 0; 88 int no_tty_flag = 0; 89 int force_tty_flag = 0; 90 91 /* don't exec a shell */ 92 int no_shell_flag = 0; 93 94 /* 95 * Flag indicating that nothing should be read from stdin. This can be set 96 * on the command line. 97 */ 98 int stdin_null_flag = 0; 99 100 /* 101 * Flag indicating that ssh should fork after authentication. This is useful 102 * so that the passphrase can be entered manually, and then ssh goes to the 103 * background. 104 */ 105 int fork_after_authentication_flag = 0; 106 107 /* 108 * General data structure for command line options and options configurable 109 * in configuration files. See readconf.h. 110 */ 111 Options options; 112 113 /* optional user configfile */ 114 char *config = NULL; 115 116 /* 117 * Name of the host we are connecting to. This is the name given on the 118 * command line, or the HostName specified for the user-supplied name in a 119 * configuration file. 120 */ 121 char *host; 122 123 /* socket address the host resolves to */ 124 struct sockaddr_storage hostaddr; 125 126 /* Private host keys. */ 127 Sensitive sensitive_data; 128 129 /* Original real UID. */ 130 uid_t original_real_uid; 131 uid_t original_effective_uid; 132 133 /* command to be executed */ 134 Buffer command; 135 136 /* Should we execute a command or invoke a subsystem? */ 137 int subsystem_flag = 0; 138 139 /* # of replies received for global requests */ 140 static int client_global_request_id = 0; 141 142 /* pid of proxycommand child process */ 143 pid_t proxy_command_pid = 0; 144 145 /* fd to control socket */ 146 int control_fd = -1; 147 148 /* Multiplexing control command */ 149 static u_int mux_command = SSHMUX_COMMAND_OPEN; 150 151 /* Only used in control client mode */ 152 volatile sig_atomic_t control_client_terminate = 0; 153 u_int control_server_pid = 0; 154 155 /* Prints a help message to the user. This function never returns. */ 156 157 static void 158 usage(void) 159 { 160 fprintf(stderr, 161 "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" 162 " [-D port] [-e escape_char] [-F configfile]\n" 163 " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" 164 " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" 165 " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" 166 " [user@]hostname [command]\n" 167 ); 168 exit(1); 169 } 170 171 static int ssh_session(void); 172 static int ssh_session2(void); 173 static void load_public_identity_files(void); 174 static void control_client(const char *path); 175 176 /* 177 * Main program for the ssh client. 178 */ 179 int 180 main(int ac, char **av) 181 { 182 int i, opt, exit_status; 183 char *p, *cp, *line, buf[256]; 184 struct stat st; 185 struct passwd *pw; 186 int dummy; 187 extern int optind, optreset; 188 extern char *optarg; 189 Forward fwd; 190 191 __progname = ssh_get_progname(av[0]); 192 init_rng(); 193 194 /* 195 * Save the original real uid. It will be needed later (uid-swapping 196 * may clobber the real uid). 197 */ 198 original_real_uid = getuid(); 199 original_effective_uid = geteuid(); 200 201 /* 202 * Use uid-swapping to give up root privileges for the duration of 203 * option processing. We will re-instantiate the rights when we are 204 * ready to create the privileged port, and will permanently drop 205 * them when the port has been created (actually, when the connection 206 * has been made, as we may need to create the port several times). 207 */ 208 PRIV_END; 209 210 #ifdef HAVE_SETRLIMIT 211 /* If we are installed setuid root be careful to not drop core. */ 212 if (original_real_uid != original_effective_uid) { 213 struct rlimit rlim; 214 rlim.rlim_cur = rlim.rlim_max = 0; 215 if (setrlimit(RLIMIT_CORE, &rlim) < 0) 216 fatal("setrlimit failed: %.100s", strerror(errno)); 217 } 218 #endif 219 /* Get user data. */ 220 pw = getpwuid(original_real_uid); 221 if (!pw) { 222 logit("You don't exist, go away!"); 223 exit(1); 224 } 225 /* Take a copy of the returned structure. */ 226 pw = pwcopy(pw); 227 228 /* 229 * Set our umask to something reasonable, as some files are created 230 * with the default umask. This will make them world-readable but 231 * writable only by the owner, which is ok for all files for which we 232 * don't set the modes explicitly. 233 */ 234 umask(022); 235 236 /* Initialize option structure to indicate that no values have been set. */ 237 initialize_options(&options); 238 239 /* Parse command-line arguments. */ 240 host = NULL; 241 242 again: 243 while ((opt = getopt(ac, av, 244 "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) { 245 switch (opt) { 246 case '1': 247 options.protocol = SSH_PROTO_1; 248 break; 249 case '2': 250 options.protocol = SSH_PROTO_2; 251 break; 252 case '4': 253 options.address_family = AF_INET; 254 break; 255 case '6': 256 options.address_family = AF_INET6; 257 break; 258 case 'n': 259 stdin_null_flag = 1; 260 break; 261 case 'f': 262 fork_after_authentication_flag = 1; 263 stdin_null_flag = 1; 264 break; 265 case 'x': 266 options.forward_x11 = 0; 267 break; 268 case 'X': 269 options.forward_x11 = 1; 270 break; 271 case 'Y': 272 options.forward_x11 = 1; 273 options.forward_x11_trusted = 1; 274 break; 275 case 'g': 276 options.gateway_ports = 1; 277 break; 278 case 'O': 279 if (strcmp(optarg, "check") == 0) 280 mux_command = SSHMUX_COMMAND_ALIVE_CHECK; 281 else if (strcmp(optarg, "exit") == 0) 282 mux_command = SSHMUX_COMMAND_TERMINATE; 283 else 284 fatal("Invalid multiplex command."); 285 break; 286 case 'P': /* deprecated */ 287 options.use_privileged_port = 0; 288 break; 289 case 'a': 290 options.forward_agent = 0; 291 break; 292 case 'A': 293 options.forward_agent = 1; 294 break; 295 case 'k': 296 options.gss_deleg_creds = 0; 297 break; 298 case 'i': 299 if (stat(optarg, &st) < 0) { 300 fprintf(stderr, "Warning: Identity file %s " 301 "not accessible: %s.\n", optarg, 302 strerror(errno)); 303 break; 304 } 305 if (options.num_identity_files >= 306 SSH_MAX_IDENTITY_FILES) 307 fatal("Too many identity files specified " 308 "(max %d)", SSH_MAX_IDENTITY_FILES); 309 options.identity_files[options.num_identity_files++] = 310 xstrdup(optarg); 311 break; 312 case 'I': 313 #ifdef SMARTCARD 314 options.smartcard_device = xstrdup(optarg); 315 #else 316 fprintf(stderr, "no support for smartcards.\n"); 317 #endif 318 break; 319 case 't': 320 if (tty_flag) 321 force_tty_flag = 1; 322 tty_flag = 1; 323 break; 324 case 'v': 325 if (debug_flag == 0) { 326 debug_flag = 1; 327 options.log_level = SYSLOG_LEVEL_DEBUG1; 328 } else { 329 if (options.log_level < SYSLOG_LEVEL_DEBUG3) 330 options.log_level++; 331 break; 332 } 333 /* FALLTHROUGH */ 334 case 'V': 335 fprintf(stderr, "%s, %s\n", 336 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); 337 if (opt == 'V') 338 exit(0); 339 break; 340 case 'q': 341 options.log_level = SYSLOG_LEVEL_QUIET; 342 break; 343 case 'e': 344 if (optarg[0] == '^' && optarg[2] == 0 && 345 (u_char) optarg[1] >= 64 && 346 (u_char) optarg[1] < 128) 347 options.escape_char = (u_char) optarg[1] & 31; 348 else if (strlen(optarg) == 1) 349 options.escape_char = (u_char) optarg[0]; 350 else if (strcmp(optarg, "none") == 0) 351 options.escape_char = SSH_ESCAPECHAR_NONE; 352 else { 353 fprintf(stderr, "Bad escape character '%s'.\n", 354 optarg); 355 exit(1); 356 } 357 break; 358 case 'c': 359 if (ciphers_valid(optarg)) { 360 /* SSH2 only */ 361 options.ciphers = xstrdup(optarg); 362 options.cipher = SSH_CIPHER_INVALID; 363 } else { 364 /* SSH1 only */ 365 options.cipher = cipher_number(optarg); 366 if (options.cipher == -1) { 367 fprintf(stderr, 368 "Unknown cipher type '%s'\n", 369 optarg); 370 exit(1); 371 } 372 if (options.cipher == SSH_CIPHER_3DES) 373 options.ciphers = "3des-cbc"; 374 else if (options.cipher == SSH_CIPHER_BLOWFISH) 375 options.ciphers = "blowfish-cbc"; 376 else 377 options.ciphers = (char *)-1; 378 } 379 break; 380 case 'm': 381 if (mac_valid(optarg)) 382 options.macs = xstrdup(optarg); 383 else { 384 fprintf(stderr, "Unknown mac type '%s'\n", 385 optarg); 386 exit(1); 387 } 388 break; 389 case 'M': 390 options.control_master = 391 (options.control_master >= 1) ? 2 : 1; 392 break; 393 case 'p': 394 options.port = a2port(optarg); 395 if (options.port == 0) { 396 fprintf(stderr, "Bad port '%s'\n", optarg); 397 exit(1); 398 } 399 break; 400 case 'l': 401 options.user = optarg; 402 break; 403 404 case 'L': 405 if (parse_forward(&fwd, optarg)) 406 add_local_forward(&options, &fwd); 407 else { 408 fprintf(stderr, 409 "Bad local forwarding specification '%s'\n", 410 optarg); 411 exit(1); 412 } 413 break; 414 415 case 'R': 416 if (parse_forward(&fwd, optarg)) { 417 add_remote_forward(&options, &fwd); 418 } else { 419 fprintf(stderr, 420 "Bad remote forwarding specification " 421 "'%s'\n", optarg); 422 exit(1); 423 } 424 break; 425 426 case 'D': 427 cp = p = xstrdup(optarg); 428 memset(&fwd, '\0', sizeof(fwd)); 429 fwd.connect_host = "socks"; 430 if ((fwd.listen_host = hpdelim(&cp)) == NULL) { 431 fprintf(stderr, "Bad dynamic forwarding " 432 "specification '%.100s'\n", optarg); 433 exit(1); 434 } 435 if (cp != NULL) { 436 fwd.listen_port = a2port(cp); 437 fwd.listen_host = cleanhostname(fwd.listen_host); 438 } else { 439 fwd.listen_port = a2port(fwd.listen_host); 440 fwd.listen_host = ""; 441 } 442 443 if (fwd.listen_port == 0) { 444 fprintf(stderr, "Bad dynamic port '%s'\n", 445 optarg); 446 exit(1); 447 } 448 add_local_forward(&options, &fwd); 449 xfree(p); 450 break; 451 452 case 'C': 453 options.compression = 1; 454 break; 455 case 'N': 456 no_shell_flag = 1; 457 no_tty_flag = 1; 458 break; 459 case 'T': 460 no_tty_flag = 1; 461 break; 462 case 'o': 463 dummy = 1; 464 line = xstrdup(optarg); 465 if (process_config_line(&options, host ? host : "", 466 line, "command-line", 0, &dummy) != 0) 467 exit(1); 468 xfree(line); 469 break; 470 case 's': 471 subsystem_flag = 1; 472 break; 473 case 'S': 474 if (options.control_path != NULL) 475 free(options.control_path); 476 options.control_path = xstrdup(optarg); 477 break; 478 case 'b': 479 options.bind_address = optarg; 480 break; 481 case 'F': 482 config = optarg; 483 break; 484 default: 485 usage(); 486 } 487 } 488 489 ac -= optind; 490 av += optind; 491 492 if (ac > 0 && !host && **av != '-') { 493 if (strrchr(*av, '@')) { 494 p = xstrdup(*av); 495 cp = strrchr(p, '@'); 496 if (cp == NULL || cp == p) 497 usage(); 498 options.user = p; 499 *cp = '\0'; 500 host = ++cp; 501 } else 502 host = *av; 503 if (ac > 1) { 504 optind = optreset = 1; 505 goto again; 506 } 507 ac--, av++; 508 } 509 510 /* Check that we got a host name. */ 511 if (!host) 512 usage(); 513 514 SSLeay_add_all_algorithms(); 515 ERR_load_crypto_strings(); 516 517 /* Initialize the command to execute on remote host. */ 518 buffer_init(&command); 519 520 /* 521 * Save the command to execute on the remote host in a buffer. There 522 * is no limit on the length of the command, except by the maximum 523 * packet size. Also sets the tty flag if there is no command. 524 */ 525 if (!ac) { 526 /* No command specified - execute shell on a tty. */ 527 tty_flag = 1; 528 if (subsystem_flag) { 529 fprintf(stderr, 530 "You must specify a subsystem to invoke.\n"); 531 usage(); 532 } 533 } else { 534 /* A command has been specified. Store it into the buffer. */ 535 for (i = 0; i < ac; i++) { 536 if (i) 537 buffer_append(&command, " ", 1); 538 buffer_append(&command, av[i], strlen(av[i])); 539 } 540 } 541 542 /* Cannot fork to background if no command. */ 543 if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) 544 fatal("Cannot fork into background without a command to execute."); 545 546 /* Allocate a tty by default if no command specified. */ 547 if (buffer_len(&command) == 0) 548 tty_flag = 1; 549 550 /* Force no tty */ 551 if (no_tty_flag) 552 tty_flag = 0; 553 /* Do not allocate a tty if stdin is not a tty. */ 554 if (!isatty(fileno(stdin)) && !force_tty_flag) { 555 if (tty_flag) 556 logit("Pseudo-terminal will not be allocated because stdin is not a terminal."); 557 tty_flag = 0; 558 } 559 560 /* 561 * Initialize "log" output. Since we are the client all output 562 * actually goes to stderr. 563 */ 564 log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, 565 SYSLOG_FACILITY_USER, 1); 566 567 /* 568 * Read per-user configuration file. Ignore the system wide config 569 * file if the user specifies a config file on the command line. 570 */ 571 if (config != NULL) { 572 if (!read_config_file(config, host, &options, 0)) 573 fatal("Can't open user config file %.100s: " 574 "%.100s", config, strerror(errno)); 575 } else { 576 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, 577 _PATH_SSH_USER_CONFFILE); 578 (void)read_config_file(buf, host, &options, 1); 579 580 /* Read systemwide configuration file after use config. */ 581 (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, 582 &options, 0); 583 } 584 585 /* Fill configuration defaults. */ 586 fill_default_options(&options); 587 588 channel_set_af(options.address_family); 589 590 /* reinit */ 591 log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1); 592 593 seed_rng(); 594 595 if (options.user == NULL) 596 options.user = xstrdup(pw->pw_name); 597 598 if (options.hostname != NULL) 599 host = options.hostname; 600 601 /* Find canonic host name. */ 602 if (strchr(host, '.') == 0) { 603 struct addrinfo hints; 604 struct addrinfo *ai = NULL; 605 int errgai; 606 memset(&hints, 0, sizeof(hints)); 607 hints.ai_family = options.address_family; 608 hints.ai_flags = AI_CANONNAME; 609 hints.ai_socktype = SOCK_STREAM; 610 errgai = getaddrinfo(host, NULL, &hints, &ai); 611 if (errgai == 0) { 612 if (ai->ai_canonname != NULL) 613 host = xstrdup(ai->ai_canonname); 614 freeaddrinfo(ai); 615 } 616 } 617 618 /* force lowercase for hostkey matching */ 619 if (options.host_key_alias != NULL) { 620 for (p = options.host_key_alias; *p; p++) 621 if (isupper(*p)) 622 *p = tolower(*p); 623 } 624 625 if (options.proxy_command != NULL && 626 strcmp(options.proxy_command, "none") == 0) 627 options.proxy_command = NULL; 628 629 if (options.control_path != NULL) { 630 options.control_path = tilde_expand_filename( 631 options.control_path, original_real_uid); 632 } 633 if (options.control_path != NULL && options.control_master == 0) 634 control_client(options.control_path); /* This doesn't return */ 635 636 /* Open a connection to the remote host. */ 637 if (ssh_connect(host, &hostaddr, options.port, 638 options.address_family, options.connection_attempts, 639 #ifdef HAVE_CYGWIN 640 options.use_privileged_port, 641 #else 642 original_effective_uid == 0 && options.use_privileged_port, 643 #endif 644 options.proxy_command) != 0) 645 exit(1); 646 647 /* 648 * If we successfully made the connection, load the host private key 649 * in case we will need it later for combined rsa-rhosts 650 * authentication. This must be done before releasing extra 651 * privileges, because the file is only readable by root. 652 * If we cannot access the private keys, load the public keys 653 * instead and try to execute the ssh-keysign helper instead. 654 */ 655 sensitive_data.nkeys = 0; 656 sensitive_data.keys = NULL; 657 sensitive_data.external_keysign = 0; 658 if (options.rhosts_rsa_authentication || 659 options.hostbased_authentication) { 660 sensitive_data.nkeys = 3; 661 sensitive_data.keys = xmalloc(sensitive_data.nkeys * 662 sizeof(Key)); 663 664 PRIV_START; 665 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, 666 _PATH_HOST_KEY_FILE, "", NULL); 667 sensitive_data.keys[1] = key_load_private_type(KEY_DSA, 668 _PATH_HOST_DSA_KEY_FILE, "", NULL); 669 sensitive_data.keys[2] = key_load_private_type(KEY_RSA, 670 _PATH_HOST_RSA_KEY_FILE, "", NULL); 671 PRIV_END; 672 673 if (options.hostbased_authentication == 1 && 674 sensitive_data.keys[0] == NULL && 675 sensitive_data.keys[1] == NULL && 676 sensitive_data.keys[2] == NULL) { 677 sensitive_data.keys[1] = key_load_public( 678 _PATH_HOST_DSA_KEY_FILE, NULL); 679 sensitive_data.keys[2] = key_load_public( 680 _PATH_HOST_RSA_KEY_FILE, NULL); 681 sensitive_data.external_keysign = 1; 682 } 683 } 684 /* 685 * Get rid of any extra privileges that we may have. We will no 686 * longer need them. Also, extra privileges could make it very hard 687 * to read identity files and other non-world-readable files from the 688 * user's home directory if it happens to be on a NFS volume where 689 * root is mapped to nobody. 690 */ 691 if (original_effective_uid == 0) { 692 PRIV_START; 693 permanently_set_uid(pw); 694 } 695 696 /* 697 * Now that we are back to our own permissions, create ~/.ssh 698 * directory if it doesn\'t already exist. 699 */ 700 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); 701 if (stat(buf, &st) < 0) 702 if (mkdir(buf, 0700) < 0) 703 error("Could not create directory '%.200s'.", buf); 704 705 /* load options.identity_files */ 706 load_public_identity_files(); 707 708 /* Expand ~ in known host file names. */ 709 /* XXX mem-leaks: */ 710 options.system_hostfile = 711 tilde_expand_filename(options.system_hostfile, original_real_uid); 712 options.user_hostfile = 713 tilde_expand_filename(options.user_hostfile, original_real_uid); 714 options.system_hostfile2 = 715 tilde_expand_filename(options.system_hostfile2, original_real_uid); 716 options.user_hostfile2 = 717 tilde_expand_filename(options.user_hostfile2, original_real_uid); 718 719 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ 720 721 /* Log into the remote system. This never returns if the login fails. */ 722 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw); 723 724 /* We no longer need the private host keys. Clear them now. */ 725 if (sensitive_data.nkeys != 0) { 726 for (i = 0; i < sensitive_data.nkeys; i++) { 727 if (sensitive_data.keys[i] != NULL) { 728 /* Destroys contents safely */ 729 debug3("clear hostkey %d", i); 730 key_free(sensitive_data.keys[i]); 731 sensitive_data.keys[i] = NULL; 732 } 733 } 734 xfree(sensitive_data.keys); 735 } 736 for (i = 0; i < options.num_identity_files; i++) { 737 if (options.identity_files[i]) { 738 xfree(options.identity_files[i]); 739 options.identity_files[i] = NULL; 740 } 741 if (options.identity_keys[i]) { 742 key_free(options.identity_keys[i]); 743 options.identity_keys[i] = NULL; 744 } 745 } 746 747 exit_status = compat20 ? ssh_session2() : ssh_session(); 748 packet_close(); 749 750 if (options.control_path != NULL && control_fd != -1) 751 unlink(options.control_path); 752 753 /* 754 * Send SIGHUP to proxy command if used. We don't wait() in 755 * case it hangs and instead rely on init to reap the child 756 */ 757 if (proxy_command_pid > 1) 758 kill(proxy_command_pid, SIGHUP); 759 760 return exit_status; 761 } 762 763 #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" 764 765 static void 766 x11_get_proto(char **_proto, char **_data) 767 { 768 char cmd[1024]; 769 char line[512]; 770 char xdisplay[512]; 771 static char proto[512], data[512]; 772 FILE *f; 773 int got_data = 0, generated = 0, do_unlink = 0, i; 774 char *display, *xauthdir, *xauthfile; 775 struct stat st; 776 777 xauthdir = xauthfile = NULL; 778 *_proto = proto; 779 *_data = data; 780 proto[0] = data[0] = '\0'; 781 782 if (!options.xauth_location || 783 (stat(options.xauth_location, &st) == -1)) { 784 debug("No xauth program."); 785 } else { 786 if ((display = getenv("DISPLAY")) == NULL) { 787 debug("x11_get_proto: DISPLAY not set"); 788 return; 789 } 790 /* 791 * Handle FamilyLocal case where $DISPLAY does 792 * not match an authorization entry. For this we 793 * just try "xauth list unix:displaynum.screennum". 794 * XXX: "localhost" match to determine FamilyLocal 795 * is not perfect. 796 */ 797 if (strncmp(display, "localhost:", 10) == 0) { 798 snprintf(xdisplay, sizeof(xdisplay), "unix:%s", 799 display + 10); 800 display = xdisplay; 801 } 802 if (options.forward_x11_trusted == 0) { 803 xauthdir = xmalloc(MAXPATHLEN); 804 xauthfile = xmalloc(MAXPATHLEN); 805 strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); 806 if (mkdtemp(xauthdir) != NULL) { 807 do_unlink = 1; 808 snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", 809 xauthdir); 810 snprintf(cmd, sizeof(cmd), 811 "%s -f %s generate %s " SSH_X11_PROTO 812 " untrusted timeout 1200 2>" _PATH_DEVNULL, 813 options.xauth_location, xauthfile, display); 814 debug2("x11_get_proto: %s", cmd); 815 if (system(cmd) == 0) 816 generated = 1; 817 } 818 } 819 snprintf(cmd, sizeof(cmd), 820 "%s %s%s list %s . 2>" _PATH_DEVNULL, 821 options.xauth_location, 822 generated ? "-f " : "" , 823 generated ? xauthfile : "", 824 display); 825 debug2("x11_get_proto: %s", cmd); 826 f = popen(cmd, "r"); 827 if (f && fgets(line, sizeof(line), f) && 828 sscanf(line, "%*s %511s %511s", proto, data) == 2) 829 got_data = 1; 830 if (f) 831 pclose(f); 832 } 833 834 if (do_unlink) { 835 unlink(xauthfile); 836 rmdir(xauthdir); 837 } 838 if (xauthdir) 839 xfree(xauthdir); 840 if (xauthfile) 841 xfree(xauthfile); 842 843 /* 844 * If we didn't get authentication data, just make up some 845 * data. The forwarding code will check the validity of the 846 * response anyway, and substitute this data. The X11 847 * server, however, will ignore this fake data and use 848 * whatever authentication mechanisms it was using otherwise 849 * for the local connection. 850 */ 851 if (!got_data) { 852 u_int32_t rnd = 0; 853 854 logit("Warning: No xauth data; " 855 "using fake authentication data for X11 forwarding."); 856 strlcpy(proto, SSH_X11_PROTO, sizeof proto); 857 for (i = 0; i < 16; i++) { 858 if (i % 4 == 0) 859 rnd = arc4random(); 860 snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", 861 rnd & 0xff); 862 rnd >>= 8; 863 } 864 } 865 } 866 867 static void 868 ssh_init_forwarding(void) 869 { 870 int success = 0; 871 int i; 872 873 /* Initiate local TCP/IP port forwardings. */ 874 for (i = 0; i < options.num_local_forwards; i++) { 875 debug("Local connections to %.200s:%d forwarded to remote " 876 "address %.200s:%d", 877 (options.local_forwards[i].listen_host == NULL) ? 878 (options.gateway_ports ? "*" : "LOCALHOST") : 879 options.local_forwards[i].listen_host, 880 options.local_forwards[i].listen_port, 881 options.local_forwards[i].connect_host, 882 options.local_forwards[i].connect_port); 883 success += channel_setup_local_fwd_listener( 884 options.local_forwards[i].listen_host, 885 options.local_forwards[i].listen_port, 886 options.local_forwards[i].connect_host, 887 options.local_forwards[i].connect_port, 888 options.gateway_ports); 889 } 890 if (i > 0 && success == 0) 891 error("Could not request local forwarding."); 892 893 /* Initiate remote TCP/IP port forwardings. */ 894 for (i = 0; i < options.num_remote_forwards; i++) { 895 debug("Remote connections from %.200s:%d forwarded to " 896 "local address %.200s:%d", 897 (options.remote_forwards[i].listen_host == NULL) ? 898 (options.gateway_ports ? "*" : "LOCALHOST") : 899 options.remote_forwards[i].listen_host, 900 options.remote_forwards[i].listen_port, 901 options.remote_forwards[i].connect_host, 902 options.remote_forwards[i].connect_port); 903 channel_request_remote_forwarding( 904 options.remote_forwards[i].listen_host, 905 options.remote_forwards[i].listen_port, 906 options.remote_forwards[i].connect_host, 907 options.remote_forwards[i].connect_port); 908 } 909 } 910 911 static void 912 check_agent_present(void) 913 { 914 if (options.forward_agent) { 915 /* Clear agent forwarding if we don\'t have an agent. */ 916 if (!ssh_agent_present()) 917 options.forward_agent = 0; 918 } 919 } 920 921 static int 922 ssh_session(void) 923 { 924 int type; 925 int interactive = 0; 926 int have_tty = 0; 927 struct winsize ws; 928 char *cp; 929 930 /* Enable compression if requested. */ 931 if (options.compression) { 932 debug("Requesting compression at level %d.", options.compression_level); 933 934 if (options.compression_level < 1 || options.compression_level > 9) 935 fatal("Compression level must be from 1 (fast) to 9 (slow, best)."); 936 937 /* Send the request. */ 938 packet_start(SSH_CMSG_REQUEST_COMPRESSION); 939 packet_put_int(options.compression_level); 940 packet_send(); 941 packet_write_wait(); 942 type = packet_read(); 943 if (type == SSH_SMSG_SUCCESS) 944 packet_start_compression(options.compression_level); 945 else if (type == SSH_SMSG_FAILURE) 946 logit("Warning: Remote host refused compression."); 947 else 948 packet_disconnect("Protocol error waiting for compression response."); 949 } 950 /* Allocate a pseudo tty if appropriate. */ 951 if (tty_flag) { 952 debug("Requesting pty."); 953 954 /* Start the packet. */ 955 packet_start(SSH_CMSG_REQUEST_PTY); 956 957 /* Store TERM in the packet. There is no limit on the 958 length of the string. */ 959 cp = getenv("TERM"); 960 if (!cp) 961 cp = ""; 962 packet_put_cstring(cp); 963 964 /* Store window size in the packet. */ 965 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) 966 memset(&ws, 0, sizeof(ws)); 967 packet_put_int(ws.ws_row); 968 packet_put_int(ws.ws_col); 969 packet_put_int(ws.ws_xpixel); 970 packet_put_int(ws.ws_ypixel); 971 972 /* Store tty modes in the packet. */ 973 tty_make_modes(fileno(stdin), NULL); 974 975 /* Send the packet, and wait for it to leave. */ 976 packet_send(); 977 packet_write_wait(); 978 979 /* Read response from the server. */ 980 type = packet_read(); 981 if (type == SSH_SMSG_SUCCESS) { 982 interactive = 1; 983 have_tty = 1; 984 } else if (type == SSH_SMSG_FAILURE) 985 logit("Warning: Remote host failed or refused to allocate a pseudo tty."); 986 else 987 packet_disconnect("Protocol error waiting for pty request response."); 988 } 989 /* Request X11 forwarding if enabled and DISPLAY is set. */ 990 if (options.forward_x11 && getenv("DISPLAY") != NULL) { 991 char *proto, *data; 992 /* Get reasonable local authentication information. */ 993 x11_get_proto(&proto, &data); 994 /* Request forwarding with authentication spoofing. */ 995 debug("Requesting X11 forwarding with authentication spoofing."); 996 x11_request_forwarding_with_spoofing(0, proto, data); 997 998 /* Read response from the server. */ 999 type = packet_read(); 1000 if (type == SSH_SMSG_SUCCESS) { 1001 interactive = 1; 1002 } else if (type == SSH_SMSG_FAILURE) { 1003 logit("Warning: Remote host denied X11 forwarding."); 1004 } else { 1005 packet_disconnect("Protocol error waiting for X11 forwarding"); 1006 } 1007 } 1008 /* Tell the packet module whether this is an interactive session. */ 1009 packet_set_interactive(interactive); 1010 1011 /* Request authentication agent forwarding if appropriate. */ 1012 check_agent_present(); 1013 1014 if (options.forward_agent) { 1015 debug("Requesting authentication agent forwarding."); 1016 auth_request_forwarding(); 1017 1018 /* Read response from the server. */ 1019 type = packet_read(); 1020 packet_check_eom(); 1021 if (type != SSH_SMSG_SUCCESS) 1022 logit("Warning: Remote host denied authentication agent forwarding."); 1023 } 1024 1025 /* Initiate port forwardings. */ 1026 ssh_init_forwarding(); 1027 1028 /* If requested, let ssh continue in the background. */ 1029 if (fork_after_authentication_flag) 1030 if (daemon(1, 1) < 0) 1031 fatal("daemon() failed: %.200s", strerror(errno)); 1032 1033 /* 1034 * If a command was specified on the command line, execute the 1035 * command now. Otherwise request the server to start a shell. 1036 */ 1037 if (buffer_len(&command) > 0) { 1038 int len = buffer_len(&command); 1039 if (len > 900) 1040 len = 900; 1041 debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); 1042 packet_start(SSH_CMSG_EXEC_CMD); 1043 packet_put_string(buffer_ptr(&command), buffer_len(&command)); 1044 packet_send(); 1045 packet_write_wait(); 1046 } else { 1047 debug("Requesting shell."); 1048 packet_start(SSH_CMSG_EXEC_SHELL); 1049 packet_send(); 1050 packet_write_wait(); 1051 } 1052 1053 /* Enter the interactive session. */ 1054 return client_loop(have_tty, tty_flag ? 1055 options.escape_char : SSH_ESCAPECHAR_NONE, 0); 1056 } 1057 1058 static void 1059 ssh_subsystem_reply(int type, u_int32_t seq, void *ctxt) 1060 { 1061 int id, len; 1062 1063 id = packet_get_int(); 1064 len = buffer_len(&command); 1065 if (len > 900) 1066 len = 900; 1067 packet_check_eom(); 1068 if (type == SSH2_MSG_CHANNEL_FAILURE) 1069 fatal("Request for subsystem '%.*s' failed on channel %d", 1070 len, (u_char *)buffer_ptr(&command), id); 1071 } 1072 1073 void 1074 client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) 1075 { 1076 int i; 1077 1078 i = client_global_request_id++; 1079 if (i >= options.num_remote_forwards) 1080 return; 1081 debug("remote forward %s for: listen %d, connect %s:%d", 1082 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 1083 options.remote_forwards[i].listen_port, 1084 options.remote_forwards[i].connect_host, 1085 options.remote_forwards[i].connect_port); 1086 if (type == SSH2_MSG_REQUEST_FAILURE) 1087 logit("Warning: remote port forwarding failed for listen " 1088 "port %d", options.remote_forwards[i].listen_port); 1089 } 1090 1091 static void 1092 ssh_control_listener(void) 1093 { 1094 struct sockaddr_un addr; 1095 mode_t old_umask; 1096 int addr_len; 1097 1098 if (options.control_path == NULL || options.control_master <= 0) 1099 return; 1100 1101 memset(&addr, '\0', sizeof(addr)); 1102 addr.sun_family = AF_UNIX; 1103 addr_len = offsetof(struct sockaddr_un, sun_path) + 1104 strlen(options.control_path) + 1; 1105 1106 if (strlcpy(addr.sun_path, options.control_path, 1107 sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) 1108 fatal("ControlPath too long"); 1109 1110 if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) 1111 fatal("%s socket(): %s\n", __func__, strerror(errno)); 1112 1113 old_umask = umask(0177); 1114 if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) { 1115 control_fd = -1; 1116 if (errno == EINVAL || errno == EADDRINUSE) 1117 fatal("ControlSocket %s already exists", 1118 options.control_path); 1119 else 1120 fatal("%s bind(): %s\n", __func__, strerror(errno)); 1121 } 1122 umask(old_umask); 1123 1124 if (listen(control_fd, 64) == -1) 1125 fatal("%s listen(): %s\n", __func__, strerror(errno)); 1126 1127 set_nonblock(control_fd); 1128 } 1129 1130 /* request pty/x11/agent/tcpfwd/shell for channel */ 1131 static void 1132 ssh_session2_setup(int id, void *arg) 1133 { 1134 extern char **environ; 1135 1136 int interactive = tty_flag; 1137 if (options.forward_x11 && getenv("DISPLAY") != NULL) { 1138 char *proto, *data; 1139 /* Get reasonable local authentication information. */ 1140 x11_get_proto(&proto, &data); 1141 /* Request forwarding with authentication spoofing. */ 1142 debug("Requesting X11 forwarding with authentication spoofing."); 1143 x11_request_forwarding_with_spoofing(id, proto, data); 1144 interactive = 1; 1145 /* XXX wait for reply */ 1146 } 1147 1148 check_agent_present(); 1149 if (options.forward_agent) { 1150 debug("Requesting authentication agent forwarding."); 1151 channel_request_start(id, "auth-agent-req@openssh.com", 0); 1152 packet_send(); 1153 } 1154 1155 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1156 NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); 1157 1158 packet_set_interactive(interactive); 1159 } 1160 1161 /* open new channel for a session */ 1162 static int 1163 ssh_session2_open(void) 1164 { 1165 Channel *c; 1166 int window, packetmax, in, out, err; 1167 1168 if (stdin_null_flag) { 1169 in = open(_PATH_DEVNULL, O_RDONLY); 1170 } else { 1171 in = dup(STDIN_FILENO); 1172 } 1173 out = dup(STDOUT_FILENO); 1174 err = dup(STDERR_FILENO); 1175 1176 if (in < 0 || out < 0 || err < 0) 1177 fatal("dup() in/out/err failed"); 1178 1179 /* enable nonblocking unless tty */ 1180 if (!isatty(in)) 1181 set_nonblock(in); 1182 if (!isatty(out)) 1183 set_nonblock(out); 1184 if (!isatty(err)) 1185 set_nonblock(err); 1186 1187 window = CHAN_SES_WINDOW_DEFAULT; 1188 packetmax = CHAN_SES_PACKET_DEFAULT; 1189 if (tty_flag) { 1190 window >>= 1; 1191 packetmax >>= 1; 1192 } 1193 c = channel_new( 1194 "session", SSH_CHANNEL_OPENING, in, out, err, 1195 window, packetmax, CHAN_EXTENDED_WRITE, 1196 "client-session", /*nonblock*/0); 1197 1198 debug3("ssh_session2_open: channel_new: %d", c->self); 1199 1200 channel_send_open(c->self); 1201 if (!no_shell_flag) 1202 channel_register_confirm(c->self, ssh_session2_setup, NULL); 1203 1204 return c->self; 1205 } 1206 1207 static int 1208 ssh_session2(void) 1209 { 1210 int id = -1; 1211 1212 /* XXX should be pre-session */ 1213 ssh_init_forwarding(); 1214 ssh_control_listener(); 1215 1216 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1217 id = ssh_session2_open(); 1218 1219 /* If requested, let ssh continue in the background. */ 1220 if (fork_after_authentication_flag) 1221 if (daemon(1, 1) < 0) 1222 fatal("daemon() failed: %.200s", strerror(errno)); 1223 1224 return client_loop(tty_flag, tty_flag ? 1225 options.escape_char : SSH_ESCAPECHAR_NONE, id); 1226 } 1227 1228 static void 1229 load_public_identity_files(void) 1230 { 1231 char *filename; 1232 int i = 0; 1233 Key *public; 1234 #ifdef SMARTCARD 1235 Key **keys; 1236 1237 if (options.smartcard_device != NULL && 1238 options.num_identity_files < SSH_MAX_IDENTITY_FILES && 1239 (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL ) { 1240 int count = 0; 1241 for (i = 0; keys[i] != NULL; i++) { 1242 count++; 1243 memmove(&options.identity_files[1], &options.identity_files[0], 1244 sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1)); 1245 memmove(&options.identity_keys[1], &options.identity_keys[0], 1246 sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); 1247 options.num_identity_files++; 1248 options.identity_keys[0] = keys[i]; 1249 options.identity_files[0] = sc_get_key_label(keys[i]); 1250 } 1251 if (options.num_identity_files > SSH_MAX_IDENTITY_FILES) 1252 options.num_identity_files = SSH_MAX_IDENTITY_FILES; 1253 i = count; 1254 xfree(keys); 1255 } 1256 #endif /* SMARTCARD */ 1257 for (; i < options.num_identity_files; i++) { 1258 filename = tilde_expand_filename(options.identity_files[i], 1259 original_real_uid); 1260 public = key_load_public(filename, NULL); 1261 debug("identity file %s type %d", filename, 1262 public ? public->type : -1); 1263 xfree(options.identity_files[i]); 1264 options.identity_files[i] = filename; 1265 options.identity_keys[i] = public; 1266 } 1267 } 1268 1269 static void 1270 control_client_sighandler(int signo) 1271 { 1272 control_client_terminate = signo; 1273 } 1274 1275 static void 1276 control_client_sigrelay(int signo) 1277 { 1278 if (control_server_pid > 1) 1279 kill(control_server_pid, signo); 1280 } 1281 1282 static int 1283 env_permitted(char *env) 1284 { 1285 int i; 1286 char name[1024], *cp; 1287 1288 strlcpy(name, env, sizeof(name)); 1289 if ((cp = strchr(name, '=')) == NULL) 1290 return (0); 1291 1292 *cp = '\0'; 1293 1294 for (i = 0; i < options.num_send_env; i++) 1295 if (match_pattern(name, options.send_env[i])) 1296 return (1); 1297 1298 return (0); 1299 } 1300 1301 static void 1302 control_client(const char *path) 1303 { 1304 struct sockaddr_un addr; 1305 int i, r, fd, sock, exitval, num_env, addr_len; 1306 Buffer m; 1307 char *term; 1308 extern char **environ; 1309 u_int flags; 1310 1311 if (stdin_null_flag) { 1312 if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) 1313 fatal("open(/dev/null): %s", strerror(errno)); 1314 if (dup2(fd, STDIN_FILENO) == -1) 1315 fatal("dup2: %s", strerror(errno)); 1316 if (fd > STDERR_FILENO) 1317 close(fd); 1318 } 1319 1320 memset(&addr, '\0', sizeof(addr)); 1321 addr.sun_family = AF_UNIX; 1322 addr_len = offsetof(struct sockaddr_un, sun_path) + 1323 strlen(path) + 1; 1324 1325 if (strlcpy(addr.sun_path, path, 1326 sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) 1327 fatal("ControlPath too long"); 1328 1329 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) 1330 fatal("%s socket(): %s", __func__, strerror(errno)); 1331 1332 if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) 1333 fatal("Couldn't connect to %s: %s", path, strerror(errno)); 1334 1335 if ((term = getenv("TERM")) == NULL) 1336 term = ""; 1337 1338 flags = 0; 1339 if (tty_flag) 1340 flags |= SSHMUX_FLAG_TTY; 1341 if (subsystem_flag) 1342 flags |= SSHMUX_FLAG_SUBSYS; 1343 1344 buffer_init(&m); 1345 1346 /* Send our command to server */ 1347 buffer_put_int(&m, mux_command); 1348 buffer_put_int(&m, flags); 1349 if (ssh_msg_send(sock, /* version */1, &m) == -1) 1350 fatal("%s: msg_send", __func__); 1351 buffer_clear(&m); 1352 1353 /* Get authorisation status and PID of controlee */ 1354 if (ssh_msg_recv(sock, &m) == -1) 1355 fatal("%s: msg_recv", __func__); 1356 if (buffer_get_char(&m) != 1) 1357 fatal("%s: wrong version", __func__); 1358 if (buffer_get_int(&m) != 1) 1359 fatal("Connection to master denied"); 1360 control_server_pid = buffer_get_int(&m); 1361 1362 buffer_clear(&m); 1363 1364 switch (mux_command) { 1365 case SSHMUX_COMMAND_ALIVE_CHECK: 1366 fprintf(stderr, "Master running (pid=%d)\r\n", 1367 control_server_pid); 1368 exit(0); 1369 case SSHMUX_COMMAND_TERMINATE: 1370 fprintf(stderr, "Exit request sent.\r\n"); 1371 exit(0); 1372 case SSHMUX_COMMAND_OPEN: 1373 /* continue below */ 1374 break; 1375 default: 1376 fatal("silly mux_command %d", mux_command); 1377 } 1378 1379 /* SSHMUX_COMMAND_OPEN */ 1380 buffer_put_cstring(&m, term); 1381 buffer_append(&command, "\0", 1); 1382 buffer_put_cstring(&m, buffer_ptr(&command)); 1383 1384 if (options.num_send_env == 0 || environ == NULL) { 1385 buffer_put_int(&m, 0); 1386 } else { 1387 /* Pass environment */ 1388 num_env = 0; 1389 for (i = 0; environ[i] != NULL; i++) 1390 if (env_permitted(environ[i])) 1391 num_env++; /* Count */ 1392 1393 buffer_put_int(&m, num_env); 1394 1395 for (i = 0; environ[i] != NULL && num_env >= 0; i++) 1396 if (env_permitted(environ[i])) { 1397 num_env--; 1398 buffer_put_cstring(&m, environ[i]); 1399 } 1400 } 1401 1402 if (ssh_msg_send(sock, /* version */1, &m) == -1) 1403 fatal("%s: msg_send", __func__); 1404 1405 mm_send_fd(sock, STDIN_FILENO); 1406 mm_send_fd(sock, STDOUT_FILENO); 1407 mm_send_fd(sock, STDERR_FILENO); 1408 1409 /* Wait for reply, so master has a chance to gather ttymodes */ 1410 buffer_clear(&m); 1411 if (ssh_msg_recv(sock, &m) == -1) 1412 fatal("%s: msg_recv", __func__); 1413 if (buffer_get_char(&m) != 1) 1414 fatal("%s: wrong version", __func__); 1415 buffer_free(&m); 1416 1417 signal(SIGHUP, control_client_sighandler); 1418 signal(SIGINT, control_client_sighandler); 1419 signal(SIGTERM, control_client_sighandler); 1420 signal(SIGWINCH, control_client_sigrelay); 1421 1422 if (tty_flag) 1423 enter_raw_mode(); 1424 1425 /* Stick around until the controlee closes the client_fd */ 1426 exitval = 0; 1427 for (;!control_client_terminate;) { 1428 r = read(sock, &exitval, sizeof(exitval)); 1429 if (r == 0) { 1430 debug2("Received EOF from master"); 1431 break; 1432 } 1433 if (r > 0) 1434 debug2("Received exit status from master %d", exitval); 1435 if (r == -1 && errno != EINTR) 1436 fatal("%s: read %s", __func__, strerror(errno)); 1437 } 1438 1439 if (control_client_terminate) 1440 debug2("Exiting on signal %d", control_client_terminate); 1441 1442 close(sock); 1443 1444 leave_raw_mode(); 1445 1446 if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) 1447 fprintf(stderr, "Connection to master closed.\r\n"); 1448 1449 exit(exitval); 1450 } 1451