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  * Code to connect to a remote host, and to perform the client side of the
   6  * login (authentication) dialog.
   7  *
   8  * As far as I am concerned, the code I have written for this software
   9  * can be used freely for any purpose.  Any derived versions of this
  10  * software must be clearly marked as such, and if the derived work is
  11  * incompatible with the protocol description in the RFC file, it must be
  12  * called by a name other than "ssh" or "Secure Shell".
  13  */
  14 /*
  15  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  16  * Use is subject to license terms.
  17  *
  18  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  19  */
  20 
  21 #include "includes.h"
  22 RCSID("$OpenBSD: sshconnect.c,v 1.135 2002/09/19 01:58:18 djm Exp $");
  23 
  24 #include <openssl/bn.h>
  25 
  26 #include "ssh.h"
  27 #include "xmalloc.h"
  28 #include "rsa.h"
  29 #include "buffer.h"
  30 #include "packet.h"
  31 #include "uidswap.h"
  32 #include "compat.h"
  33 #include "key.h"
  34 #include "sshconnect.h"
  35 #include "hostfile.h"
  36 #include "log.h"
  37 #include "readconf.h"
  38 #include "atomicio.h"
  39 #include "misc.h"
  40 #include "readpass.h"
  41 #include <langinfo.h>
  42 #include <regex.h>
  43 #include <err.h>
  44 #include "engine.h"
  45 
  46 char *client_version_string = NULL;
  47 char *server_version_string = NULL;
  48 
  49 /* import */
  50 extern Options options;
  51 extern char *__progname;
  52 extern uid_t original_real_uid;
  53 extern uid_t original_effective_uid;
  54 extern pid_t proxy_command_pid;
  55 extern ENGINE *e;
  56 
  57 #ifndef INET6_ADDRSTRLEN                /* for non IPv6 machines */
  58 #define INET6_ADDRSTRLEN 46
  59 #endif
  60 
  61 static int show_other_keys(const char *, Key *);
  62 
  63 /*
  64  * Connect to the given ssh server using a proxy command.
  65  */
  66 static int
  67 ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
  68 {
  69         Buffer command;
  70         const char *cp;
  71         char *command_string;
  72         int pin[2], pout[2];
  73         pid_t pid;
  74         char strport[NI_MAXSERV];
  75 
  76         /* Convert the port number into a string. */
  77         snprintf(strport, sizeof strport, "%hu", port);
  78 
  79         /*
  80          * Build the final command string in the buffer by making the
  81          * appropriate substitutions to the given proxy command.
  82          *
  83          * Use "exec" to avoid "sh -c" processes on some platforms 
  84          * (e.g. Solaris)
  85          */
  86         buffer_init(&command);
  87 
  88 #define EXECLEN (sizeof ("exec") - 1)
  89         for (cp = proxy_command; *cp && isspace(*cp) ; cp++)
  90                 ;
  91         if (strncmp(cp, "exec", EXECLEN) != 0 ||
  92             (strlen(cp) >= EXECLEN && !isspace(*(cp + EXECLEN))))
  93                 buffer_append(&command, "exec ", EXECLEN + 1);
  94 #undef EXECLEN
  95 
  96         for (cp = proxy_command; *cp; cp++) {
  97                 if (cp[0] == '%' && cp[1] == '%') {
  98                         buffer_append(&command, "%", 1);
  99                         cp++;
 100                         continue;
 101                 }
 102                 if (cp[0] == '%' && cp[1] == 'h') {
 103                         buffer_append(&command, host, strlen(host));
 104                         cp++;
 105                         continue;
 106                 }
 107                 if (cp[0] == '%' && cp[1] == 'p') {
 108                         buffer_append(&command, strport, strlen(strport));
 109                         cp++;
 110                         continue;
 111                 }
 112                 buffer_append(&command, cp, 1);
 113         }
 114         buffer_append(&command, "\0", 1);
 115 
 116         /* Get the final command string. */
 117         command_string = buffer_ptr(&command);
 118 
 119         /* Create pipes for communicating with the proxy. */
 120         if (pipe(pin) < 0 || pipe(pout) < 0)
 121                 fatal("Could not create pipes to communicate with the proxy: %.100s",
 122                     strerror(errno));
 123 
 124         debug("Executing proxy command: %.500s", command_string);
 125 
 126         /* Fork and execute the proxy command. */
 127         if ((pid = fork()) == 0) {
 128                 char *argv[10];
 129 
 130                 /* Child.  Permanently give up superuser privileges. */
 131                 seteuid(original_real_uid);
 132                 setuid(original_real_uid);
 133 
 134                 /* Redirect stdin and stdout. */
 135                 close(pin[1]);
 136                 if (pin[0] != 0) {
 137                         if (dup2(pin[0], 0) < 0)
 138                                 perror("dup2 stdin");
 139                         close(pin[0]);
 140                 }
 141                 close(pout[0]);
 142                 if (dup2(pout[1], 1) < 0)
 143                         perror("dup2 stdout");
 144                 /* Cannot be 1 because pin allocated two descriptors. */
 145                 close(pout[1]);
 146 
 147                 /* Stderr is left as it is so that error messages get
 148                    printed on the user's terminal. */
 149                 argv[0] = _PATH_BSHELL;
 150                 argv[1] = "-c";
 151                 argv[2] = command_string;
 152                 argv[3] = NULL;
 153 
 154                 /* Execute the proxy command.  Note that we gave up any
 155                    extra privileges above. */
 156                 execv(argv[0], argv);
 157                 perror(argv[0]);
 158                 exit(1);
 159         }
 160         /* Parent. */
 161         if (pid < 0)
 162                 fatal("fork failed: %.100s", strerror(errno));
 163         else
 164                 proxy_command_pid = pid; /* save pid to clean up later */
 165 
 166         /* Close child side of the descriptors. */
 167         close(pin[0]);
 168         close(pout[1]);
 169 
 170         /* Free the command name. */
 171         buffer_free(&command);
 172 
 173         /* Set the connection file descriptors. */
 174         packet_set_connection(pout[0], pin[1]);
 175 
 176         /* Indicate OK return */
 177         return 0;
 178 }
 179 
 180 /*
 181  * Creates a (possibly privileged) socket for use as the ssh connection.
 182  */
 183 static int
 184 ssh_create_socket(int privileged, int family)
 185 {
 186         int sock, gaierr;
 187         struct addrinfo hints, *res;
 188 
 189         /*
 190          * If we are running as root and want to connect to a privileged
 191          * port, bind our own socket to a privileged port.
 192          */
 193         if (privileged) {
 194                 int p = IPPORT_RESERVED - 1;
 195                 PRIV_START;
 196                 sock = rresvport_af(&p, family);
 197                 PRIV_END;
 198                 if (sock < 0)
 199                         error("rresvport: af=%d %.100s", family, strerror(errno));
 200                 else
 201                         debug("Allocated local port %d.", p);
 202                 return sock;
 203         }
 204         sock = socket(family, SOCK_STREAM, 0);
 205         if (sock < 0)
 206                 error("socket: %.100s", strerror(errno));
 207 
 208         /* Bind the socket to an alternative local IP address */
 209         if (options.bind_address == NULL)
 210                 return sock;
 211 
 212         memset(&hints, 0, sizeof(hints));
 213         hints.ai_family = family;
 214         hints.ai_socktype = SOCK_STREAM;
 215         hints.ai_flags = AI_PASSIVE;
 216         gaierr = getaddrinfo(options.bind_address, "0", &hints, &res);
 217         if (gaierr) {
 218                 error("getaddrinfo: %s: %s", options.bind_address,
 219                     gai_strerror(gaierr));
 220                 close(sock);
 221                 return -1;
 222         }
 223         if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
 224                 error("bind: %s: %s", options.bind_address, strerror(errno));
 225                 close(sock);
 226                 freeaddrinfo(res);
 227                 return -1;
 228         }
 229         freeaddrinfo(res);
 230         return sock;
 231 }
 232 
 233 /*
 234  * Connect with timeout. Implements ConnectTimeout option.
 235  */
 236 static int
 237 timeout_connect(int sockfd, const struct sockaddr *serv_addr,
 238     socklen_t addrlen, int timeout)
 239 {
 240         fd_set *fdset;
 241         struct timeval tv;
 242         socklen_t optlen;
 243         int optval, rc, result = -1;
 244 
 245         if (timeout <= 0)
 246                 return (connect(sockfd, serv_addr, addrlen));
 247 
 248         set_nonblock(sockfd);
 249         rc = connect(sockfd, serv_addr, addrlen);
 250         if (rc == 0) {
 251                 unset_nonblock(sockfd);
 252                 return (0);
 253         }
 254         if (errno != EINPROGRESS)
 255                 return (-1);
 256 
 257         fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
 258             sizeof(fd_mask));
 259         FD_SET(sockfd, fdset);
 260         tv.tv_sec = timeout;
 261         tv.tv_usec = 0;
 262 
 263         for (;;) {
 264                 rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
 265                 if (rc != -1 || errno != EINTR)
 266                         break;
 267         }
 268 
 269         switch (rc) {
 270         case 0:
 271                 /* Timed out */
 272                 errno = ETIMEDOUT;
 273                 break;
 274         case -1:
 275                 /* Select error */
 276                 debug("select: %s", strerror(errno));
 277                 break;
 278         case 1:
 279                 /* Completed or failed */
 280                 optval = 0;
 281                 optlen = sizeof(optval);
 282                 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
 283                     &optlen) == -1) {
 284                         debug("getsockopt: %s", strerror(errno));
 285                         break;
 286                 }
 287                 if (optval != 0) {
 288                         errno = optval;
 289                         break;
 290                 }
 291                 result = 0;
 292                 unset_nonblock(sockfd);
 293                 break;
 294         default:
 295                 /* Should not occur */
 296                 fatal("Bogus return (%d) from select()", rc);
 297         }
 298 
 299         xfree(fdset);
 300         return (result);
 301 }
 302 
 303 /*
 304  * Opens a TCP/IP connection to the remote server on the given host.
 305  * The address of the remote host will be returned in hostaddr.
 306  * If port is 0, the default port will be used.  If needpriv is true,
 307  * a privileged port will be allocated to make the connection.
 308  * This requires super-user privileges if needpriv is true.
 309  * Connection_attempts specifies the maximum number of tries (one per
 310  * second).  If proxy_command is non-NULL, it specifies the command (with %h
 311  * and %p substituted for host and port, respectively) to use to contact
 312  * the daemon.
 313  * Return values:
 314  *    0 for OK
 315  *    ECONNREFUSED if we got a "Connection Refused" by the peer on any address
 316  *    ECONNABORTED if we failed without a "Connection refused"
 317  * Suitable error messages for the connection failure will already have been
 318  * printed.
 319  */
 320 int
 321 ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
 322     ushort_t port, int family, int connection_attempts,
 323     int needpriv, const char *proxy_command)
 324 {
 325         int gaierr;
 326         int on = 1;
 327         int sock = -1, attempt;
 328         char ntop[NI_MAXHOST], strport[NI_MAXSERV];
 329         struct addrinfo hints, *ai, *aitop;
 330         struct servent *sp;
 331         /*
 332          * Did we get only other errors than "Connection refused" (which
 333          * should block fallback to rsh and similar), or did we get at least
 334          * one "Connection refused"?
 335          */
 336         int full_failure = 1;
 337 
 338         debug("ssh_connect: needpriv %d", needpriv);
 339 
 340         /* Get default port if port has not been set. */
 341         if (port == 0) {
 342                 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
 343                 if (sp)
 344                         port = ntohs(sp->s_port);
 345                 else
 346                         port = SSH_DEFAULT_PORT;
 347         }
 348         /* If a proxy command is given, connect using it. */
 349         if (proxy_command != NULL)
 350                 return ssh_proxy_connect(host, port, proxy_command);
 351 
 352         /* No proxy command. */
 353 
 354         memset(&hints, 0, sizeof(hints));
 355         hints.ai_family = family;
 356         hints.ai_socktype = SOCK_STREAM;
 357         snprintf(strport, sizeof strport, "%u", port);
 358         if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
 359                 fatal("%s: %.100s: %s", __progname, host,
 360                     gai_strerror(gaierr));
 361 
 362         /*
 363          * Try to connect several times.  On some machines, the first time
 364          * will sometimes fail.  In general socket code appears to behave
 365          * quite magically on many machines.
 366                  */
 367         for (attempt = 0; ;) {
 368                 if (attempt > 0)
 369                         debug("Trying again...");
 370 
 371                 /* Loop through addresses for this host, and try each one in
 372                    sequence until the connection succeeds. */
 373                 for (ai = aitop; ai; ai = ai->ai_next) {
 374                         if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
 375                                 continue;
 376                         if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
 377                             ntop, sizeof(ntop), strport, sizeof(strport),
 378                             NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
 379                                 error("ssh_connect: getnameinfo failed");
 380                                 continue;
 381                         }
 382                         debug("Connecting to %.200s [%.100s] port %s.",
 383                                 host, ntop, strport);
 384 
 385                         /* Create a socket for connecting. */
 386                         sock = ssh_create_socket(needpriv, ai->ai_family);
 387                         if (sock < 0)
 388                                 /* Any error is already output */
 389                                 continue;
 390 
 391                         if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
 392                             options.connection_timeout) >= 0) {
 393                                 /* Successful connection. */
 394                                 memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
 395                                 break;
 396                         } else {
 397                                 if (errno == ECONNREFUSED)
 398                                         full_failure = 0;
 399                                 debug("connect to address %s port %s: %s",
 400                                     ntop, strport, strerror(errno));
 401                                 /*
 402                                  * Close the failed socket; there appear to
 403                                  * be some problems when reusing a socket for
 404                                  * which connect() has already returned an
 405                                  * error.
 406                                  */
 407                                 close(sock);
 408                         }
 409                 }
 410                 if (ai)
 411                         break;  /* Successful connection. */
 412 
 413                 attempt++;
 414                 if (attempt >= connection_attempts)
 415                         break;
 416                 /* Sleep a moment before retrying. */
 417                 sleep(1);
 418         }
 419 
 420         freeaddrinfo(aitop);
 421 
 422         /* Return failure if we didn't get a successful connection. */
 423         if (attempt >= connection_attempts) {
 424                 log("ssh: connect to host %s port %s: %s",
 425                     host, strport, strerror(errno));
 426                 return full_failure ? ECONNABORTED : ECONNREFUSED;
 427         }
 428 
 429         debug("Connection established.");
 430 
 431         /* Set keepalives if requested. */
 432         if (options.keepalives &&
 433             setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
 434             sizeof(on)) < 0)
 435                 debug2("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
 436 
 437         /* Set the connection. */
 438         packet_set_connection(sock, sock);
 439 
 440         return 0;
 441 }
 442 
 443 /*
 444  * Waits for the server identification string, and sends our own
 445  * identification string.
 446  */
 447 static void
 448 ssh_exchange_identification(void)
 449 {
 450         char buf[256], remote_version[256];     /* must be same size! */
 451         int remote_major, remote_minor, i, mismatch;
 452         int connection_in = packet_get_connection_in();
 453         int connection_out = packet_get_connection_out();
 454         int minor1 = PROTOCOL_MINOR_1;
 455 
 456         /* Read other side\'s version identification. */
 457         for (;;) {
 458                 for (i = 0; i < sizeof(buf) - 1; i++) {
 459                         int len = atomicio(read, connection_in, &buf[i], 1);
 460                         if (len < 0)
 461                                 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
 462                         if (len != 1)
 463                                 fatal("ssh_exchange_identification: Connection closed by remote host");
 464                         if (buf[i] == '\r') {
 465                                 buf[i] = '\n';
 466                                 buf[i + 1] = 0;
 467                                 continue;               /**XXX wait for \n */
 468                         }
 469                         if (buf[i] == '\n') {
 470                                 buf[i + 1] = 0;
 471                                 break;
 472                         }
 473                 }
 474                 buf[sizeof(buf) - 1] = 0;
 475                 if (strncmp(buf, "SSH-", 4) == 0)
 476                         break;
 477                 debug("ssh_exchange_identification: %s", buf);
 478         }
 479         server_version_string = xstrdup(buf);
 480 
 481         /*
 482          * Check that the versions match.  In future this might accept
 483          * several versions and set appropriate flags to handle them.
 484          */
 485         if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n",
 486             &remote_major, &remote_minor, remote_version) != 3)
 487                 fatal("Bad remote protocol version identification: '%.100s'", buf);
 488         debug("Remote protocol version %d.%d, remote software version %.100s",
 489             remote_major, remote_minor, remote_version);
 490 
 491         compat_datafellows(remote_version);
 492         mismatch = 0;
 493 
 494         switch (remote_major) {
 495         case 1:
 496                 if (remote_minor == 99 &&
 497                     (options.protocol & SSH_PROTO_2) &&
 498                     !(options.protocol & SSH_PROTO_1_PREFERRED)) {
 499                         enable_compat20();
 500                         break;
 501                 }
 502                 if (!(options.protocol & SSH_PROTO_1)) {
 503                         mismatch = 1;
 504                         break;
 505                 }
 506                 if (remote_minor < 3) {
 507                         fatal("Remote machine has too old SSH software version.");
 508                 } else if (remote_minor == 3 || remote_minor == 4) {
 509                         /* We speak 1.3, too. */
 510                         enable_compat13();
 511                         minor1 = 3;
 512                         if (options.forward_agent) {
 513                                 log("Agent forwarding disabled for protocol 1.3");
 514                                 options.forward_agent = 0;
 515                         }
 516                 }
 517                 break;
 518         case 2:
 519                 if (options.protocol & SSH_PROTO_2) {
 520                         enable_compat20();
 521                         break;
 522                 }
 523                 /* FALLTHROUGH */
 524         default:
 525                 mismatch = 1;
 526                 break;
 527         }
 528         if (mismatch)
 529                 fatal("Protocol major versions differ: %d vs. %d",
 530                     (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
 531                     remote_major);
 532         /* Send our own protocol version identification. */
 533         snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
 534             compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
 535             compat20 ? PROTOCOL_MINOR_2 : minor1,
 536             SSH_VERSION);
 537         if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
 538                 fatal("write: %.100s", strerror(errno));
 539         client_version_string = xstrdup(buf);
 540         chop(client_version_string);
 541         chop(server_version_string);
 542         debug("Local version string %.100s", client_version_string);
 543 }
 544 
 545 /* defaults to 'no' */
 546 static int
 547 confirm(const char *prompt)
 548 {
 549         const char *msg;
 550         char *p, *again = NULL;
 551         int n, ret = -1;
 552         regex_t yesre, nore;
 553         char *errstr;
 554         int rerr, errlen;
 555 
 556         if (options.batch_mode)
 557                 return 0;
 558         n = snprintf(NULL, 0, gettext("Please type '%s' or '%s': "),
 559                 nl_langinfo(YESSTR), nl_langinfo(NOSTR));
 560         again = xmalloc(n + 1);
 561         (void) snprintf(again, n + 1, gettext("Please type '%s' or '%s': "),
 562             nl_langinfo(YESSTR), nl_langinfo(NOSTR));
 563 
 564         if ((rerr = regcomp(&yesre, nl_langinfo(YESEXPR), REG_EXTENDED)) != 0) {
 565                 errlen = regerror(rerr, &yesre, NULL, 0);
 566                 if ((errstr = malloc(errlen)) == NULL)
 567                         err(1, "malloc");
 568                 regerror(rerr, &yesre, errstr, errlen);
 569                 errx(1, "YESEXPR: %s: %s", nl_langinfo(YESEXPR), errstr);
 570         }
 571 
 572         if ((rerr = regcomp(&nore, nl_langinfo(NOEXPR), REG_EXTENDED)) != 0) {
 573                 errlen = regerror(rerr, &nore, NULL, 0);
 574                 if ((errstr = malloc(errlen)) == NULL)
 575                         err(1, "malloc");
 576                 regerror(rerr, &nore, errstr, errlen);
 577                 errx(1, "NOEXPR: %s: %s", nl_langinfo(NOEXPR), errstr);
 578         }
 579 
 580         for (msg = prompt;;msg = again) {
 581                 p = read_passphrase(msg, RP_ECHO);
 582                 if (p == NULL || (p[0] == '\0') || (p[0] == '\n') ||
 583                     regexec(&nore, p, 0, NULL, 0) == 0)
 584                         ret = 0;
 585                 if (p && regexec(&yesre, p, 0, NULL, 0) == 0)
 586                         ret = 1;
 587                 if (p)
 588                         xfree(p);
 589                 if (ret != -1) {
 590                         regfree(&yesre);
 591                         regfree(&nore);
 592                         return ret;
 593                 }
 594         }
 595 }
 596 
 597 /*
 598  * check whether the supplied host key is valid, return -1 if the key
 599  * is not valid. the user_hostfile will not be updated if 'readonly' is true.
 600  */
 601 static int
 602 check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, int
 603         validated, int readonly, const char *user_hostfile, const char
 604         *system_hostfile)
 605 {
 606         Key *file_key;
 607         char *type = key_type(host_key);
 608         char *ip = NULL;
 609         char hostline[1000], *hostp, *fp;
 610         HostStatus host_status;
 611         HostStatus ip_status;
 612         int r, local = 0, host_ip_differ = 0;
 613         int salen;
 614         char ntop[NI_MAXHOST];
 615         char msg[1024];
 616         int len, host_line, ip_line, has_keys;
 617         const char *host_file = NULL, *ip_file = NULL;
 618 
 619         /*
 620          * Force accepting of the host key for loopback/localhost. The
 621          * problem is that if the home directory is NFS-mounted to multiple
 622          * machines, localhost will refer to a different machine in each of
 623          * them, and the user will get bogus HOST_CHANGED warnings.  This
 624          * essentially disables host authentication for localhost; however,
 625          * this is probably not a real problem.
 626          */
 627         /**  hostaddr == 0! */
 628         switch (hostaddr->sa_family) {
 629         case AF_INET:
 630                 /* LINTED */
 631                 local = (ntohl(((struct sockaddr_in *)hostaddr)->
 632                    sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
 633                 salen = sizeof(struct sockaddr_in);
 634                 break;
 635         case AF_INET6:
 636                 /* LINTED */
 637                 local = IN6_IS_ADDR_LOOPBACK(
 638                     &(((struct sockaddr_in6 *)hostaddr)->sin6_addr));
 639                 salen = sizeof(struct sockaddr_in6);
 640                 break;
 641         default:
 642                 local = 0;
 643                 salen = sizeof(struct sockaddr_storage);
 644                 break;
 645         }
 646         if (options.no_host_authentication_for_localhost == 1 && local &&
 647             options.host_key_alias == NULL) {
 648                 debug("Forcing accepting of host key for "
 649                     "loopback/localhost.");
 650                 return 0;
 651         }
 652 
 653         /*
 654          * We don't have the remote ip-address for connections
 655          * using a proxy command
 656          */
 657         if (options.proxy_command == NULL) {
 658                 if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
 659                     NULL, 0, NI_NUMERICHOST) != 0)
 660                         fatal("check_host_key: getnameinfo failed");
 661                 ip = xstrdup(ntop);
 662         } else {
 663                 ip = xstrdup("<no hostip for proxy command>");
 664         }
 665         /*
 666          * Turn off check_host_ip if the connection is to localhost, via proxy
 667          * command or if we don't have a hostname to compare with
 668          */
 669         if (options.check_host_ip &&
 670             (local || strcmp(host, ip) == 0 || options.proxy_command != NULL))
 671                 options.check_host_ip = 0;
 672 
 673         /*
 674          * Allow the user to record the key under a different name. This is
 675          * useful for ssh tunneling over forwarded connections or if you run
 676          * multiple sshd's on different ports on the same machine.
 677          */
 678         if (options.host_key_alias != NULL) {
 679                 host = options.host_key_alias;
 680                 debug("using hostkeyalias: %s", host);
 681         }
 682 
 683         /*
 684          * Store the host key from the known host file in here so that we can
 685          * compare it with the key for the IP address.
 686          */
 687         file_key = key_new(host_key->type);
 688 
 689         /*
 690          * Check if the host key is present in the user's list of known
 691          * hosts or in the systemwide list.
 692          */
 693         host_file = user_hostfile;
 694         host_status = check_host_in_hostfile(host_file, host, host_key,
 695             file_key, &host_line);
 696         if (host_status == HOST_NEW) {
 697                 host_file = system_hostfile;
 698                 host_status = check_host_in_hostfile(host_file, host, host_key,
 699                     file_key, &host_line);
 700         }
 701         /*
 702          * Also perform check for the ip address, skip the check if we are
 703          * localhost or the hostname was an ip address to begin with
 704          */
 705         if (options.check_host_ip) {
 706                 Key *ip_key = key_new(host_key->type);
 707 
 708                 ip_file = user_hostfile;
 709                 ip_status = check_host_in_hostfile(ip_file, ip, host_key,
 710                     ip_key, &ip_line);
 711                 if (ip_status == HOST_NEW) {
 712                         ip_file = system_hostfile;
 713                         ip_status = check_host_in_hostfile(ip_file, ip,
 714                             host_key, ip_key, &ip_line);
 715                 }
 716                 if (host_status == HOST_CHANGED &&
 717                     (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))
 718                         host_ip_differ = 1;
 719 
 720                 key_free(ip_key);
 721         } else
 722                 ip_status = host_status;
 723 
 724         key_free(file_key);
 725 
 726         switch (host_status) {
 727         case HOST_OK:
 728                 /* The host is known and the key matches. */
 729                 if (validated)
 730                         debug("Host '%.200s' is known and matches the %s host key.",
 731                             host, type);
 732                 else
 733                         debug("Host '%.200s' is known and matches the %s host "
 734                                 "key.", host, type);
 735                 debug("Found key in %s:%d", host_file, host_line);
 736                 if (options.check_host_ip && ip_status == HOST_NEW) {
 737                         if (readonly)
 738                                 log("%s host key for IP address "
 739                                     "'%.128s' not in list of known hosts.",
 740                                     type, ip);
 741                         else if (!add_host_to_hostfile(user_hostfile, ip,
 742                             host_key, options.hash_known_hosts))
 743                                 log("Failed to add the %s host key for IP "
 744                                     "address '%.128s' to the list of known "
 745                                     "hosts (%.30s).", type, ip, user_hostfile);
 746                         else
 747                                 log("Warning: Permanently added the %s host "
 748                                     "key for IP address '%.128s' to the list "
 749                                     "of known hosts.", type, ip);
 750                 }
 751                 break;
 752         case HOST_NEW:
 753                 if (readonly)
 754                         goto fail;
 755                 /* The host is new. */
 756                 if (!validated && options.strict_host_key_checking == 1) {
 757                         /*
 758                          * User has requested strict host key checking.  We
 759                          * will not add the host key automatically.  The only
 760                          * alternative left is to abort.
 761                          */
 762                         error("No %s host key is known for %.200s and you "
 763                             "have requested strict checking.", type, host);
 764                         goto fail;
 765                 } else if (!validated &&
 766                             options.strict_host_key_checking == 2) {
 767                         has_keys = show_other_keys(host, host_key);
 768                         /* The default */
 769                         fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
 770                         snprintf(msg, sizeof(msg),
 771                             gettext("The authenticity of host '%.200s (%s)' "
 772                             "can't be established%s\n%s key fingerprint "
 773                             "is %s.\n"
 774                             "Are you sure you want to continue connecting "
 775                             "(%s/%s)? "),
 776                              host, ip,
 777                              has_keys ? gettext(",\nbut keys of different type "
 778                                     "are already known for this host.") : ".",
 779                              type, fp, nl_langinfo(YESSTR), nl_langinfo(NOSTR));
 780                         xfree(fp);
 781                         if (!confirm(msg))
 782                                 goto fail;
 783                 }
 784                 /*
 785                  * If not in strict mode, add the key automatically to the
 786                  * local known_hosts file.
 787                  */
 788                 if (options.check_host_ip && ip_status == HOST_NEW) {
 789                         snprintf(hostline, sizeof(hostline), "%s,%s",
 790                             host, ip);
 791                         hostp = hostline;
 792                         if (options.hash_known_hosts) {
 793                                 /* Add hash of host and IP separately */
 794                                 r = add_host_to_hostfile(user_hostfile, host,
 795                                     host_key, options.hash_known_hosts) &&
 796                                     add_host_to_hostfile(user_hostfile, ip,
 797                                     host_key, options.hash_known_hosts);
 798                         } else {
 799                                 /* Add unhashed "host,ip" */
 800                                 r = add_host_to_hostfile(user_hostfile,
 801                                     hostline, host_key,
 802                                     options.hash_known_hosts);
 803                         }
 804                 } else {
 805                         r = add_host_to_hostfile(user_hostfile, host, host_key,
 806                             options.hash_known_hosts);
 807                         hostp = host;
 808                 }
 809 
 810                 if (!r)
 811                         log("Failed to add the host to the list of known "
 812                             "hosts (%.500s).", user_hostfile);
 813                 else
 814                         log("Warning: Permanently added '%.200s' (%s) to the "
 815                             "list of known hosts.", hostp, type);
 816                 break;
 817         case HOST_CHANGED:
 818                 if (validated) {
 819                         log("Warning: The host key for host %s has changed; "
 820                                 "please update your known hosts file(s) "
 821                                 "(%s:%d)", host, host_file, host_line);
 822                         if (options.check_host_ip && host_ip_differ) {
 823                                 log("Warning: The host key for host %s has "
 824                                         "changed; please update your known "
 825                                         "hosts file(s) (%s:%d)", ip, host_file,
 826                                         host_line);
 827 
 828                         }
 829                         break;
 830                 }
 831                 if (options.check_host_ip && host_ip_differ) {
 832                         char *msg;
 833                         if (ip_status == HOST_NEW)
 834                                 msg = "is unknown";
 835                         else if (ip_status == HOST_OK)
 836                                 msg = "is unchanged";
 837                         else
 838                                 msg = "has a different value";
 839                         error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
 840                               "@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @\n"
 841                               "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
 842                               "The %s host key for %s has changed,\n"
 843                               "and the key for the according IP address %s\n"
 844                               "%s. This could either mean that\n"
 845                               "DNS SPOOFING is happening or the IP address for the host\n"
 846                               "and its host key have changed at the same time.\n",
 847                               type, host, ip, msg);
 848                         if (ip_status != HOST_NEW)
 849                                 error("Offending key for IP in %s:%d", ip_file, ip_line);
 850                 }
 851                 /* The host key has changed. */
 852                 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
 853                 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
 854                       "@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @\n"
 855                       "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
 856                       "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"
 857                       "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"
 858                       "It is also possible that the %s host key has just been changed.\n"
 859                       "The fingerprint for the %s key sent by the remote host is\n%s.\n"
 860                       "Please contact your system administrator.\n"
 861                       "Add correct host key in %.100s to get rid of this message.\n"
 862                       "Offending key in %s:%d\n",
 863                       type, type, fp, user_hostfile, host_file, host_line);
 864                 xfree(fp);
 865 
 866                 /*
 867                  * If strict host key checking is in use, the user will have
 868                  * to edit the key manually and we can only abort.
 869                  */
 870                 if (options.strict_host_key_checking) {
 871                         error("%s host key for %.200s has changed and you have "
 872                             "requested strict checking.", type, host);
 873                         goto fail;
 874                 }
 875 
 876                 /*
 877                  * If strict host key checking has not been requested, allow
 878                  * the connection but without password authentication or
 879                  * agent forwarding.
 880                  */
 881                 if (options.password_authentication) {
 882                         error("Password authentication is disabled to avoid "
 883                             "man-in-the-middle attacks.");
 884                         options.password_authentication = 0;
 885                 }
 886                 if (options.forward_agent) {
 887                         error("Agent forwarding is disabled to avoid "
 888                             "man-in-the-middle attacks.");
 889                         options.forward_agent = 0;
 890                 }
 891                 if (options.forward_x11) {
 892                         error("X11 forwarding is disabled to avoid "
 893                             "man-in-the-middle attacks.");
 894                         options.forward_x11 = 0;
 895                 }
 896                 if (options.num_local_forwards > 0 ||
 897                     options.num_remote_forwards > 0) {
 898                         error("Port forwarding is disabled to avoid "
 899                             "man-in-the-middle attacks.");
 900                         options.num_local_forwards =
 901                             options.num_remote_forwards = 0;
 902                 }
 903                 /*
 904                  * XXX Should permit the user to change to use the new id.
 905                  * This could be done by converting the host key to an
 906                  * identifying sentence, tell that the host identifies itself
 907                  * by that sentence, and ask the user if he/she whishes to
 908                  * accept the authentication.
 909                  */
 910                 break;
 911         case HOST_FOUND:
 912                 fatal("internal error");
 913                 break;
 914         }
 915 
 916         if (options.check_host_ip && host_status != HOST_CHANGED &&
 917             ip_status == HOST_CHANGED) {
 918                 snprintf(msg, sizeof(msg),
 919                     gettext("Warning: the %s host key for '%.200s' "
 920                             "differs from the key for the IP address '%.128s'"
 921                             "\nOffending key for IP in %s:%d"),
 922                     type, host, ip, ip_file, ip_line);
 923                 if (host_status == HOST_OK) {
 924                         len = strlen(msg);
 925                         snprintf(msg + len, sizeof(msg) - len,
 926                             "\nMatching host key in %s:%d",
 927                             host_file, host_line);
 928                 }
 929                 if (!validated && options.strict_host_key_checking == 1) {
 930                         log(msg);
 931                         error("Exiting, you have requested strict checking.");
 932                         goto fail;
 933                 } else if (!validated &&
 934                             options.strict_host_key_checking == 2) {
 935                         snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg),
 936                                 gettext("\nAre you sure you want to continue "
 937                                         "connecting (%s/%s)"),
 938                                 nl_langinfo(YESSTR), nl_langinfo(NOSTR));
 939                         if (!confirm(msg))
 940                                 goto fail;
 941                 } else {
 942                         log(msg);
 943                 }
 944         }
 945 
 946         xfree(ip);
 947         return 0;
 948 
 949 fail:
 950         xfree(ip);
 951         return -1;
 952 }
 953 
 954 int
 955 verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
 956 {
 957         struct stat st;
 958 
 959         /* return ok if the key can be found in an old keyfile */
 960         if (stat(options.system_hostfile2, &st) == 0 ||
 961             stat(options.user_hostfile2, &st) == 0) {
 962                 if (check_host_key(host, hostaddr, host_key, 0, /*readonly*/ 1,
 963                     options.user_hostfile2, options.system_hostfile2) == 0)
 964                         return 0;
 965         }
 966         return check_host_key(host, hostaddr, host_key, 0, /*readonly*/ 0,
 967             options.user_hostfile, options.system_hostfile);
 968 }
 969 
 970 int
 971 accept_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
 972 {
 973         struct stat st;
 974 
 975         /* return ok if the key can be found in an old keyfile */
 976         if (stat(options.system_hostfile2, &st) == 0 ||
 977             stat(options.user_hostfile2, &st) == 0) {
 978                 if (check_host_key(host, hostaddr, host_key, 1, /*readonly*/ 1,
 979                     options.user_hostfile2, options.system_hostfile2) == 0)
 980                         return 0;
 981         }
 982         return check_host_key(host, hostaddr, host_key, 1, /*readonly*/ 0,
 983             options.user_hostfile, options.system_hostfile);
 984 }
 985 /*
 986  * Starts a dialog with the server, and authenticates the current user on the
 987  * server.  This does not need any extra privileges.  The basic connection
 988  * to the server must already have been established before this is called.
 989  * If login fails, this function prints an error and never returns.
 990  * This function does not require super-user privileges.
 991  */
 992 void
 993 ssh_login(Sensitive *sensitive, const char *orighost,
 994     struct sockaddr *hostaddr, char *pw_name)
 995 {
 996         char *host, *cp;
 997         char *server_user, *local_user;
 998 
 999         local_user = xstrdup(pw_name);
1000         server_user = options.user ? options.user : local_user;
1001 
1002         /* Convert the user-supplied hostname into all lowercase. */
1003         host = xstrdup(orighost);
1004         for (cp = host; *cp; cp++)
1005                 if (isupper(*cp))
1006                         *cp = tolower(*cp);
1007 
1008         /* Exchange protocol version identification strings with the server. */
1009         ssh_exchange_identification();
1010 
1011         /*
1012          * See comment at definition of will_daemonize for information why we
1013          * don't support the PKCS#11 engine with protocol 1.
1014          */
1015         if (compat20 == 1 && options.use_openssl_engine == 1) {
1016                 /*
1017                  * If this fails then 'e' will be NULL which means we do not use
1018                  * the engine, as if UseOpenSSLEngine was set to "no". This is
1019                  * important in case we go to the background after the
1020                  * authentication.
1021                  */
1022                 e = pkcs11_engine_load(options.use_openssl_engine);
1023         }
1024 
1025         /* Put the connection into non-blocking mode. */
1026         packet_set_nonblocking();
1027 
1028         /* key exchange */
1029         /* authenticate user */
1030         if (compat20) {
1031                 /*
1032                  * Note that the host pointer is saved in ssh_kex2() for later
1033                  * use during the key re-exchanges so we must not xfree() it.
1034                  */
1035                 ssh_kex2(host, hostaddr);
1036                 ssh_userauth2(local_user, server_user, host, sensitive);
1037         } else {
1038                 ssh_kex(host, hostaddr);
1039                 ssh_userauth1(local_user, server_user, host, sensitive);
1040         }
1041 
1042         xfree(local_user);
1043 }
1044 
1045 void
1046 ssh_put_password(char *password)
1047 {
1048         int size;
1049         char *padded;
1050 
1051         if (datafellows & SSH_BUG_PASSWORDPAD) {
1052                 packet_put_cstring(password);
1053                 return;
1054         }
1055         size = roundup(strlen(password) + 1, 32);
1056         padded = xmalloc(size);
1057         memset(padded, 0, size);
1058         strlcpy(padded, password, size);
1059         packet_put_string(padded, size);
1060         memset(padded, 0, size);
1061         xfree(padded);
1062 }
1063 
1064 static int
1065 show_key_from_file(const char *file, const char *host, int keytype)
1066 {
1067         Key *found;
1068         char *fp;
1069         int line, ret;
1070 
1071         found = key_new(keytype);
1072         if ((ret = lookup_key_in_hostfile_by_type(file, host,
1073             keytype, found, &line))) {
1074                 fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
1075                 log("WARNING: %s key found for host %s\n"
1076                     "in %s:%d\n"
1077                     "%s key fingerprint %s.",
1078                     key_type(found), host, file, line,
1079                     key_type(found), fp);
1080                 xfree(fp);
1081         }
1082         key_free(found);
1083         return (ret);
1084 }
1085 
1086 /* print all known host keys for a given host, but skip keys of given type */
1087 static int
1088 show_other_keys(const char *host, Key *key)
1089 {
1090         int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, -1};
1091         int i, found = 0;
1092 
1093         for (i = 0; type[i] != -1; i++) {
1094                 if (type[i] == key->type)
1095                         continue;
1096                 if (type[i] != KEY_RSA1 &&
1097                     show_key_from_file(options.user_hostfile2, host, type[i])) {
1098                         found = 1;
1099                         continue;
1100                 }
1101                 if (type[i] != KEY_RSA1 &&
1102                     show_key_from_file(options.system_hostfile2, host, type[i])) {
1103                         found = 1;
1104                         continue;
1105                 }
1106                 if (show_key_from_file(options.user_hostfile, host, type[i])) {
1107                         found = 1;
1108                         continue;
1109                 }
1110                 if (show_key_from_file(options.system_hostfile, host, type[i])) {
1111                         found = 1;
1112                         continue;
1113                 }
1114                 debug2("no key of type %d for host %s", type[i], host);
1115         }
1116         return (found);
1117 }