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 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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  43  * Use is subject to license terms.
  44  */
  45 
  46 #include "includes.h"
  47 RCSID("$OpenBSD: ssh.c,v 1.186 2002/09/19 01:58:18 djm Exp $");
  48 
  49 #include <openssl/err.h>
  50 
  51 #include "ssh.h"
  52 #include "ssh1.h"
  53 #include "ssh2.h"
  54 #include "compat.h"
  55 #include "cipher.h"
  56 #include "xmalloc.h"
  57 #include "packet.h"
  58 #include "buffer.h"
  59 #include "channels.h"
  60 #include "key.h"
  61 #include "authfd.h"
  62 #include "authfile.h"
  63 #include "pathnames.h"
  64 #include "clientloop.h"
  65 #include "log.h"
  66 #include "readconf.h"
  67 #include "sshconnect.h"
  68 #include "tildexpand.h"
  69 #include "dispatch.h"
  70 #include "misc.h"
  71 #include "kex.h"
  72 #include "mac.h"
  73 #include "sshtty.h"
  74 
  75 #include "g11n.h"
  76 
  77 #ifdef HAVE___PROGNAME
  78 extern char *__progname;
  79 #else
  80 char *__progname;
  81 #endif
  82 
  83 /* Flag indicating whether IPv4 or IPv6.  This can be set on the command line.
  84    Default value is AF_UNSPEC means both IPv4 and IPv6. */
  85 #ifdef IPV4_DEFAULT
  86 int IPv4or6 = AF_INET;
  87 #else
  88 int IPv4or6 = AF_UNSPEC;
  89 #endif
  90 
  91 /* Flag indicating whether debug mode is on.  This can be set on the command line. */
  92 int debug_flag = 0;
  93 
  94 /* Flag indicating whether a tty should be allocated */
  95 int tty_flag = 0;
  96 int no_tty_flag = 0;
  97 int force_tty_flag = 0;
  98 
  99 /* don't exec a shell */
 100 int no_shell_flag = 0;
 101 
 102 /*
 103  * Flag indicating that nothing should be read from stdin.  This can be set
 104  * on the command line.
 105  */
 106 int stdin_null_flag = 0;
 107 
 108 /*
 109  * Flag indicating that ssh should fork after authentication.  This is useful
 110  * so that the passphrase can be entered manually, and then ssh goes to the
 111  * background.
 112  */
 113 int fork_after_authentication_flag = 0;
 114 
 115 /*
 116  * General data structure for command line options and options configurable
 117  * in configuration files.  See readconf.h.
 118  */
 119 Options options;
 120 
 121 /* optional user configfile */
 122 char *config = NULL;
 123 
 124 /*
 125  * Name of the host we are connecting to.  This is the name given on the
 126  * command line, or the HostName specified for the user-supplied name in a
 127  * configuration file.
 128  */
 129 char *host;
 130 
 131 /* socket address the host resolves to */
 132 struct sockaddr_storage hostaddr;
 133 
 134 /* Private host keys. */
 135 Sensitive sensitive_data;
 136 
 137 /* Original real UID. */
 138 uid_t original_real_uid;
 139 uid_t original_effective_uid;
 140 
 141 /* command to be executed */
 142 Buffer command;
 143 
 144 /* Should we execute a command or invoke a subsystem? */
 145 int subsystem_flag = 0;
 146 
 147 /* # of replies received for global requests */
 148 static int client_global_request_id = 0;
 149 
 150 /* pid of proxycommand child process */
 151 pid_t proxy_command_pid = 0;
 152 
 153 /* Prints a help message to the user.  This function never returns. */
 154 
 155 static void
 156 usage(void)
 157 {
 158         fprintf(stderr,
 159                 gettext("Usage: %s [options] host [command]\n"
 160                 "Options:\n"
 161                 "  -l user     Log in using this user name.\n"
 162                 "  -n          Redirect input from /dev/null.\n"
 163                 "  -F config   Config file (default: ~/%s).\n"
 164                 "  -A          Enable authentication agent forwarding.\n"
 165                 "  -a          Disable authentication agent forwarding "
 166                 "(default).\n"
 167 #ifdef AFS
 168                 "  -k          Disable Kerberos ticket and AFS token "
 169                 "forwarding.\n"
 170 #endif                          /* AFS */
 171                 "  -X          Enable X11 connection forwarding.\n"
 172                 "  -x          Disable X11 connection forwarding (default).\n"
 173                 "  -i file     Identity for public key authentication "
 174                             "(default: ~/.ssh/identity)\n"
 175                 "  -t          Tty; allocate a tty even if command is given.\n"
 176                 "  -T          Do not allocate a tty.\n"
 177                 "  -v          Verbose; display verbose debugging messages.\n"
 178                 "              Multiple -v increases verbosity.\n"
 179                 "  -V          Display version number only.\n"
 180                 "  -q          Quiet; don't display any warning messages.\n"
 181                 "  -f          Fork into background after authentication.\n"
 182                 "  -e char     Set escape character; ``none'' = disable "
 183                 "(default: ~).\n"
 184                 "  -c cipher   Select encryption algorithm\n"
 185                 "  -m macs     Specify MAC algorithms for protocol version 2.\n"
 186                 "  -p port     Connect to this port.  Server must be "
 187                 "on the same port.\n"
 188                 "  -L listen-port:host:port   Forward local port to "
 189                 "remote address\n"
 190                 "  -R listen-port:host:port   Forward remote port to "
 191                 "local address\n"
 192                 "              These cause %s to listen for connections "
 193                 "on a port, and\n"
 194                 "              forward them to the other side by "
 195                 "connecting to host:port.\n"
 196                 "  -D port     Enable dynamic application-level "
 197                 "port forwarding.\n"
 198                 "  -C          Enable compression.\n"
 199                 "  -N          Do not execute a shell or command.\n"
 200                 "  -g          Allow remote hosts to connect to forwarded "
 201                 "ports.\n"
 202                 "  -1          Force protocol version 1.\n"
 203                 "  -2          Force protocol version 2.\n"
 204                 "  -4          Use IPv4 only.\n"
 205                 "  -6          Use IPv6 only.\n"
 206                 "  -o 'option' Process the option as if it was read "
 207                 "from a configuration file.\n"
 208                 "  -s          Invoke command (mandatory) as SSH2 subsystem.\n"
 209                 "  -b addr     Local IP address.\n"),
 210                 __progname, _PATH_SSH_USER_CONFFILE, __progname);
 211         exit(1);
 212 }
 213 
 214 static int ssh_session(void);
 215 static int ssh_session2(void);
 216 static void load_public_identity_files(void);
 217 static void rsh_connect(char *host, char *user, Buffer * command);
 218 
 219 /*
 220  * Main program for the ssh client.
 221  */
 222 int
 223 main(int ac, char **av)
 224 {
 225         int i, opt, exit_status;
 226         char *p, *cp, buf[256], *pw_name, *pw_dir;
 227         struct stat st;
 228         struct passwd *pw;
 229         int dummy;
 230         extern int optind, optreset;
 231         extern char *optarg;
 232         Forward fwd;
 233 
 234         __progname = get_progname(av[0]);
 235 
 236         (void) g11n_setlocale(LC_ALL, "");
 237 
 238         init_rng();
 239 
 240         /*
 241          * Save the original real uid.  It will be needed later (uid-swapping
 242          * may clobber the real uid).
 243          */
 244         original_real_uid = getuid();
 245         original_effective_uid = geteuid();
 246  
 247         /*
 248          * Use uid-swapping to give up root privileges for the duration of
 249          * option processing.  We will re-instantiate the rights when we are
 250          * ready to create the privileged port, and will permanently drop
 251          * them when the port has been created (actually, when the connection
 252          * has been made, as we may need to create the port several times).
 253          */
 254         PRIV_END;
 255 
 256 #ifdef HAVE_SETRLIMIT
 257         /* If we are installed setuid root be careful to not drop core. */
 258         if (original_real_uid != original_effective_uid) {
 259                 struct rlimit rlim;
 260                 rlim.rlim_cur = rlim.rlim_max = 0;
 261                 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
 262                         fatal("setrlimit failed: %.100s", strerror(errno));
 263         }
 264 #endif
 265         /*
 266          * Get user data. It may happen that NIS or LDAP connection breaks down
 267          * during the user's session. We should try to do our best and use the
 268          * HOME and LOGNAME variables. Remember that the SSH client might be the
 269          * only tool available to fix the problem with the naming services.
 270          */
 271         pw = getpwuid(original_real_uid);
 272         if (pw == NULL) {
 273                 if ((pw_dir = getenv("HOME")) == NULL) {
 274                         log("User account's password entry not found and HOME "
 275                             "not set. Set it manually and try again. "
 276                             "Exiting.");
 277                         exit(1);
 278                 }
 279                 log("User account's password entry not found, using "
 280                     "the HOME variable.");
 281 
 282                 if ((pw_name = getenv("LOGNAME")) == NULL) {
 283                         log("Need a local user name but LOGNAME is not set. "
 284                            "Set it manually and try again. Exiting.");
 285                         exit(1);
 286                 }
 287                 log("Local user name '%s' set from the LOGNAME variable.",
 288                     pw_name);
 289 
 290                 pw_dir = xstrdup(pw_dir);
 291                 pw_name = xstrdup(pw_name);
 292         } else {
 293                 pw_name = xstrdup(pw->pw_name);
 294                 pw_dir = xstrdup(pw->pw_dir);
 295         }
 296 
 297         /*
 298          * Set our umask to something reasonable, as some files are created
 299          * with the default umask.  This will make them world-readable but
 300          * writable only by the owner, which is ok for all files for which we
 301          * don't set the modes explicitly.
 302          */
 303         umask(022);
 304 
 305         /* Initialize option structure to indicate that no values have been set. */
 306         initialize_options(&options);
 307 
 308         /* Parse command-line arguments. */
 309         host = NULL;
 310 
 311 again:
 312         while ((opt = getopt(ac, av,
 313             "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) {
 314                 switch (opt) {
 315                 case '1':
 316                         options.protocol = SSH_PROTO_1;
 317                         break;
 318                 case '2':
 319                         options.protocol = SSH_PROTO_2;
 320                         break;
 321                 case '4':
 322                         IPv4or6 = AF_INET;
 323                         break;
 324                 case '6':
 325                         IPv4or6 = AF_INET6;
 326                         break;
 327                 case 'n':
 328                         stdin_null_flag = 1;
 329                         break;
 330                 case 'f':
 331                         fork_after_authentication_flag = 1;
 332                         stdin_null_flag = 1;
 333                         break;
 334                 case 'x':
 335                         options.forward_x11 = 0;
 336                         break;
 337                 case 'X':
 338                         options.forward_x11 = 1;
 339                         break;
 340                 case 'g':
 341                         options.gateway_ports = 1;
 342                         break;
 343                 case 'P':       /* deprecated */
 344                         fprintf(stderr, gettext("Warning: Option -P has "
 345                                                 "been deprecated\n"));
 346                         options.use_privileged_port = 0;
 347                         break;
 348                 case 'a':
 349                         options.forward_agent = 0;
 350                         break;
 351                 case 'A':
 352                         options.forward_agent = 1;
 353                         break;
 354 #ifdef AFS
 355                 case 'k':
 356                         options.kerberos_tgt_passing = 0;
 357                         options.afs_token_passing = 0;
 358                         break;
 359 #endif
 360                 case 'i':
 361                         if (stat(optarg, &st) < 0) {
 362                                 fprintf(stderr,
 363                                         gettext("Warning: Identity file %s "
 364                                         "does not exist.\n"), optarg);
 365                                 break;
 366                         }
 367                         if (options.num_identity_files >=
 368                             SSH_MAX_IDENTITY_FILES)
 369                                 fatal("Too many identity files specified "
 370                                     "(max %d)", SSH_MAX_IDENTITY_FILES);
 371                         options.identity_files[options.num_identity_files++] =
 372                             xstrdup(optarg);
 373                         break;
 374                 case 'I':
 375                         fprintf(stderr, "no support for smartcards.\n");
 376                         break;
 377                 case 't':
 378                         if (tty_flag)
 379                                 force_tty_flag = 1;
 380                         tty_flag = 1;
 381                         break;
 382                 case 'v':
 383                         if (0 == debug_flag) {
 384                                 debug_flag = 1;
 385                                 options.log_level = SYSLOG_LEVEL_DEBUG1;
 386                         } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) {
 387                                 options.log_level++;
 388                                 break;
 389                         } else
 390                                 fatal("Too high debugging level.");
 391                         /* FALLTHROUGH */
 392                 case 'V':
 393                         fprintf(stderr,
 394                             gettext("%s, SSH protocols %d.%d/%d.%d, "
 395                                     "OpenSSL 0x%8.8lx\n"),
 396                             SSH_VERSION,
 397                             PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
 398                             PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
 399                             SSLeay());
 400                         if (opt == 'V')
 401                                 exit(0);
 402                         break;
 403                 case 'q':
 404                         options.log_level = SYSLOG_LEVEL_QUIET;
 405                         break;
 406                 case 'e':
 407                         if (optarg[0] == '^' && optarg[2] == 0 &&
 408                             (u_char) optarg[1] >= 64 &&
 409                             (u_char) optarg[1] < 128)
 410                                 options.escape_char = (u_char) optarg[1] & 31;
 411                         else if (strlen(optarg) == 1)
 412                                 options.escape_char = (u_char) optarg[0];
 413                         else if (strcmp(optarg, "none") == 0)
 414                                 options.escape_char = SSH_ESCAPECHAR_NONE;
 415                         else {
 416                                 fprintf(stderr,
 417                                         gettext("Bad escape character '%s'.\n"),
 418                                     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,
 432                                                 gettext("Unknown cipher "
 433                                                         "type '%s'\n"),
 434                                             optarg);
 435                                         exit(1);
 436                                 }
 437                                 if (options.cipher == SSH_CIPHER_3DES)
 438                                         options.ciphers = "3des-cbc";
 439                                 else if (options.cipher == SSH_CIPHER_BLOWFISH)
 440                                         options.ciphers = "blowfish-cbc";
 441                                 else
 442                                         options.ciphers = (char *)-1;
 443                         }
 444                         break;
 445                 case 'm':
 446                         if (mac_valid(optarg))
 447                                 options.macs = xstrdup(optarg);
 448                         else {
 449                                 fprintf(stderr,
 450                                         gettext("Unknown mac type '%s'\n"),
 451                                     optarg);
 452                                 exit(1);
 453                         }
 454                         break;
 455                 case 'p':
 456                         options.port = a2port(optarg);
 457                         if (options.port == 0) {
 458                                 fprintf(stderr, gettext("Bad port '%s'\n"),
 459                                         optarg);
 460                                 exit(1);
 461                         }
 462                         break;
 463                 case 'l':
 464                         options.user = optarg;
 465                         break;
 466 
 467                 case 'L':
 468                         if (parse_forward(1, &fwd, optarg))
 469                                 add_local_forward(&options, &fwd);
 470                         else
 471                                 fatal("Bad local forwarding specification "
 472                                 "'%s'\n", optarg);
 473                         break;
 474 
 475                 case 'R':
 476                         if (parse_forward(1, &fwd, optarg))
 477                                 add_remote_forward(&options, &fwd);
 478                         else
 479                                 fatal("Bad remote forwarding specification "
 480                                     "'%s'\n", optarg);
 481                         break;
 482 
 483                 case 'D':
 484                         if (parse_forward(0, &fwd, optarg) == 0)
 485                                 fatal("Bad dynamic forwarding specification "
 486                                     "'%s'\n", optarg);
 487                         fwd.connect_host = "socks";
 488                         add_local_forward(&options, &fwd);
 489                         break;
 490 
 491                 case 'C':
 492                         options.compression = 1;
 493                         break;
 494                 case 'N':
 495                         no_shell_flag = 1;
 496                         no_tty_flag = 1;
 497                         break;
 498                 case 'T':
 499                         no_tty_flag = 1;
 500                         break;
 501                 case 'o':
 502                         dummy = 1;
 503                         if (process_config_line(&options, host ? host : "",
 504                             optarg, "command-line", 0, &dummy) != 0)
 505                                 exit(1);
 506                         break;
 507                 case 's':
 508                         subsystem_flag = 1;
 509                         break;
 510                 case 'b':
 511                         options.bind_address = optarg;
 512                         break;
 513                 case 'F':
 514                         config = optarg;
 515                         break;
 516                 default:
 517                         usage();
 518                 }
 519         }
 520 
 521         ac -= optind;
 522         av += optind;
 523 
 524         if (ac > 0 && !host && **av != '-') {
 525                 if (strchr(*av, '@')) {
 526                         p = xstrdup(*av);
 527                         cp = strchr(p, '@');
 528                         if (cp == NULL || cp == p)
 529                                 usage();
 530                         options.user = p;
 531                         *cp = '\0';
 532                         host = ++cp;
 533                 } else
 534                         host = *av;
 535                 ac--, av++;
 536                 if (ac > 0) {
 537                         optind = 0;
 538                         optreset = 1;
 539                         goto again;
 540                 }
 541         }
 542 
 543         /* Check that we got a host name. */
 544         if (!host)
 545                 usage();
 546 
 547         SSLeay_add_all_algorithms();
 548         ERR_load_crypto_strings();
 549         channel_set_af(IPv4or6);
 550 
 551         /* Initialize the command to execute on remote host. */
 552         buffer_init(&command);
 553 
 554         /*
 555          * Save the command to execute on the remote host in a buffer. There
 556          * is no limit on the length of the command, except by the maximum
 557          * packet size.  Also sets the tty flag if there is no command.
 558          */
 559         if (!ac) {
 560                 /* No command specified - execute shell on a tty. */
 561                 tty_flag = 1;
 562                 if (subsystem_flag) {
 563                         fprintf(stderr,
 564                                 gettext("You must specify a subsystem "
 565                                         "to invoke.\n"));
 566                         usage();
 567                 }
 568         } else {
 569                 /* A command has been specified.  Store it into the buffer. */
 570                 for (i = 0; i < ac; i++) {
 571                         if (i)
 572                                 buffer_append(&command, " ", 1);
 573                         buffer_append(&command, av[i], strlen(av[i]));
 574                 }
 575         }
 576 
 577         /* Cannot fork to background if no command. */
 578         if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag)
 579                 fatal("Cannot fork into background without a command to execute.");
 580 
 581         /* Allocate a tty by default if no command specified. */
 582         if (buffer_len(&command) == 0)
 583                 tty_flag = 1;
 584 
 585         /* Force no tty */
 586         if (no_tty_flag)
 587                 tty_flag = 0;
 588         /* Do not allocate a tty if stdin is not a tty. */
 589         if (!isatty(fileno(stdin)) && !force_tty_flag) {
 590                 if (tty_flag)
 591                         log("Pseudo-terminal will not be allocated because stdin is not a terminal.");
 592                 tty_flag = 0;
 593         }
 594 
 595         /*
 596          * Initialize "log" output.  Since we are the client all output
 597          * actually goes to stderr.
 598          */
 599         log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
 600             SYSLOG_FACILITY_USER, 1);
 601 
 602         /*
 603          * Read per-user configuration file.  Ignore the system wide config
 604          * file if the user specifies a config file on the command line.
 605          */
 606         if (config != NULL) {
 607                 if (!read_config_file(config, host, &options))
 608                         fatal("Can't open user config file %.100s: "
 609                             "%.100s", config, strerror(errno));
 610         } else  {
 611                 snprintf(buf, sizeof buf, "%.100s/%.100s", pw_dir,
 612                     _PATH_SSH_USER_CONFFILE);
 613                 (void)read_config_file(buf, host, &options);
 614 
 615                 /* Read systemwide configuration file after use config. */
 616                 (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, &options);
 617         }
 618 
 619         process_unknown_options(&options);
 620 
 621         /* Fill configuration defaults. */
 622         fill_default_options(&options);
 623 
 624         /* reinit */
 625         log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1);
 626 
 627         seed_rng();
 628 
 629         if (options.user == NULL)
 630                 options.user = xstrdup(pw_name);
 631 
 632         if (options.hostname != NULL)
 633                 host = options.hostname;
 634 
 635         /* Disable rhosts authentication if not running as root. */
 636 #ifdef HAVE_CYGWIN
 637         /* Ignore uid if running under Windows */
 638         if (!options.use_privileged_port) {
 639 #else
 640         if (original_effective_uid != 0 || !options.use_privileged_port) {
 641 #endif
 642                 debug("Rhosts Authentication disabled, "
 643                     "originating port will not be trusted.");
 644                 options.rhosts_authentication = 0;
 645         }
 646         /* Open a connection to the remote host. */
 647 
 648         /* XXX OpenSSH has deprecated UseRsh */
 649         if (options.use_rsh) {
 650                 seteuid(original_real_uid);
 651                 setuid(original_real_uid);
 652                 rsh_connect(host, options.user, &command);
 653                 fatal("rsh_connect returned");
 654         }
 655 
 656         if (ssh_connect(host, &hostaddr, options.port, IPv4or6,
 657             options.connection_attempts,
 658 #ifdef HAVE_CYGWIN
 659             options.use_privileged_port,
 660 #else
 661             original_effective_uid == 0 && options.use_privileged_port,
 662 #endif
 663             options.proxy_command) != 0) {
 664                 /* XXX OpenSSH has deprecated FallbackToRsh */
 665                 if (options.fallback_to_rsh) {
 666                         seteuid(original_real_uid);
 667                         setuid(original_real_uid);
 668                         rsh_connect(host, options.user, &command);
 669                         fatal("rsh_connect returned");
 670                 }
 671                 exit(1);
 672         }
 673 
 674         /*
 675          * If we successfully made the connection, load the host private key
 676          * in case we will need it later for combined rsa-rhosts
 677          * authentication. This must be done before releasing extra
 678          * privileges, because the file is only readable by root.
 679          * If we cannot access the private keys, load the public keys
 680          * instead and try to execute the ssh-keysign helper instead.
 681          */
 682         sensitive_data.nkeys = 0;
 683         sensitive_data.keys = NULL;
 684         sensitive_data.external_keysign = 0;
 685         if (options.rhosts_rsa_authentication ||
 686             options.hostbased_authentication) {
 687                 sensitive_data.nkeys = 3;
 688                 sensitive_data.keys = xmalloc(sensitive_data.nkeys *
 689                     sizeof(Key));
 690 
 691                 PRIV_START;
 692                 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
 693                     _PATH_HOST_KEY_FILE, "", NULL);
 694                 sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
 695                     _PATH_HOST_DSA_KEY_FILE, "", NULL);
 696                 sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
 697                     _PATH_HOST_RSA_KEY_FILE, "", NULL);
 698                 PRIV_END;
 699 
 700                 if (options.hostbased_authentication == 1 &&
 701                     sensitive_data.keys[0] == NULL &&
 702                     sensitive_data.keys[1] == NULL &&
 703                     sensitive_data.keys[2] == NULL) {
 704                         sensitive_data.keys[1] = key_load_public(
 705                             _PATH_HOST_DSA_KEY_FILE, NULL);
 706                         sensitive_data.keys[2] = key_load_public(
 707                             _PATH_HOST_RSA_KEY_FILE, NULL);
 708                         sensitive_data.external_keysign = 1;
 709                 }
 710         }
 711         /*
 712          * Get rid of any extra privileges that we may have.  We will no
 713          * longer need them.  Also, extra privileges could make it very hard
 714          * to read identity files and other non-world-readable files from the
 715          * user's home directory if it happens to be on a NFS volume where
 716          * root is mapped to nobody.
 717          */
 718         seteuid(original_real_uid);
 719         setuid(original_real_uid);
 720 
 721         /*
 722          * Now that we are back to our own permissions, create ~/.ssh
 723          * directory if it doesn\'t already exist.
 724          */
 725         snprintf(buf, sizeof buf, "%.100s%s%.100s", pw_dir,
 726             strcmp(pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
 727         xfree(pw_dir);
 728         if (stat(buf, &st) < 0)
 729                 if (mkdir(buf, 0700) < 0)
 730                         error("Could not create directory '%.200s'.", buf);
 731 
 732         /* load options.identity_files */
 733         load_public_identity_files();
 734 
 735         /* Expand ~ in known host file names. */
 736         /* XXX mem-leaks: */
 737         options.system_hostfile =
 738             tilde_expand_filename(options.system_hostfile, original_real_uid);
 739         options.user_hostfile =
 740             tilde_expand_filename(options.user_hostfile, original_real_uid);
 741         options.system_hostfile2 =
 742             tilde_expand_filename(options.system_hostfile2, original_real_uid);
 743         options.user_hostfile2 =
 744             tilde_expand_filename(options.user_hostfile2, original_real_uid);
 745 
 746         signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
 747 
 748         /* Log into the remote system.  This never returns if the login fails. */
 749         ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw_name);
 750         xfree(pw_name);
 751 
 752         /* We no longer need the private host keys.  Clear them now. */
 753         if (sensitive_data.nkeys != 0) {
 754                 for (i = 0; i < sensitive_data.nkeys; i++) {
 755                         if (sensitive_data.keys[i] != NULL) {
 756                                 /* Destroys contents safely */
 757                                 debug3("clear hostkey %d", i);
 758                                 key_free(sensitive_data.keys[i]);
 759                                 sensitive_data.keys[i] = NULL;
 760                         }
 761                 }
 762                 xfree(sensitive_data.keys);
 763         }
 764         for (i = 0; i < options.num_identity_files; i++) {
 765                 if (options.identity_files[i]) {
 766                         xfree(options.identity_files[i]);
 767                         options.identity_files[i] = NULL;
 768                 }
 769                 if (options.identity_keys[i]) {
 770                         key_free(options.identity_keys[i]);
 771                         options.identity_keys[i] = NULL;
 772                 }
 773         }
 774 
 775         exit_status = compat20 ? ssh_session2() : ssh_session();
 776         packet_close();
 777 
 778         /*
 779          * Send SIGHUP to proxy command if used. We don't wait() in 
 780          * case it hangs and instead rely on init to reap the child
 781          */
 782         if (proxy_command_pid > 1)
 783                 kill(proxy_command_pid, SIGHUP);
 784 
 785         return exit_status;
 786 }
 787 
 788 static void
 789 ssh_init_forwarding(void)
 790 {
 791         int success = 0;
 792         int i;
 793 
 794         /* Initiate local TCP/IP port forwardings. */
 795         for (i = 0; i < options.num_local_forwards; i++) {
 796                 debug("Local connections to %.200s:%d forwarded to remote "
 797                     "address %.200s:%d",
 798                     (options.local_forwards[i].listen_host == NULL) ?
 799                     (options.gateway_ports ? "*" : "LOCALHOST") :
 800                     options.local_forwards[i].listen_host,
 801                     options.local_forwards[i].listen_port,
 802                     options.local_forwards[i].connect_host,
 803                     options.local_forwards[i].connect_port);
 804                 success += channel_setup_local_fwd_listener(
 805                     options.local_forwards[i].listen_host,
 806                     options.local_forwards[i].listen_port,
 807                     options.local_forwards[i].connect_host,
 808                     options.local_forwards[i].connect_port,
 809                     options.gateway_ports);
 810         }
 811         if (i > 0 && success == 0)
 812                 error("Could not request local forwarding.");
 813 
 814         /* Initiate remote TCP/IP port forwardings. */
 815         for (i = 0; i < options.num_remote_forwards; i++) {
 816                 debug("Remote connections from %.200s:%d forwarded to "
 817                     "local address %.200s:%d",
 818                     (options.remote_forwards[i].listen_host == NULL) ?
 819                     "LOCALHOST" : options.remote_forwards[i].listen_host,
 820                     options.remote_forwards[i].listen_port,
 821                     options.remote_forwards[i].connect_host,
 822                     options.remote_forwards[i].connect_port);
 823                 if (channel_request_remote_forwarding(
 824                     options.remote_forwards[i].listen_host,
 825                     options.remote_forwards[i].listen_port,
 826                     options.remote_forwards[i].connect_host,
 827                     options.remote_forwards[i].connect_port) < 0) {
 828                         log("Warning: Could not request remote forwarding.");
 829                     }
 830         }
 831 }
 832 
 833 static void
 834 check_agent_present(void)
 835 {
 836         if (options.forward_agent) {
 837                 /* Clear agent forwarding if we don't have an agent. */
 838                 if (!ssh_agent_present())
 839                         options.forward_agent = 0;
 840         }
 841 }
 842 
 843 static int
 844 ssh_session(void)
 845 {
 846         int type;
 847         int interactive = 0;
 848         int have_tty = 0;
 849         struct winsize ws;
 850         char *cp;
 851         const char *display;
 852 
 853         /* Enable compression if requested. */
 854         if (options.compression) {
 855                 debug("Requesting compression at level %d.", options.compression_level);
 856 
 857                 if (options.compression_level < 1 || options.compression_level > 9)
 858                         fatal("Compression level must be from 1 (fast) to 9 (slow, best).");
 859 
 860                 /* Send the request. */
 861                 packet_start(SSH_CMSG_REQUEST_COMPRESSION);
 862                 packet_put_int(options.compression_level);
 863                 packet_send();
 864                 packet_write_wait();
 865                 type = packet_read();
 866                 if (type == SSH_SMSG_SUCCESS)
 867                         packet_start_compression(options.compression_level);
 868                 else if (type == SSH_SMSG_FAILURE)
 869                         log("Warning: Remote host refused compression.");
 870                 else
 871                         packet_disconnect("Protocol error waiting for compression response.");
 872         }
 873         /* Allocate a pseudo tty if appropriate. */
 874         if (tty_flag) {
 875                 debug("Requesting pty.");
 876 
 877                 /* Start the packet. */
 878                 packet_start(SSH_CMSG_REQUEST_PTY);
 879 
 880                 /* Store TERM in the packet.  There is no limit on the
 881                    length of the string. */
 882                 cp = getenv("TERM");
 883                 if (!cp)
 884                         cp = "";
 885                 packet_put_cstring(cp);
 886 
 887                 /* Store window size in the packet. */
 888                 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
 889                         memset(&ws, 0, sizeof(ws));
 890                 packet_put_int(ws.ws_row);
 891                 packet_put_int(ws.ws_col);
 892                 packet_put_int(ws.ws_xpixel);
 893                 packet_put_int(ws.ws_ypixel);
 894 
 895                 /* Store tty modes in the packet. */
 896                 tty_make_modes(fileno(stdin), NULL);
 897 
 898                 /* Send the packet, and wait for it to leave. */
 899                 packet_send();
 900                 packet_write_wait();
 901 
 902                 /* Read response from the server. */
 903                 type = packet_read();
 904                 if (type == SSH_SMSG_SUCCESS) {
 905                         interactive = 1;
 906                         have_tty = 1;
 907                 } else if (type == SSH_SMSG_FAILURE)
 908                         log("Warning: Remote host failed or refused to allocate a pseudo tty.");
 909                 else
 910                         packet_disconnect("Protocol error waiting for pty request response.");
 911         }
 912         /* Request X11 forwarding if enabled and DISPLAY is set. */
 913         display = getenv("DISPLAY");
 914         if (options.forward_x11 && display != NULL) {
 915                 char *proto, *data;
 916                 /* Get reasonable local authentication information. */
 917                 client_x11_get_proto(display, options.xauth_location,
 918                     options.forward_x11_trusted, &proto, &data);
 919                 /* Request forwarding with authentication spoofing. */
 920                 debug("Requesting X11 forwarding with authentication spoofing.");
 921                 x11_request_forwarding_with_spoofing(0, display, proto, data);
 922 
 923                 /* Read response from the server. */
 924                 type = packet_read();
 925                 if (type == SSH_SMSG_SUCCESS) {
 926                         interactive = 1;
 927                 } else if (type == SSH_SMSG_FAILURE) {
 928                         log("Warning: Remote host denied X11 forwarding.");
 929                 } else {
 930                         packet_disconnect("Protocol error waiting for X11 forwarding");
 931                 }
 932         }
 933         /* Tell the packet module whether this is an interactive session. */
 934         packet_set_interactive(interactive);
 935 
 936         /* Request authentication agent forwarding if appropriate. */
 937         check_agent_present();
 938 
 939         if (options.forward_agent) {
 940                 debug("Requesting authentication agent forwarding.");
 941                 auth_request_forwarding();
 942 
 943                 /* Read response from the server. */
 944                 type = packet_read();
 945                 packet_check_eom();
 946                 if (type != SSH_SMSG_SUCCESS)
 947                         log("Warning: Remote host denied authentication agent forwarding.");
 948         }
 949 
 950         /* Initiate port forwardings. */
 951         ssh_init_forwarding();
 952 
 953         /* If requested, let ssh continue in the background. */
 954         if (fork_after_authentication_flag)
 955                 if (daemon(1, 1) < 0)
 956                         fatal("daemon() failed: %.200s", strerror(errno));
 957 
 958         /*
 959          * If a command was specified on the command line, execute the
 960          * command now. Otherwise request the server to start a shell.
 961          */
 962         if (buffer_len(&command) > 0) {
 963                 int len = buffer_len(&command);
 964                 if (len > 900)
 965                         len = 900;
 966                 debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command));
 967                 packet_start(SSH_CMSG_EXEC_CMD);
 968                 packet_put_string(buffer_ptr(&command), buffer_len(&command));
 969                 packet_send();
 970                 packet_write_wait();
 971         } else {
 972                 debug("Requesting shell.");
 973                 packet_start(SSH_CMSG_EXEC_SHELL);
 974                 packet_send();
 975                 packet_write_wait();
 976         }
 977 
 978         /* Enter the interactive session. */
 979         return client_loop(have_tty, tty_flag ?
 980             options.escape_char : SSH_ESCAPECHAR_NONE, 0);
 981 }
 982 
 983 static void
 984 client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
 985 {
 986         int id, len;
 987 
 988         id = packet_get_int();
 989         len = buffer_len(&command);
 990         if (len > 900)
 991                 len = 900;
 992         packet_check_eom();
 993         if (type == SSH2_MSG_CHANNEL_FAILURE)
 994                 fatal("Request for subsystem '%.*s' failed on channel %d",
 995                     len, (u_char *)buffer_ptr(&command), id);
 996 }
 997 
 998 void
 999 client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
