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 * 17 * Modified to work with SSL by Niels Provos <provos@citi.umich.edu> 18 * in Canada (German citizen). 19 * 20 * Redistribution and use in source and binary forms, with or without 21 * modification, are permitted provided that the following conditions 22 * are met: 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 31 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 32 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 34 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 38 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 #include "includes.h" 42 RCSID("$OpenBSD: ssh.c,v 1.116 2001/04/17 12:55:04 markus Exp $"); 43 RCSID("$FreeBSD$"); 44 45 #include <openssl/evp.h> 46 #include <openssl/err.h> 47 48 #include "ssh.h" 49 #include "ssh1.h" 50 #include "ssh2.h" 51 #include "compat.h" 52 #include "cipher.h" 53 #include "xmalloc.h" 54 #include "packet.h" 55 #include "buffer.h" 56 #include "uidswap.h" 57 #include "channels.h" 58 #include "key.h" 59 #include "authfd.h" 60 #include "authfile.h" 61 #include "pathnames.h" 62 #include "clientloop.h" 63 #include "log.h" 64 #include "readconf.h" 65 #include "sshconnect.h" 66 #include "tildexpand.h" 67 #include "dispatch.h" 68 #include "misc.h" 69 #include "kex.h" 70 #include "mac.h" 71 #include "sshtty.h" 72 73 extern char *__progname; 74 75 /* Flag indicating whether IPv4 or IPv6. This can be set on the command line. 76 Default value is AF_UNSPEC means both IPv4 and IPv6. */ 77 int IPv4or6 = AF_UNSPEC; 78 79 /* Flag indicating whether debug mode is on. This can be set on the command line. */ 80 int debug_flag = 0; 81 82 /* Flag indicating whether a tty should be allocated */ 83 int tty_flag = 0; 84 int no_tty_flag = 0; 85 int force_tty_flag = 0; 86 87 /* don't exec a shell */ 88 int no_shell_flag = 0; 89 90 /* 91 * Flag indicating that nothing should be read from stdin. This can be set 92 * on the command line. 93 */ 94 int stdin_null_flag = 0; 95 96 /* 97 * Flag indicating that ssh should fork after authentication. This is useful 98 * so that the pasphrase can be entered manually, and then ssh goes to the 99 * background. 100 */ 101 int fork_after_authentication_flag = 0; 102 103 /* 104 * General data structure for command line options and options configurable 105 * in configuration files. See readconf.h. 106 */ 107 Options options; 108 109 /* 110 * Name of the host we are connecting to. This is the name given on the 111 * command line, or the HostName specified for the user-supplied name in a 112 * configuration file. 113 */ 114 char *host; 115 116 /* socket address the host resolves to */ 117 struct sockaddr_storage hostaddr; 118 119 /* 120 * Flag to indicate that we have received a window change signal which has 121 * not yet been processed. This will cause a message indicating the new 122 * window size to be sent to the server a little later. This is volatile 123 * because this is updated in a signal handler. 124 */ 125 volatile int received_window_change_signal = 0; 126 127 /* Private host keys. */ 128 struct { 129 Key **keys; 130 int nkeys; 131 } sensitive_data; 132 133 /* Original real UID. */ 134 uid_t original_real_uid; 135 136 /* command to be executed */ 137 Buffer command; 138 139 /* Should we execute a command or invoke a subsystem? */ 140 int subsystem_flag = 0; 141 142 /* Prints a help message to the user. This function never returns. */ 143 144 void 145 usage(void) 146 { 147 fprintf(stderr, "Usage: %s [options] host [command]\n", __progname); 148 fprintf(stderr, "Options:\n"); 149 fprintf(stderr, " -l user Log in using this user name.\n"); 150 fprintf(stderr, " -n Redirect input from " _PATH_DEVNULL ".\n"); 151 fprintf(stderr, " -A Enable authentication agent forwarding.\n"); 152 fprintf(stderr, " -a Disable authentication agent forwarding.\n"); 153 #ifdef AFS 154 fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); 155 #endif /* AFS */ 156 fprintf(stderr, " -X Enable X11 connection forwarding.\n"); 157 fprintf(stderr, " -x Disable X11 connection forwarding.\n"); 158 fprintf(stderr, " -i file Identity for public key authentication " 159 "(default: ~/.ssh/identity)\n"); 160 fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); 161 fprintf(stderr, " -T Do not allocate a tty.\n"); 162 fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); 163 fprintf(stderr, " Multiple -v increases verbosity.\n"); 164 fprintf(stderr, " -V Display version number only.\n"); 165 fprintf(stderr, " -P Don't allocate a privileged port.\n"); 166 fprintf(stderr, " -q Quiet; don't display any warning messages.\n"); 167 fprintf(stderr, " -f Fork into background after authentication.\n"); 168 fprintf(stderr, " -e char Set escape character; ``none'' = disable (default: ~).\n"); 169 170 fprintf(stderr, " -c cipher Select encryption algorithm: " 171 "``3des'', ``blowfish''\n"); 172 fprintf(stderr, " -m macs Specify MAC algorithms for protocol version 2.\n"); 173 fprintf(stderr, " -p port Connect to this port. Server must be on the same port.\n"); 174 fprintf(stderr, " -L listen-port:host:port Forward local port to remote address\n"); 175 fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); 176 fprintf(stderr, " These cause %s to listen for connections on a port, and\n", __progname); 177 fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); 178 fprintf(stderr, " -C Enable compression.\n"); 179 fprintf(stderr, " -N Do not execute a shell or command.\n"); 180 fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); 181 fprintf(stderr, " -1 Force protocol version 1.\n"); 182 fprintf(stderr, " -2 Force protocol version 2.\n"); 183 fprintf(stderr, " -4 Use IPv4 only.\n"); 184 fprintf(stderr, " -6 Use IPv6 only.\n"); 185 fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); 186 fprintf(stderr, " -s Invoke command (mandatory) as SSH2 subsystem.\n"); 187 exit(1); 188 } 189 190 /* 191 * Connects to the given host using rsh (or prints an error message and exits 192 * if rsh is not available). This function never returns. 193 */ 194 void 195 rsh_connect(char *host, char *user, Buffer * command) 196 { 197 char *args[10]; 198 int i; 199 200 log("Using rsh. WARNING: Connection will not be encrypted."); 201 /* Build argument list for rsh. */ 202 i = 0; 203 #ifndef _PATH_RSH 204 #define _PATH_RSH "/usr/bin/rsh" 205 #endif 206 args[i++] = _PATH_RSH; 207 /* host may have to come after user on some systems */ 208 args[i++] = host; 209 if (user) { 210 args[i++] = "-l"; 211 args[i++] = user; 212 } 213 if (buffer_len(command) > 0) { 214 buffer_append(command, "\0", 1); 215 args[i++] = buffer_ptr(command); 216 } 217 args[i++] = NULL; 218 if (debug_flag) { 219 for (i = 0; args[i]; i++) { 220 if (i != 0) 221 fprintf(stderr, " "); 222 fprintf(stderr, "%s", args[i]); 223 } 224 fprintf(stderr, "\n"); 225 } 226 execv(_PATH_RSH, args); 227 perror(_PATH_RSH); 228 exit(1); 229 } 230 231 int ssh_session(void); 232 int ssh_session2(void); 233 void load_public_identity_files(void); 234 235 /* 236 * Main program for the ssh client. 237 */ 238 int 239 main(int ac, char **av) 240 { 241 int i, opt, optind, exit_status, ok; 242 u_short fwd_port, fwd_host_port; 243 char *optarg, *cp, buf[256]; 244 struct stat st; 245 struct passwd *pw; 246 int dummy; 247 uid_t original_effective_uid; 248 249 /* 250 * Save the original real uid. It will be needed later (uid-swapping 251 * may clobber the real uid). 252 */ 253 original_real_uid = getuid(); 254 original_effective_uid = geteuid(); 255 256 /* If we are installed setuid root be careful to not drop core. */ 257 if (original_real_uid != original_effective_uid) { 258 struct rlimit rlim; 259 rlim.rlim_cur = rlim.rlim_max = 0; 260 if (setrlimit(RLIMIT_CORE, &rlim) < 0) 261 fatal("setrlimit failed: %.100s", strerror(errno)); 262 } 263 /* Get user data. */ 264 pw = getpwuid(original_real_uid); 265 if (!pw) { 266 log("You don't exist, go away!"); 267 exit(1); 268 } 269 /* Take a copy of the returned structure. */ 270 pw = pwcopy(pw); 271 272 /* 273 * Use uid-swapping to give up root privileges for the duration of 274 * option processing. We will re-instantiate the rights when we are 275 * ready to create the privileged port, and will permanently drop 276 * them when the port has been created (actually, when the connection 277 * has been made, as we may need to create the port several times). 278 */ 279 temporarily_use_uid(pw); 280 281 /* 282 * Set our umask to something reasonable, as some files are created 283 * with the default umask. This will make them world-readable but 284 * writable only by the owner, which is ok for all files for which we 285 * don't set the modes explicitly. 286 */ 287 umask(022); 288 289 /* Initialize option structure to indicate that no values have been set. */ 290 initialize_options(&options); 291 292 /* Parse command-line arguments. */ 293 host = NULL; 294 295 for (optind = 1; optind < ac; optind++) { 296 if (av[optind][0] != '-') { 297 if (host) 298 break; 299 if ((cp = strchr(av[optind], '@'))) { 300 if(cp == av[optind]) 301 usage(); 302 options.user = av[optind]; 303 *cp = '\0'; 304 host = ++cp; 305 } else 306 host = av[optind]; 307 continue; 308 } 309 opt = av[optind][1]; 310 if (!opt) 311 usage(); 312 if (strchr("eilcmpLRDo", opt)) { /* options with arguments */ 313 optarg = av[optind] + 2; 314 if (strcmp(optarg, "") == 0) { 315 if (optind >= ac - 1) 316 usage(); 317 optarg = av[++optind]; 318 } 319 } else { 320 if (av[optind][2]) 321 usage(); 322 optarg = NULL; 323 } 324 switch (opt) { 325 case '1': 326 options.protocol = SSH_PROTO_1; 327 break; 328 case '2': 329 options.protocol = SSH_PROTO_2; 330 break; 331 case '4': 332 IPv4or6 = AF_INET; 333 break; 334 case '6': 335 IPv4or6 = AF_INET6; 336 break; 337 case 'n': 338 stdin_null_flag = 1; 339 break; 340 case 'f': 341 fork_after_authentication_flag = 1; 342 stdin_null_flag = 1; 343 break; 344 case 'x': 345 options.forward_x11 = 0; 346 break; 347 case 'X': 348 options.forward_x11 = 1; 349 break; 350 case 'g': 351 options.gateway_ports = 1; 352 break; 353 case 'P': 354 options.use_privileged_port = 0; 355 break; 356 case 'a': 357 options.forward_agent = 0; 358 break; 359 case 'A': 360 options.forward_agent = 1; 361 break; 362 #ifdef AFS 363 case 'k': 364 options.krb4_tgt_passing = 0; 365 options.krb5_tgt_passing = 0; 366 options.afs_token_passing = 0; 367 break; 368 #endif 369 case 'i': 370 if (stat(optarg, &st) < 0) { 371 fprintf(stderr, "Warning: Identity file %s does not exist.\n", 372 optarg); 373 break; 374 } 375 if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) 376 fatal("Too many identity files specified (max %d)", 377 SSH_MAX_IDENTITY_FILES); 378 options.identity_files[options.num_identity_files++] = xstrdup(optarg); 379 break; 380 case 't': 381 if (tty_flag) 382 force_tty_flag = 1; 383 tty_flag = 1; 384 break; 385 case 'v': 386 if (0 == debug_flag) { 387 debug_flag = 1; 388 options.log_level = SYSLOG_LEVEL_DEBUG1; 389 } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { 390 options.log_level++; 391 break; 392 } else { 393 fatal("Too high debugging level."); 394 } 395 /* fallthrough */ 396 case 'V': 397 fprintf(stderr, 398 "%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n", 399 SSH_VERSION, 400 PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, 401 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, 402 SSLeay()); 403 if (opt == 'V') 404 exit(0); 405 break; 406 case 'q': 407 options.log_level = SYSLOG_LEVEL_QUIET; 408 break; 409 case 'e': 410 if (optarg[0] == '^' && optarg[2] == 0 && 411 (u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) 412 options.escape_char = (u_char) optarg[1] & 31; 413 else if (strlen(optarg) == 1) 414 options.escape_char = (u_char) optarg[0]; 415 else if (strcmp(optarg, "none") == 0) 416 options.escape_char = -2; 417 else { 418 fprintf(stderr, "Bad escape character '%s'.\n", optarg); 419 exit(1); 420 } 421 break; 422 case 'c': 423 if (ciphers_valid(optarg)) { 424 /* SSH2 only */ 425 options.ciphers = xstrdup(optarg); 426 options.cipher = SSH_CIPHER_ILLEGAL; 427 } else { 428 /* SSH1 only */ 429 options.cipher = cipher_number(optarg); 430 if (options.cipher == -1) { 431 fprintf(stderr, "Unknown cipher type '%s'\n", optarg); 432 exit(1); 433 } 434 if (options.cipher == SSH_CIPHER_3DES) { 435 options.ciphers = "3des-cbc"; 436 } else if (options.cipher == SSH_CIPHER_BLOWFISH) { 437 options.ciphers = "blowfish-cbc"; 438 } else { 439 options.ciphers = (char *)-1; 440 } 441 } 442 break; 443 case 'm': 444 if (mac_valid(optarg)) 445 options.macs = xstrdup(optarg); 446 else { 447 fprintf(stderr, "Unknown mac type '%s'\n", optarg); 448 exit(1); 449 } 450 break; 451 case 'p': 452 options.port = a2port(optarg); 453 if (options.port == 0) { 454 fprintf(stderr, "Bad port '%s'\n", optarg); 455 exit(1); 456 } 457 break; 458 case 'l': 459 options.user = optarg; 460 break; 461 case 'R': 462 if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, 463 &fwd_host_port) != 3 && 464 sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, 465 &fwd_host_port) != 3) { 466 fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); 467 usage(); 468 /* NOTREACHED */ 469 } 470 add_remote_forward(&options, fwd_port, buf, fwd_host_port); 471 break; 472 case 'L': 473 if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, 474 &fwd_host_port) != 3 && 475 sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, 476 &fwd_host_port) != 3) { 477 fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); 478 usage(); 479 /* NOTREACHED */ 480 } 481 add_local_forward(&options, fwd_port, buf, fwd_host_port); 482 break; 483 484 case 'D': 485 fwd_port = a2port(optarg); 486 if (fwd_port == 0) { 487 fprintf(stderr, "Bad dynamic port '%s'\n", optarg); 488 exit(1); 489 } 490 add_local_forward(&options, fwd_port, "socks4", 0); 491 break; 492 493 case 'C': 494 options.compression = 1; 495 break; 496 case 'N': 497 no_shell_flag = 1; 498 no_tty_flag = 1; 499 break; 500 case 'T': 501 no_tty_flag = 1; 502 break; 503 case 'o': 504 dummy = 1; 505 if (process_config_line(&options, host ? host : "", optarg, 506 "command-line", 0, &dummy) != 0) 507 exit(1); 508 break; 509 case 's': 510 subsystem_flag = 1; 511 break; 512 default: 513 usage(); 514 } 515 } 516 517 /* Check that we got a host name. */ 518 if (!host) 519 usage(); 520 521 SSLeay_add_all_algorithms(); 522 ERR_load_crypto_strings(); 523 524 /* Initialize the command to execute on remote host. */ 525 buffer_init(&command); 526 527 /* 528 * Save the command to execute on the remote host in a buffer. There 529 * is no limit on the length of the command, except by the maximum 530 * packet size. Also sets the tty flag if there is no command. 531 */ 532 if (optind == ac) { 533 /* No command specified - execute shell on a tty. */ 534 tty_flag = 1; 535 if (subsystem_flag) { 536 fprintf(stderr, "You must specify a subsystem to invoke.\n"); 537 usage(); 538 } 539 } else { 540 /* A command has been specified. Store it into the 541 buffer. */ 542 for (i = optind; i < ac; i++) { 543 if (i > optind) 544 buffer_append(&command, " ", 1); 545 buffer_append(&command, av[i], strlen(av[i])); 546 } 547 } 548 549 /* Cannot fork to background if no command. */ 550 if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) 551 fatal("Cannot fork into background without a command to execute."); 552 553 /* Allocate a tty by default if no command specified. */ 554 if (buffer_len(&command) == 0) 555 tty_flag = 1; 556 557 /* Force no tty*/ 558 if (no_tty_flag) 559 tty_flag = 0; 560 /* Do not allocate a tty if stdin is not a tty. */ 561 if (!isatty(fileno(stdin)) && !force_tty_flag) { 562 if (tty_flag) 563 log("Pseudo-terminal will not be allocated because stdin is not a terminal."); 564 tty_flag = 0; 565 } 566 567 /* 568 * Initialize "log" output. Since we are the client all output 569 * actually goes to stderr. 570 */ 571 log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, 572 SYSLOG_FACILITY_USER, 1); 573 574 /* Read per-user configuration file. */ 575 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); 576 read_config_file(buf, host, &options); 577 578 /* Read systemwide configuration file. */ 579 read_config_file(_PATH_HOST_CONFIG_FILE, host, &options); 580 581 /* Fill configuration defaults. */ 582 fill_default_options(&options); 583 584 /* reinit */ 585 log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1); 586 587 if (options.user == NULL) 588 options.user = xstrdup(pw->pw_name); 589 590 if (options.hostname != NULL) 591 host = options.hostname; 592 593 /* Find canonic host name. */ 594 if (strchr(host, '.') == 0) { 595 struct addrinfo hints; 596 struct addrinfo *ai = NULL; 597 int errgai; 598 memset(&hints, 0, sizeof(hints)); 599 hints.ai_family = IPv4or6; 600 hints.ai_flags = AI_CANONNAME; 601 hints.ai_socktype = SOCK_STREAM; 602 errgai = getaddrinfo(host, NULL, &hints, &ai); 603 if (errgai == 0) { 604 if (ai->ai_canonname != NULL) 605 host = xstrdup(ai->ai_canonname); 606 freeaddrinfo(ai); 607 } 608 } 609 /* Disable rhosts authentication if not running as root. */ 610 if (original_effective_uid != 0 || !options.use_privileged_port) { 611 debug("Rhosts Authentication disabled, " 612 "originating port will not be trusted."); 613 options.rhosts_authentication = 0; 614 } 615 /* 616 * If using rsh has been selected, exec it now (without trying 617 * anything else). Note that we must release privileges first. 618 */ 619 if (options.use_rsh) { 620 /* 621 * Restore our superuser privileges. This must be done 622 * before permanently setting the uid. 623 */ 624 restore_uid(); 625 626 /* Switch to the original uid permanently. */ 627 permanently_set_uid(pw); 628 629 /* Execute rsh. */ 630 rsh_connect(host, options.user, &command); 631 fatal("rsh_connect returned"); 632 } 633 /* Restore our superuser privileges. */ 634 restore_uid(); 635 636 /* Open a connection to the remote host. */ 637 638 ok = ssh_connect(host, &hostaddr, options.port, 639 options.connection_attempts, 640 original_effective_uid != 0 || !options.use_privileged_port, 641 pw, options.proxy_command); 642 643 /* 644 * If we successfully made the connection, load the host private key 645 * in case we will need it later for combined rsa-rhosts 646 * authentication. This must be done before releasing extra 647 * privileges, because the file is only readable by root. 648 */ 649 sensitive_data.nkeys = 0; 650 sensitive_data.keys = NULL; 651 if (ok && (options.rhosts_rsa_authentication || 652 options.hostbased_authentication)) { 653 sensitive_data.nkeys = 3; 654 sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key)); 655 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, 656 _PATH_HOST_KEY_FILE, "", NULL); 657 sensitive_data.keys[1] = key_load_private_type(KEY_DSA, 658 _PATH_HOST_DSA_KEY_FILE, "", NULL); 659 sensitive_data.keys[2] = key_load_private_type(KEY_RSA, 660 _PATH_HOST_RSA_KEY_FILE, "", NULL); 661 } 662 /* 663 * Get rid of any extra privileges that we may have. We will no 664 * longer need them. Also, extra privileges could make it very hard 665 * to read identity files and other non-world-readable files from the 666 * user's home directory if it happens to be on a NFS volume where 667 * root is mapped to nobody. 668 */ 669 670 /* 671 * Note that some legacy systems need to postpone the following call 672 * to permanently_set_uid() until the private hostkey is destroyed 673 * with RSA_free(). Otherwise the calling user could ptrace() the 674 * process, read the private hostkey and impersonate the host. 675 * OpenBSD does not allow ptracing of setuid processes. 676 */ 677 permanently_set_uid(pw); 678 679 /* 680 * Now that we are back to our own permissions, create ~/.ssh 681 * directory if it doesn\'t already exist. 682 */ 683 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_DIR); 684 if (stat(buf, &st) < 0) 685 if (mkdir(buf, 0700) < 0) 686 error("Could not create directory '%.200s'.", buf); 687 688 /* Check if the connection failed, and try "rsh" if appropriate. */ 689 if (!ok) { 690 if (options.port != 0) 691 log("Secure connection to %.100s on port %hu refused%.100s.", 692 host, options.port, 693 options.fallback_to_rsh ? "; reverting to insecure method" : ""); 694 else 695 log("Secure connection to %.100s refused%.100s.", host, 696 options.fallback_to_rsh ? "; reverting to insecure method" : ""); 697 698 if (options.fallback_to_rsh) { 699 rsh_connect(host, options.user, &command); 700 fatal("rsh_connect returned"); 701 } 702 exit(1); 703 } 704 /* load options.identity_files */ 705 load_public_identity_files(); 706 707 /* Expand ~ in known host file names. */ 708 /* XXX mem-leaks: */ 709 options.system_hostfile = 710 tilde_expand_filename(options.system_hostfile, original_real_uid); 711 options.user_hostfile = 712 tilde_expand_filename(options.user_hostfile, original_real_uid); 713 options.system_hostfile2 = 714 tilde_expand_filename(options.system_hostfile2, original_real_uid); 715 options.user_hostfile2 = 716 tilde_expand_filename(options.user_hostfile2, original_real_uid); 717 718 /* Log into the remote system. This never returns if the login fails. */ 719 ssh_login(sensitive_data.keys, sensitive_data.nkeys, 720 host, (struct sockaddr *)&hostaddr, pw); 721 722 /* We no longer need the private host keys. Clear them now. */ 723 if (sensitive_data.nkeys != 0) { 724 for (i = 0; i < sensitive_data.nkeys; i++) { 725 if (sensitive_data.keys[i] != NULL) { 726 /* Destroys contents safely */ 727 debug3("clear hostkey %d", i); 728 key_free(sensitive_data.keys[i]); 729 sensitive_data.keys[i] = NULL; 730 } 731 } 732 xfree(sensitive_data.keys); 733 } 734 735 exit_status = compat20 ? ssh_session2() : ssh_session(); 736 packet_close(); 737 return exit_status; 738 } 739 740 void 741 x11_get_proto(char *proto, int proto_len, char *data, int data_len) 742 { 743 char line[512]; 744 FILE *f; 745 int got_data = 0, i; 746 747 if (options.xauth_location) { 748 /* Try to get Xauthority information for the display. */ 749 snprintf(line, sizeof line, "%.100s list %.200s 2>" _PATH_DEVNULL, 750 options.xauth_location, getenv("DISPLAY")); 751 f = popen(line, "r"); 752 if (f && fgets(line, sizeof(line), f) && 753 sscanf(line, "%*s %s %s", proto, data) == 2) 754 got_data = 1; 755 if (f) 756 pclose(f); 757 } 758 /* 759 * If we didn't get authentication data, just make up some 760 * data. The forwarding code will check the validity of the 761 * response anyway, and substitute this data. The X11 762 * server, however, will ignore this fake data and use 763 * whatever authentication mechanisms it was using otherwise 764 * for the local connection. 765 */ 766 if (!got_data) { 767 u_int32_t rand = 0; 768 769 strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len); 770 for (i = 0; i < 16; i++) { 771 if (i % 4 == 0) 772 rand = arc4random(); 773 snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff); 774 rand >>= 8; 775 } 776 } 777 } 778 779 void 780 ssh_init_forwarding(void) 781 { 782 int success = 0; 783 int i; 784 785 /* Initiate local TCP/IP port forwardings. */ 786 for (i = 0; i < options.num_local_forwards; i++) { 787 debug("Connections to local port %d forwarded to remote address %.200s:%d", 788 options.local_forwards[i].port, 789 options.local_forwards[i].host, 790 options.local_forwards[i].host_port); 791 success += channel_request_local_forwarding( 792 options.local_forwards[i].port, 793 options.local_forwards[i].host, 794 options.local_forwards[i].host_port, 795 options.gateway_ports); 796 } 797 if (i > 0 && success == 0) 798 error("Could not request local forwarding."); 799 800 /* Initiate remote TCP/IP port forwardings. */ 801 for (i = 0; i < options.num_remote_forwards; i++) { 802 debug("Connections to remote port %d forwarded to local address %.200s:%d", 803 options.remote_forwards[i].port, 804 options.remote_forwards[i].host, 805 options.remote_forwards[i].host_port); 806 channel_request_remote_forwarding( 807 options.remote_forwards[i].port, 808 options.remote_forwards[i].host, 809 options.remote_forwards[i].host_port); 810 } 811 } 812 813 void 814 check_agent_present(void) 815 { 816 if (options.forward_agent) { 817 /* Clear agent forwarding if we don\'t have an agent. */ 818 int authfd = ssh_get_authentication_socket(); 819 if (authfd < 0) 820 options.forward_agent = 0; 821 else 822 ssh_close_authentication_socket(authfd); 823 } 824 } 825 826 int 827 ssh_session(void) 828 { 829 int type; 830 int plen; 831 int interactive = 0; 832 int have_tty = 0; 833 struct winsize ws; 834 char *cp; 835 836 /* Enable compression if requested. */ 837 if (options.compression) { 838 debug("Requesting compression at level %d.", options.compression_level); 839 840 if (options.compression_level < 1 || options.compression_level > 9) 841 fatal("Compression level must be from 1 (fast) to 9 (slow, best)."); 842 843 /* Send the request. */ 844 packet_start(SSH_CMSG_REQUEST_COMPRESSION); 845 packet_put_int(options.compression_level); 846 packet_send(); 847 packet_write_wait(); 848 type = packet_read(&plen); 849 if (type == SSH_SMSG_SUCCESS) 850 packet_start_compression(options.compression_level); 851 else if (type == SSH_SMSG_FAILURE) 852 log("Warning: Remote host refused compression."); 853 else 854 packet_disconnect("Protocol error waiting for compression response."); 855 } 856 /* Allocate a pseudo tty if appropriate. */ 857 if (tty_flag) { 858 debug("Requesting pty."); 859 860 /* Start the packet. */ 861 packet_start(SSH_CMSG_REQUEST_PTY); 862 863 /* Store TERM in the packet. There is no limit on the 864 length of the string. */ 865 cp = getenv("TERM"); 866 if (!cp) 867 cp = ""; 868 packet_put_string(cp, strlen(cp)); 869 870 /* Store window size in the packet. */ 871 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) 872 memset(&ws, 0, sizeof(ws)); 873 packet_put_int(ws.ws_row); 874 packet_put_int(ws.ws_col); 875 packet_put_int(ws.ws_xpixel); 876 packet_put_int(ws.ws_ypixel); 877 878 /* Store tty modes in the packet. */ 879 tty_make_modes(fileno(stdin), NULL); 880 881 /* Send the packet, and wait for it to leave. */ 882 packet_send(); 883 packet_write_wait(); 884 885 /* Read response from the server. */ 886 type = packet_read(&plen); 887 if (type == SSH_SMSG_SUCCESS) { 888 interactive = 1; 889 have_tty = 1; 890 } else if (type == SSH_SMSG_FAILURE) 891 log("Warning: Remote host failed or refused to allocate a pseudo tty."); 892 else 893 packet_disconnect("Protocol error waiting for pty request response."); 894 } 895 /* Request X11 forwarding if enabled and DISPLAY is set. */ 896 if (options.forward_x11 && getenv("DISPLAY") != NULL) { 897 char proto[512], data[512]; 898 /* Get reasonable local authentication information. */ 899 x11_get_proto(proto, sizeof proto, data, sizeof data); 900 /* Request forwarding with authentication spoofing. */ 901 debug("Requesting X11 forwarding with authentication spoofing."); 902 x11_request_forwarding_with_spoofing(0, proto, data); 903 904 /* Read response from the server. */ 905 type = packet_read(&plen); 906 if (type == SSH_SMSG_SUCCESS) { 907 interactive = 1; 908 } else if (type == SSH_SMSG_FAILURE) { 909 log("Warning: Remote host denied X11 forwarding."); 910 } else { 911 packet_disconnect("Protocol error waiting for X11 forwarding"); 912 } 913 } 914 /* Tell the packet module whether this is an interactive session. */ 915 packet_set_interactive(interactive); 916 917 /* Request authentication agent forwarding if appropriate. */ 918 check_agent_present(); 919 920 if (options.forward_agent) { 921 debug("Requesting authentication agent forwarding."); 922 auth_request_forwarding(); 923 924 /* Read response from the server. */ 925 type = packet_read(&plen); 926 packet_integrity_check(plen, 0, type); 927 if (type != SSH_SMSG_SUCCESS) 928 log("Warning: Remote host denied authentication agent forwarding."); 929 } 930 931 /* Initiate port forwardings. */ 932 ssh_init_forwarding(); 933 934 /* If requested, let ssh continue in the background. */ 935 if (fork_after_authentication_flag) 936 if (daemon(1, 1) < 0) 937 fatal("daemon() failed: %.200s", strerror(errno)); 938 939 /* 940 * If a command was specified on the command line, execute the 941 * command now. Otherwise request the server to start a shell. 942 */ 943 if (buffer_len(&command) > 0) { 944 int len = buffer_len(&command); 945 if (len > 900) 946 len = 900; 947 debug("Sending command: %.*s", len, buffer_ptr(&command)); 948 packet_start(SSH_CMSG_EXEC_CMD); 949 packet_put_string(buffer_ptr(&command), buffer_len(&command)); 950 packet_send(); 951 packet_write_wait(); 952 } else { 953 debug("Requesting shell."); 954 packet_start(SSH_CMSG_EXEC_SHELL); 955 packet_send(); 956 packet_write_wait(); 957 } 958 959 /* Enter the interactive session. */ 960 return client_loop(have_tty, tty_flag ? options.escape_char : -1, 0); 961 } 962 963 void 964 client_subsystem_reply(int type, int plen, void *ctxt) 965 { 966 int id, len; 967 968 id = packet_get_int(); 969 len = buffer_len(&command); 970 if (len > 900) 971 len = 900; 972 packet_done(); 973 if (type == SSH2_MSG_CHANNEL_FAILURE) 974 fatal("Request for subsystem '%.*s' failed on channel %d", 975 len, buffer_ptr(&command), id); 976 } 977 978 void 979 ssh_session2_callback(int id, void *arg) 980 { 981 int len; 982 int interactive = 0; 983 struct termios tio; 984 985 debug("client_init id %d arg %ld", id, (long)arg); 986 987 if (tty_flag) { 988 struct winsize ws; 989 char *cp; 990 cp = getenv("TERM"); 991 if (!cp) 992 cp = ""; 993 /* Store window size in the packet. */ 994 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) 995 memset(&ws, 0, sizeof(ws)); 996 997 channel_request_start(id, "pty-req", 0); 998 packet_put_cstring(cp); 999 packet_put_int(ws.ws_col); 1000 packet_put_int(ws.ws_row); 1001 packet_put_int(ws.ws_xpixel); 1002 packet_put_int(ws.ws_ypixel); 1003 tio = get_saved_tio(); 1004 tty_make_modes(/*ignored*/ 0, &tio); 1005 packet_send(); 1006 interactive = 1; 1007 /* XXX wait for reply */ 1008 } 1009 if (options.forward_x11 && 1010 getenv("DISPLAY") != NULL) { 1011 char proto[512], data[512]; 1012 /* Get reasonable local authentication information. */ 1013 x11_get_proto(proto, sizeof proto, data, sizeof data); 1014 /* Request forwarding with authentication spoofing. */ 1015 debug("Requesting X11 forwarding with authentication spoofing."); 1016 x11_request_forwarding_with_spoofing(id, proto, data); 1017 interactive = 1; 1018 /* XXX wait for reply */ 1019 } 1020 1021 check_agent_present(); 1022 if (options.forward_agent) { 1023 debug("Requesting authentication agent forwarding."); 1024 channel_request_start(id, "auth-agent-req@openssh.com", 0); 1025 packet_send(); 1026 } 1027 1028 len = buffer_len(&command); 1029 if (len > 0) { 1030 if (len > 900) 1031 len = 900; 1032 if (subsystem_flag) { 1033 debug("Sending subsystem: %.*s", len, buffer_ptr(&command)); 1034 channel_request_start(id, "subsystem", /*want reply*/ 1); 1035 /* register callback for reply */ 1036 /* XXX we asume that client_loop has already been called */ 1037 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply); 1038 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply); 1039 } else { 1040 debug("Sending command: %.*s", len, buffer_ptr(&command)); 1041 channel_request_start(id, "exec", 0); 1042 } 1043 packet_put_string(buffer_ptr(&command), buffer_len(&command)); 1044 packet_send(); 1045 } else { 1046 channel_request(id, "shell", 0); 1047 } 1048 /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */ 1049 1050 /* register different callback, etc. XXX */ 1051 packet_set_interactive(interactive); 1052 } 1053 1054 int 1055 ssh_session2_command(void) 1056 { 1057 int id, window, packetmax; 1058 int in, out, err; 1059 1060 if (stdin_null_flag) { 1061 in = open(_PATH_DEVNULL, O_RDONLY); 1062 } else { 1063 in = dup(STDIN_FILENO); 1064 } 1065 out = dup(STDOUT_FILENO); 1066 err = dup(STDERR_FILENO); 1067 1068 if (in < 0 || out < 0 || err < 0) 1069 fatal("dup() in/out/err failed"); 1070 1071 /* enable nonblocking unless tty */ 1072 if (!isatty(in)) 1073 set_nonblock(in); 1074 if (!isatty(out)) 1075 set_nonblock(out); 1076 if (!isatty(err)) 1077 set_nonblock(err); 1078 1079 window = CHAN_SES_WINDOW_DEFAULT; 1080 packetmax = CHAN_SES_PACKET_DEFAULT; 1081 if (!tty_flag) { 1082 window *= 2; 1083 packetmax *=2; 1084 } 1085 id = channel_new( 1086 "session", SSH_CHANNEL_OPENING, in, out, err, 1087 window, packetmax, CHAN_EXTENDED_WRITE, 1088 xstrdup("client-session"), /*nonblock*/0); 1089 1090 debug("channel_new: %d", id); 1091 1092 channel_open(id); 1093 channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, 1094 ssh_session2_callback, (void *)0); 1095 1096 return id; 1097 } 1098 1099 int 1100 ssh_session2(void) 1101 { 1102 int id; 1103 1104 /* XXX should be pre-session */ 1105 ssh_init_forwarding(); 1106 1107 id = no_shell_flag ? -1 : ssh_session2_command(); 1108 1109 /* If requested, let ssh continue in the background. */ 1110 if (fork_after_authentication_flag) 1111 if (daemon(1, 1) < 0) 1112 fatal("daemon() failed: %.200s", strerror(errno)); 1113 1114 return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); 1115 } 1116 1117 void 1118 load_public_identity_files(void) 1119 { 1120 char *filename; 1121 Key *public; 1122 int i; 1123 1124 for (i = 0; i < options.num_identity_files; i++) { 1125 filename = tilde_expand_filename(options.identity_files[i], 1126 original_real_uid); 1127 public = key_load_public(filename, NULL); 1128 debug("identity file %s type %d", filename, 1129 public ? public->type : -1); 1130 xfree(options.identity_files[i]); 1131 options.identity_files[i] = filename; 1132 options.identity_keys[i] = public; 1133 } 1134 } 1135