1000 {
1001         int i;
1002 
1003         i = client_global_request_id++;
1004         if (i >= options.num_remote_forwards)
1005                 return;
1006         debug("remote forward %s for: listen %d, connect %s:%d",
1007             type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1008             options.remote_forwards[i].listen_port,
1009             options.remote_forwards[i].connect_host,
1010             options.remote_forwards[i].connect_port);
1011         if (type == SSH2_MSG_REQUEST_FAILURE)
1012                 log("Warning: remote port forwarding failed for listen port %d",
1013                     options.remote_forwards[i].listen_port);
1014 }
1015 
1016 static
1017 void
1018 ssh_session2_setlocale(int id)
1019 {
1020         char *loc;
1021 
1022 #define remote_setlocale(envvar) \
1023         if ((loc = getenv(envvar)) != NULL) {\
1024                 channel_request_start(id, "env", 0);\
1025                 debug2("Sent request for environment variable %s=%s", envvar, \
1026                         loc); \
1027                 packet_put_cstring(envvar);\
1028                 packet_put_cstring(loc);\
1029                 packet_send();\
1030         }
1031 
1032         remote_setlocale("LANG")
1033 
1034         remote_setlocale("LC_CTYPE")
1035         remote_setlocale("LC_COLLATE")
1036         remote_setlocale("LC_TIME")
1037         remote_setlocale("LC_NUMERIC")
1038         remote_setlocale("LC_MONETARY")
1039         remote_setlocale("LC_MESSAGES")
1040 
1041         remote_setlocale("LC_ALL")
1042 }
1043 
1044 /* request pty/x11/agent/tcpfwd/shell for channel */
1045 static void
1046 ssh_session2_setup(int id, void *arg)
1047 {
1048         int len;
1049         const char *display;
1050         int interactive = 0;
1051         struct termios tio;
1052 
1053         debug("ssh_session2_setup: id %d", id);
1054 
1055         ssh_session2_setlocale(id);
1056 
1057         if (tty_flag) {
1058                 struct winsize ws;
1059                 char *cp;
1060                 cp = getenv("TERM");
1061                 if (!cp)
1062                         cp = "";
1063                 /* Store window size in the packet. */
1064                 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
1065                         memset(&ws, 0, sizeof(ws));
1066 
1067                 channel_request_start(id, "pty-req", 0);
1068                 packet_put_cstring(cp);
1069                 packet_put_int(ws.ws_col);
1070                 packet_put_int(ws.ws_row);
1071                 packet_put_int(ws.ws_xpixel);
1072                 packet_put_int(ws.ws_ypixel);
1073                 tio = get_saved_tio();
1074                 tty_make_modes(/*ignored*/ 0, &tio);
1075                 packet_send();
1076                 interactive = 1;
1077                 /* XXX wait for reply */
1078         }
1079 
1080         display = getenv("DISPLAY");
1081         if (options.forward_x11 && display != NULL) {
1082                 char *proto, *data;
1083                 /* Get reasonable local authentication information. */
1084                 client_x11_get_proto(display, options.xauth_location,
1085                     options.forward_x11_trusted, &proto, &data);
1086                 /* Request forwarding with authentication spoofing. */
1087                 debug("Requesting X11 forwarding with authentication spoofing.");
1088                 x11_request_forwarding_with_spoofing(id, display, proto, data);
1089                 interactive = 1;
1090                 /* XXX wait for reply */
1091         }
1092 
1093         check_agent_present();
1094         if (options.forward_agent) {
1095                 debug("Requesting authentication agent forwarding.");
1096                 channel_request_start(id, "auth-agent-req@openssh.com", 0);
1097                 packet_send();
1098         }
1099 
1100         len = buffer_len(&command);
1101         if (len > 0) {
1102                 if (len > 900)
1103                         len = 900;
1104                 if (subsystem_flag) {
1105                         debug("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command));
1106                         channel_request_start(id, "subsystem", /*want reply*/ 1);
1107                         /* register callback for reply */
1108                         /* XXX we assume that client_loop has already been called */
1109                         dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply);
1110                         dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply);
1111                 } else {
1112                         debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command));
1113                         channel_request_start(id, "exec", 0);
1114                 }
1115                 packet_put_string(buffer_ptr(&command), buffer_len(&command));
1116                 packet_send();
1117         } else {
1118                 channel_request_start(id, "shell", 0);
1119                 packet_send();
1120         }
1121 
1122         packet_set_interactive(interactive);
1123 }
1124 
1125 /* open new channel for a session */
1126 static int
1127 ssh_session2_open(void)
1128 {
1129         Channel *c;
1130         int window, packetmax, in, out, err;
1131 
1132         if (stdin_null_flag) {
1133                 in = open(_PATH_DEVNULL, O_RDONLY);
1134         } else {
1135                 in = dup(STDIN_FILENO);
1136         }
1137         out = dup(STDOUT_FILENO);
1138         err = dup(STDERR_FILENO);
1139 
1140         if (in < 0 || out < 0 || err < 0)
1141                 fatal("dup() in/out/err failed");
1142 
1143         /* enable nonblocking unless tty */
1144         if (!isatty(in))
1145                 set_nonblock(in);
1146         if (!isatty(out))
1147                 set_nonblock(out);
1148         if (!isatty(err))
1149                 set_nonblock(err);
1150 
1151         window = CHAN_SES_WINDOW_DEFAULT;
1152         packetmax = CHAN_SES_PACKET_DEFAULT;
1153         if (tty_flag) {
1154                 window >>= 1;
1155                 packetmax >>= 1;
1156         }
1157         c = channel_new(
1158             "session", SSH_CHANNEL_OPENING, in, out, err,
1159             window, packetmax, CHAN_EXTENDED_WRITE,
1160             xstrdup("client-session"), /*nonblock*/0);
1161 
1162         debug3("ssh_session2_open: channel_new: %d", c->self);
1163 
1164         channel_send_open(c->self);
1165         if (!no_shell_flag)
1166                 channel_register_confirm(c->self, ssh_session2_setup);
1167 
1168         return c->self;
1169 }
1170 
1171 static int
1172 ssh_session2(void)
1173 {
1174         int id = -1;
1175 
1176         /* XXX should be pre-session */
1177         ssh_init_forwarding();
1178 
1179         if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1180                 id = ssh_session2_open();
1181 
1182         /* If requested, let ssh continue in the background. */
1183         if (fork_after_authentication_flag)
1184                 client_daemonize();
1185 
1186         return (client_loop(tty_flag, tty_flag ?
1187             options.escape_char : SSH_ESCAPECHAR_NONE, id));
1188 }
1189 
1190 static void
1191 load_public_identity_files(void)
1192 {
1193         char *filename;
1194         int i = 0;
1195         Key *public;
1196 
1197         for (; i < options.num_identity_files; i++) {
1198                 filename = tilde_expand_filename(options.identity_files[i],
1199                     original_real_uid);
1200                 public = key_load_public(filename, NULL);
1201                 debug("identity file %s type %d", filename,
1202                     public ? public->type : -1);
1203                 xfree(options.identity_files[i]);
1204                 options.identity_files[i] = filename;
1205                 options.identity_keys[i] = public;
1206         }
1207 }
1208 
1209 /*
1210  * Connects to the given host using rsh(or prints an error message and exits
1211  * if rsh is not available).  This function never returns.
1212  */
1213 static void
1214 rsh_connect(char *host, char *user, Buffer * command)
1215 {
1216         char *args[10];
1217         int i;
1218 
1219         log("Using rsh.  WARNING: Connection will not be encrypted.");
1220         /* Build argument list for rsh. */
1221         i = 0;
1222         args[i++] = _PATH_RSH;
1223         /* host may have to come after user on some systems */
1224         args[i++] = host;
1225         if (user) {
1226                 args[i++] = "-l";
1227                 args[i++] = user;
1228         }
1229         if (buffer_len(command) > 0) {
1230                 buffer_append(command, "\0", 1);
1231                 args[i++] = buffer_ptr(command);
1232         }
1233         args[i++] = NULL;
1234         if (debug_flag) {
1235                 for (i = 0; args[i]; i++) {
1236                         if (i != 0)
1237                                 (void) fprintf(stderr, " ");
1238                         (void) fprintf(stderr, "%s", args[i]);
1239                 }
1240                 (void) fprintf(stderr, "\n");
1241         }
1242         (void) execv(_PATH_RSH, args);
1243         perror(_PATH_RSH);
1244         exit(1);
1245 }