1 /* $OpenBSD: sshconnect.c,v 1.297 2018/02/23 15:58:38 markus Exp $ */ 2 /* 3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5 * All rights reserved 6 * Code to connect to a remote host, and to perform the client side of the 7 * login (authentication) dialog. 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 16 #include "includes.h" 17 __RCSID("$FreeBSD$"); 18 19 #include <sys/types.h> 20 #include <sys/wait.h> 21 #include <sys/stat.h> 22 #include <sys/socket.h> 23 #ifdef HAVE_SYS_TIME_H 24 # include <sys/time.h> 25 #endif 26 27 #include <net/if.h> 28 #include <netinet/in.h> 29 #include <arpa/inet.h> 30 #include <rpc/rpc.h> 31 32 #include <ctype.h> 33 #include <errno.h> 34 #include <fcntl.h> 35 #include <netdb.h> 36 #ifdef HAVE_PATHS_H 37 #include <paths.h> 38 #endif 39 #include <pwd.h> 40 #ifdef HAVE_POLL_H 41 #include <poll.h> 42 #endif 43 #include <signal.h> 44 #include <stdarg.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <unistd.h> 49 #ifdef HAVE_IFADDRS_H 50 # include <ifaddrs.h> 51 #endif 52 53 #include "xmalloc.h" 54 #include "key.h" 55 #include "hostfile.h" 56 #include "ssh.h" 57 #include "buffer.h" 58 #include "packet.h" 59 #include "uidswap.h" 60 #include "compat.h" 61 #include "key.h" 62 #include "sshconnect.h" 63 #include "hostfile.h" 64 #include "log.h" 65 #include "misc.h" 66 #include "readconf.h" 67 #include "atomicio.h" 68 #include "dns.h" 69 #include "monitor_fdpass.h" 70 #include "ssh2.h" 71 #include "version.h" 72 #include "authfile.h" 73 #include "ssherr.h" 74 #include "authfd.h" 75 76 char *client_version_string = NULL; 77 char *server_version_string = NULL; 78 struct sshkey *previous_host_key = NULL; 79 80 static int matching_host_key_dns = 0; 81 82 static pid_t proxy_command_pid = 0; 83 84 /* import */ 85 extern Options options; 86 extern char *__progname; 87 extern uid_t original_real_uid; 88 extern uid_t original_effective_uid; 89 90 static int show_other_keys(struct hostkeys *, struct sshkey *); 91 static void warn_changed_key(struct sshkey *); 92 93 /* Expand a proxy command */ 94 static char * 95 expand_proxy_command(const char *proxy_command, const char *user, 96 const char *host, int port) 97 { 98 char *tmp, *ret, strport[NI_MAXSERV]; 99 100 snprintf(strport, sizeof strport, "%d", port); 101 xasprintf(&tmp, "exec %s", proxy_command); 102 ret = percent_expand(tmp, "h", host, "p", strport, 103 "r", options.user, (char *)NULL); 104 free(tmp); 105 return ret; 106 } 107 108 /* 109 * Connect to the given ssh server using a proxy command that passes a 110 * a connected fd back to us. 111 */ 112 static int 113 ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port, 114 const char *proxy_command) 115 { 116 char *command_string; 117 int sp[2], sock; 118 pid_t pid; 119 char *shell; 120 121 if ((shell = getenv("SHELL")) == NULL) 122 shell = _PATH_BSHELL; 123 124 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) 125 fatal("Could not create socketpair to communicate with " 126 "proxy dialer: %.100s", strerror(errno)); 127 128 command_string = expand_proxy_command(proxy_command, options.user, 129 host, port); 130 debug("Executing proxy dialer command: %.500s", command_string); 131 132 /* Fork and execute the proxy command. */ 133 if ((pid = fork()) == 0) { 134 char *argv[10]; 135 136 /* Child. Permanently give up superuser privileges. */ 137 permanently_drop_suid(original_real_uid); 138 139 close(sp[1]); 140 /* Redirect stdin and stdout. */ 141 if (sp[0] != 0) { 142 if (dup2(sp[0], 0) < 0) 143 perror("dup2 stdin"); 144 } 145 if (sp[0] != 1) { 146 if (dup2(sp[0], 1) < 0) 147 perror("dup2 stdout"); 148 } 149 if (sp[0] >= 2) 150 close(sp[0]); 151 152 /* 153 * Stderr is left as it is so that error messages get 154 * printed on the user's terminal. 155 */ 156 argv[0] = shell; 157 argv[1] = "-c"; 158 argv[2] = command_string; 159 argv[3] = NULL; 160 161 /* 162 * Execute the proxy command. 163 * Note that we gave up any extra privileges above. 164 */ 165 execv(argv[0], argv); 166 perror(argv[0]); 167 exit(1); 168 } 169 /* Parent. */ 170 if (pid < 0) 171 fatal("fork failed: %.100s", strerror(errno)); 172 close(sp[0]); 173 free(command_string); 174 175 if ((sock = mm_receive_fd(sp[1])) == -1) 176 fatal("proxy dialer did not pass back a connection"); 177 close(sp[1]); 178 179 while (waitpid(pid, NULL, 0) == -1) 180 if (errno != EINTR) 181 fatal("Couldn't wait for child: %s", strerror(errno)); 182 183 /* Set the connection file descriptors. */ 184 if (ssh_packet_set_connection(ssh, sock, sock) == NULL) 185 return -1; /* ssh_packet_set_connection logs error */ 186 187 return 0; 188 } 189 190 /* 191 * Connect to the given ssh server using a proxy command. 192 */ 193 static int 194 ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port, 195 const char *proxy_command) 196 { 197 char *command_string; 198 int pin[2], pout[2]; 199 pid_t pid; 200 char *shell; 201 202 if ((shell = getenv("SHELL")) == NULL || *shell == '\0') 203 shell = _PATH_BSHELL; 204 205 /* Create pipes for communicating with the proxy. */ 206 if (pipe(pin) < 0 || pipe(pout) < 0) 207 fatal("Could not create pipes to communicate with the proxy: %.100s", 208 strerror(errno)); 209 210 command_string = expand_proxy_command(proxy_command, options.user, 211 host, port); 212 debug("Executing proxy command: %.500s", command_string); 213 214 /* Fork and execute the proxy command. */ 215 if ((pid = fork()) == 0) { 216 char *argv[10]; 217 218 /* Child. Permanently give up superuser privileges. */ 219 permanently_drop_suid(original_real_uid); 220 221 /* Redirect stdin and stdout. */ 222 close(pin[1]); 223 if (pin[0] != 0) { 224 if (dup2(pin[0], 0) < 0) 225 perror("dup2 stdin"); 226 close(pin[0]); 227 } 228 close(pout[0]); 229 if (dup2(pout[1], 1) < 0) 230 perror("dup2 stdout"); 231 /* Cannot be 1 because pin allocated two descriptors. */ 232 close(pout[1]); 233 234 /* Stderr is left as it is so that error messages get 235 printed on the user's terminal. */ 236 argv[0] = shell; 237 argv[1] = "-c"; 238 argv[2] = command_string; 239 argv[3] = NULL; 240 241 /* Execute the proxy command. Note that we gave up any 242 extra privileges above. */ 243 signal(SIGPIPE, SIG_DFL); 244 execv(argv[0], argv); 245 perror(argv[0]); 246 exit(1); 247 } 248 /* Parent. */ 249 if (pid < 0) 250 fatal("fork failed: %.100s", strerror(errno)); 251 else 252 proxy_command_pid = pid; /* save pid to clean up later */ 253 254 /* Close child side of the descriptors. */ 255 close(pin[0]); 256 close(pout[1]); 257 258 /* Free the command name. */ 259 free(command_string); 260 261 /* Set the connection file descriptors. */ 262 if (ssh_packet_set_connection(ssh, pout[0], pin[1]) == NULL) 263 return -1; /* ssh_packet_set_connection logs error */ 264 265 return 0; 266 } 267 268 void 269 ssh_kill_proxy_command(void) 270 { 271 /* 272 * Send SIGHUP to proxy command if used. We don't wait() in 273 * case it hangs and instead rely on init to reap the child 274 */ 275 if (proxy_command_pid > 1) 276 kill(proxy_command_pid, SIGHUP); 277 } 278 279 #ifdef HAVE_IFADDRS_H 280 /* 281 * Search a interface address list (returned from getifaddrs(3)) for an 282 * address that matches the desired address family on the specifed interface. 283 * Returns 0 and fills in *resultp and *rlenp on success. Returns -1 on failure. 284 */ 285 static int 286 check_ifaddrs(const char *ifname, int af, const struct ifaddrs *ifaddrs, 287 struct sockaddr_storage *resultp, socklen_t *rlenp) 288 { 289 struct sockaddr_in6 *sa6; 290 struct sockaddr_in *sa; 291 struct in6_addr *v6addr; 292 const struct ifaddrs *ifa; 293 int allow_local; 294 295 /* 296 * Prefer addresses that are not loopback or linklocal, but use them 297 * if nothing else matches. 298 */ 299 for (allow_local = 0; allow_local < 2; allow_local++) { 300 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { 301 if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL || 302 (ifa->ifa_flags & IFF_UP) == 0 || 303 ifa->ifa_addr->sa_family != af || 304 strcmp(ifa->ifa_name, options.bind_interface) != 0) 305 continue; 306 switch (ifa->ifa_addr->sa_family) { 307 case AF_INET: 308 sa = (struct sockaddr_in *)ifa->ifa_addr; 309 if (!allow_local && sa->sin_addr.s_addr == 310 htonl(INADDR_LOOPBACK)) 311 continue; 312 if (*rlenp < sizeof(struct sockaddr_in)) { 313 error("%s: v4 addr doesn't fit", 314 __func__); 315 return -1; 316 } 317 *rlenp = sizeof(struct sockaddr_in); 318 memcpy(resultp, sa, *rlenp); 319 return 0; 320 case AF_INET6: 321 sa6 = (struct sockaddr_in6 *)ifa->ifa_addr; 322 v6addr = &sa6->sin6_addr; 323 if (!allow_local && 324 (IN6_IS_ADDR_LINKLOCAL(v6addr) || 325 IN6_IS_ADDR_LOOPBACK(v6addr))) 326 continue; 327 if (*rlenp < sizeof(struct sockaddr_in6)) { 328 error("%s: v6 addr doesn't fit", 329 __func__); 330 return -1; 331 } 332 *rlenp = sizeof(struct sockaddr_in6); 333 memcpy(resultp, sa6, *rlenp); 334 return 0; 335 } 336 } 337 } 338 return -1; 339 } 340 #endif 341 342 /* 343 * Creates a (possibly privileged) socket for use as the ssh connection. 344 */ 345 static int 346 ssh_create_socket(int privileged, struct addrinfo *ai) 347 { 348 int sock, r, oerrno; 349 struct sockaddr_storage bindaddr; 350 socklen_t bindaddrlen = 0; 351 struct addrinfo hints, *res = NULL; 352 #ifdef HAVE_IFADDRS_H 353 struct ifaddrs *ifaddrs = NULL; 354 #endif 355 char ntop[NI_MAXHOST]; 356 357 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 358 if (sock < 0) { 359 error("socket: %s", strerror(errno)); 360 return -1; 361 } 362 fcntl(sock, F_SETFD, FD_CLOEXEC); 363 364 /* Bind the socket to an alternative local IP address */ 365 if (options.bind_address == NULL && options.bind_interface == NULL && 366 !privileged) 367 return sock; 368 369 if (options.bind_address != NULL) { 370 memset(&hints, 0, sizeof(hints)); 371 hints.ai_family = ai->ai_family; 372 hints.ai_socktype = ai->ai_socktype; 373 hints.ai_protocol = ai->ai_protocol; 374 hints.ai_flags = AI_PASSIVE; 375 if ((r = getaddrinfo(options.bind_address, NULL, 376 &hints, &res)) != 0) { 377 error("getaddrinfo: %s: %s", options.bind_address, 378 ssh_gai_strerror(r)); 379 goto fail; 380 } 381 if (res == NULL) { 382 error("getaddrinfo: no addrs"); 383 goto fail; 384 } 385 if (res->ai_addrlen > sizeof(bindaddr)) { 386 error("%s: addr doesn't fit", __func__); 387 goto fail; 388 } 389 memcpy(&bindaddr, res->ai_addr, res->ai_addrlen); 390 bindaddrlen = res->ai_addrlen; 391 } else if (options.bind_interface != NULL) { 392 #ifdef HAVE_IFADDRS_H 393 if ((r = getifaddrs(&ifaddrs)) != 0) { 394 error("getifaddrs: %s: %s", options.bind_interface, 395 strerror(errno)); 396 goto fail; 397 } 398 bindaddrlen = sizeof(bindaddr); 399 if (check_ifaddrs(options.bind_interface, ai->ai_family, 400 ifaddrs, &bindaddr, &bindaddrlen) != 0) { 401 logit("getifaddrs: %s: no suitable addresses", 402 options.bind_interface); 403 goto fail; 404 } 405 #else 406 error("BindInterface not supported on this platform."); 407 #endif 408 } 409 if ((r = getnameinfo((struct sockaddr *)&bindaddr, bindaddrlen, 410 ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST)) != 0) { 411 error("%s: getnameinfo failed: %s", __func__, 412 ssh_gai_strerror(r)); 413 goto fail; 414 } 415 /* 416 * If we are running as root and want to connect to a privileged 417 * port, bind our own socket to a privileged port. 418 */ 419 if (privileged) { 420 PRIV_START; 421 r = bindresvport_sa(sock, 422 bindaddrlen == 0 ? NULL : (struct sockaddr *)&bindaddr); 423 oerrno = errno; 424 PRIV_END; 425 if (r < 0) { 426 error("bindresvport_sa %s: %s", ntop, 427 strerror(oerrno)); 428 goto fail; 429 } 430 } else if (bind(sock, (struct sockaddr *)&bindaddr, bindaddrlen) != 0) { 431 error("bind %s: %s", ntop, strerror(errno)); 432 goto fail; 433 } 434 debug("%s: bound to %s", __func__, ntop); 435 /* success */ 436 goto out; 437 fail: 438 close(sock); 439 sock = -1; 440 out: 441 if (res != NULL) 442 freeaddrinfo(res); 443 #ifdef HAVE_IFADDRS_H 444 if (ifaddrs != NULL) 445 freeifaddrs(ifaddrs); 446 #endif 447 return sock; 448 } 449 450 /* 451 * Wait up to *timeoutp milliseconds for fd to be readable. Updates 452 * *timeoutp with time remaining. 453 * Returns 0 if fd ready or -1 on timeout or error (see errno). 454 */ 455 static int 456 waitrfd(int fd, int *timeoutp) 457 { 458 struct pollfd pfd; 459 struct timeval t_start; 460 int oerrno, r; 461 462 monotime_tv(&t_start); 463 pfd.fd = fd; 464 pfd.events = POLLIN; 465 for (; *timeoutp >= 0;) { 466 r = poll(&pfd, 1, *timeoutp); 467 oerrno = errno; 468 ms_subtract_diff(&t_start, timeoutp); 469 errno = oerrno; 470 if (r > 0) 471 return 0; 472 else if (r == -1 && errno != EAGAIN) 473 return -1; 474 else if (r == 0) 475 break; 476 } 477 /* timeout */ 478 errno = ETIMEDOUT; 479 return -1; 480 } 481 482 static int 483 timeout_connect(int sockfd, const struct sockaddr *serv_addr, 484 socklen_t addrlen, int *timeoutp) 485 { 486 int optval = 0; 487 socklen_t optlen = sizeof(optval); 488 489 /* No timeout: just do a blocking connect() */ 490 if (*timeoutp <= 0) 491 return connect(sockfd, serv_addr, addrlen); 492 493 set_nonblock(sockfd); 494 if (connect(sockfd, serv_addr, addrlen) == 0) { 495 /* Succeeded already? */ 496 unset_nonblock(sockfd); 497 return 0; 498 } else if (errno != EINPROGRESS) 499 return -1; 500 501 if (waitrfd(sockfd, timeoutp) == -1) 502 return -1; 503 504 /* Completed or failed */ 505 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) { 506 debug("getsockopt: %s", strerror(errno)); 507 return -1; 508 } 509 if (optval != 0) { 510 errno = optval; 511 return -1; 512 } 513 unset_nonblock(sockfd); 514 return 0; 515 } 516 517 /* 518 * Opens a TCP/IP connection to the remote server on the given host. 519 * The address of the remote host will be returned in hostaddr. 520 * If port is 0, the default port will be used. If needpriv is true, 521 * a privileged port will be allocated to make the connection. 522 * This requires super-user privileges if needpriv is true. 523 * Connection_attempts specifies the maximum number of tries (one per 524 * second). If proxy_command is non-NULL, it specifies the command (with %h 525 * and %p substituted for host and port, respectively) to use to contact 526 * the daemon. 527 */ 528 static int 529 ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, 530 struct sockaddr_storage *hostaddr, u_short port, int family, 531 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) 532 { 533 int on = 1; 534 int oerrno, sock = -1, attempt; 535 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 536 struct addrinfo *ai; 537 538 debug2("%s: needpriv %d", __func__, needpriv); 539 memset(ntop, 0, sizeof(ntop)); 540 memset(strport, 0, sizeof(strport)); 541 542 for (attempt = 0; attempt < connection_attempts; attempt++) { 543 if (attempt > 0) { 544 /* Sleep a moment before retrying. */ 545 sleep(1); 546 debug("Trying again..."); 547 } 548 /* 549 * Loop through addresses for this host, and try each one in 550 * sequence until the connection succeeds. 551 */ 552 for (ai = aitop; ai; ai = ai->ai_next) { 553 if (ai->ai_family != AF_INET && 554 ai->ai_family != AF_INET6) { 555 errno = EAFNOSUPPORT; 556 continue; 557 } 558 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, 559 ntop, sizeof(ntop), strport, sizeof(strport), 560 NI_NUMERICHOST|NI_NUMERICSERV) != 0) { 561 oerrno = errno; 562 error("%s: getnameinfo failed", __func__); 563 errno = oerrno; 564 continue; 565 } 566 debug("Connecting to %.200s [%.100s] port %s.", 567 host, ntop, strport); 568 569 /* Create a socket for connecting. */ 570 sock = ssh_create_socket(needpriv, ai); 571 if (sock < 0) { 572 /* Any error is already output */ 573 errno = 0; 574 continue; 575 } 576 577 if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, 578 timeout_ms) >= 0) { 579 /* Successful connection. */ 580 memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); 581 break; 582 } else { 583 oerrno = errno; 584 debug("connect to address %s port %s: %s", 585 ntop, strport, strerror(errno)); 586 close(sock); 587 sock = -1; 588 errno = oerrno; 589 } 590 } 591 if (sock != -1) 592 break; /* Successful connection. */ 593 } 594 595 /* Return failure if we didn't get a successful connection. */ 596 if (sock == -1) { 597 error("ssh: connect to host %s port %s: %s", 598 host, strport, errno == 0 ? "failure" : strerror(errno)); 599 return -1; 600 } 601 602 debug("Connection established."); 603 604 /* Set SO_KEEPALIVE if requested. */ 605 if (want_keepalive && 606 setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, 607 sizeof(on)) < 0) 608 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 609 610 /* Set the connection. */ 611 if (ssh_packet_set_connection(ssh, sock, sock) == NULL) 612 return -1; /* ssh_packet_set_connection logs error */ 613 614 return 0; 615 } 616 617 int 618 ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs, 619 struct sockaddr_storage *hostaddr, u_short port, int family, 620 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) 621 { 622 if (options.proxy_command == NULL) { 623 return ssh_connect_direct(ssh, host, addrs, hostaddr, port, 624 family, connection_attempts, timeout_ms, want_keepalive, 625 needpriv); 626 } else if (strcmp(options.proxy_command, "-") == 0) { 627 if ((ssh_packet_set_connection(ssh, 628 STDIN_FILENO, STDOUT_FILENO)) == NULL) 629 return -1; /* ssh_packet_set_connection logs error */ 630 return 0; 631 } else if (options.proxy_use_fdpass) { 632 return ssh_proxy_fdpass_connect(ssh, host, port, 633 options.proxy_command); 634 } 635 return ssh_proxy_connect(ssh, host, port, options.proxy_command); 636 } 637 638 static void 639 send_client_banner(int connection_out, int minor1) 640 { 641 /* Send our own protocol version identification. */ 642 xasprintf(&client_version_string, "SSH-%d.%d-%.100s%s%s\n", 643 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, 644 *options.version_addendum == '\0' ? "" : " ", 645 options.version_addendum); 646 if (atomicio(vwrite, connection_out, client_version_string, 647 strlen(client_version_string)) != strlen(client_version_string)) 648 fatal("write: %.100s", strerror(errno)); 649 chop(client_version_string); 650 debug("Local version string %.100s", client_version_string); 651 } 652 653 /* 654 * Waits for the server identification string, and sends our own 655 * identification string. 656 */ 657 void 658 ssh_exchange_identification(int timeout_ms) 659 { 660 char buf[256], remote_version[256]; /* must be same size! */ 661 int remote_major, remote_minor, mismatch; 662 int connection_in = packet_get_connection_in(); 663 int connection_out = packet_get_connection_out(); 664 u_int i, n; 665 size_t len; 666 int rc; 667 668 send_client_banner(connection_out, 0); 669 670 /* Read other side's version identification. */ 671 for (n = 0;;) { 672 for (i = 0; i < sizeof(buf) - 1; i++) { 673 if (timeout_ms > 0) { 674 rc = waitrfd(connection_in, &timeout_ms); 675 if (rc == -1 && errno == ETIMEDOUT) { 676 fatal("Connection timed out during " 677 "banner exchange"); 678 } else if (rc == -1) { 679 fatal("%s: %s", 680 __func__, strerror(errno)); 681 } 682 } 683 684 len = atomicio(read, connection_in, &buf[i], 1); 685 if (len != 1 && errno == EPIPE) 686 fatal("ssh_exchange_identification: " 687 "Connection closed by remote host"); 688 else if (len != 1) 689 fatal("ssh_exchange_identification: " 690 "read: %.100s", strerror(errno)); 691 if (buf[i] == '\r') { 692 buf[i] = '\n'; 693 buf[i + 1] = 0; 694 continue; /**XXX wait for \n */ 695 } 696 if (buf[i] == '\n') { 697 buf[i + 1] = 0; 698 break; 699 } 700 if (++n > 65536) 701 fatal("ssh_exchange_identification: " 702 "No banner received"); 703 } 704 buf[sizeof(buf) - 1] = 0; 705 if (strncmp(buf, "SSH-", 4) == 0) 706 break; 707 debug("ssh_exchange_identification: %s", buf); 708 } 709 server_version_string = xstrdup(buf); 710 711 /* 712 * Check that the versions match. In future this might accept 713 * several versions and set appropriate flags to handle them. 714 */ 715 if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", 716 &remote_major, &remote_minor, remote_version) != 3) 717 fatal("Bad remote protocol version identification: '%.100s'", buf); 718 debug("Remote protocol version %d.%d, remote software version %.100s", 719 remote_major, remote_minor, remote_version); 720 721 active_state->compat = compat_datafellows(remote_version); 722 mismatch = 0; 723 724 switch (remote_major) { 725 case 2: 726 break; 727 case 1: 728 if (remote_minor != 99) 729 mismatch = 1; 730 break; 731 default: 732 mismatch = 1; 733 break; 734 } 735 if (mismatch) 736 fatal("Protocol major versions differ: %d vs. %d", 737 PROTOCOL_MAJOR_2, remote_major); 738 if ((datafellows & SSH_BUG_RSASIGMD5) != 0) 739 logit("Server version \"%.100s\" uses unsafe RSA signature " 740 "scheme; disabling use of RSA keys", remote_version); 741 chop(server_version_string); 742 } 743 744 /* defaults to 'no' */ 745 static int 746 confirm(const char *prompt) 747 { 748 const char *msg, *again = "Please type 'yes' or 'no': "; 749 char *p; 750 int ret = -1; 751 752 if (options.batch_mode) 753 return 0; 754 for (msg = prompt;;msg = again) { 755 p = read_passphrase(msg, RP_ECHO); 756 if (p == NULL) 757 return 0; 758 p[strcspn(p, "\n")] = '\0'; 759 if (p[0] == '\0' || strcasecmp(p, "no") == 0) 760 ret = 0; 761 else if (strcasecmp(p, "yes") == 0) 762 ret = 1; 763 free(p); 764 if (ret != -1) 765 return ret; 766 } 767 } 768 769 static int 770 check_host_cert(const char *host, const struct sshkey *host_key) 771 { 772 const char *reason; 773 774 if (key_cert_check_authority(host_key, 1, 0, host, &reason) != 0) { 775 error("%s", reason); 776 return 0; 777 } 778 if (buffer_len(host_key->cert->critical) != 0) { 779 error("Certificate for %s contains unsupported " 780 "critical options(s)", host); 781 return 0; 782 } 783 return 1; 784 } 785 786 static int 787 sockaddr_is_local(struct sockaddr *hostaddr) 788 { 789 switch (hostaddr->sa_family) { 790 case AF_INET: 791 return (ntohl(((struct sockaddr_in *)hostaddr)-> 792 sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; 793 case AF_INET6: 794 return IN6_IS_ADDR_LOOPBACK( 795 &(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); 796 default: 797 return 0; 798 } 799 } 800 801 /* 802 * Prepare the hostname and ip address strings that are used to lookup 803 * host keys in known_hosts files. These may have a port number appended. 804 */ 805 void 806 get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr, 807 u_short port, char **hostfile_hostname, char **hostfile_ipaddr) 808 { 809 char ntop[NI_MAXHOST]; 810 socklen_t addrlen; 811 812 switch (hostaddr == NULL ? -1 : hostaddr->sa_family) { 813 case -1: 814 addrlen = 0; 815 break; 816 case AF_INET: 817 addrlen = sizeof(struct sockaddr_in); 818 break; 819 case AF_INET6: 820 addrlen = sizeof(struct sockaddr_in6); 821 break; 822 default: 823 addrlen = sizeof(struct sockaddr); 824 break; 825 } 826 827 /* 828 * We don't have the remote ip-address for connections 829 * using a proxy command 830 */ 831 if (hostfile_ipaddr != NULL) { 832 if (options.proxy_command == NULL) { 833 if (getnameinfo(hostaddr, addrlen, 834 ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0) 835 fatal("%s: getnameinfo failed", __func__); 836 *hostfile_ipaddr = put_host_port(ntop, port); 837 } else { 838 *hostfile_ipaddr = xstrdup("<no hostip for proxy " 839 "command>"); 840 } 841 } 842 843 /* 844 * Allow the user to record the key under a different name or 845 * differentiate a non-standard port. This is useful for ssh 846 * tunneling over forwarded connections or if you run multiple 847 * sshd's on different ports on the same machine. 848 */ 849 if (hostfile_hostname != NULL) { 850 if (options.host_key_alias != NULL) { 851 *hostfile_hostname = xstrdup(options.host_key_alias); 852 debug("using hostkeyalias: %s", *hostfile_hostname); 853 } else { 854 *hostfile_hostname = put_host_port(hostname, port); 855 } 856 } 857 } 858 859 /* 860 * check whether the supplied host key is valid, return -1 if the key 861 * is not valid. user_hostfile[0] will not be updated if 'readonly' is true. 862 */ 863 #define RDRW 0 864 #define RDONLY 1 865 #define ROQUIET 2 866 static int 867 check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, 868 struct sshkey *host_key, int readonly, 869 char **user_hostfiles, u_int num_user_hostfiles, 870 char **system_hostfiles, u_int num_system_hostfiles) 871 { 872 HostStatus host_status; 873 HostStatus ip_status; 874 struct sshkey *raw_key = NULL; 875 char *ip = NULL, *host = NULL; 876 char hostline[1000], *hostp, *fp, *ra; 877 char msg[1024]; 878 const char *type; 879 const struct hostkey_entry *host_found, *ip_found; 880 int len, cancelled_forwarding = 0; 881 int local = sockaddr_is_local(hostaddr); 882 int r, want_cert = sshkey_is_cert(host_key), host_ip_differ = 0; 883 int hostkey_trusted = 0; /* Known or explicitly accepted by user */ 884 struct hostkeys *host_hostkeys, *ip_hostkeys; 885 u_int i; 886 887 /* 888 * Force accepting of the host key for loopback/localhost. The 889 * problem is that if the home directory is NFS-mounted to multiple 890 * machines, localhost will refer to a different machine in each of 891 * them, and the user will get bogus HOST_CHANGED warnings. This 892 * essentially disables host authentication for localhost; however, 893 * this is probably not a real problem. 894 */ 895 if (options.no_host_authentication_for_localhost == 1 && local && 896 options.host_key_alias == NULL) { 897 debug("Forcing accepting of host key for " 898 "loopback/localhost."); 899 return 0; 900 } 901 902 /* 903 * Prepare the hostname and address strings used for hostkey lookup. 904 * In some cases, these will have a port number appended. 905 */ 906 get_hostfile_hostname_ipaddr(hostname, hostaddr, port, &host, &ip); 907 908 /* 909 * Turn off check_host_ip if the connection is to localhost, via proxy 910 * command or if we don't have a hostname to compare with 911 */ 912 if (options.check_host_ip && (local || 913 strcmp(hostname, ip) == 0 || options.proxy_command != NULL)) 914 options.check_host_ip = 0; 915 916 host_hostkeys = init_hostkeys(); 917 for (i = 0; i < num_user_hostfiles; i++) 918 load_hostkeys(host_hostkeys, host, user_hostfiles[i]); 919 for (i = 0; i < num_system_hostfiles; i++) 920 load_hostkeys(host_hostkeys, host, system_hostfiles[i]); 921 922 ip_hostkeys = NULL; 923 if (!want_cert && options.check_host_ip) { 924 ip_hostkeys = init_hostkeys(); 925 for (i = 0; i < num_user_hostfiles; i++) 926 load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]); 927 for (i = 0; i < num_system_hostfiles; i++) 928 load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]); 929 } 930 931 retry: 932 /* Reload these as they may have changed on cert->key downgrade */ 933 want_cert = sshkey_is_cert(host_key); 934 type = sshkey_type(host_key); 935 936 /* 937 * Check if the host key is present in the user's list of known 938 * hosts or in the systemwide list. 939 */ 940 host_status = check_key_in_hostkeys(host_hostkeys, host_key, 941 &host_found); 942 943 /* 944 * Also perform check for the ip address, skip the check if we are 945 * localhost, looking for a certificate, or the hostname was an ip 946 * address to begin with. 947 */ 948 if (!want_cert && ip_hostkeys != NULL) { 949 ip_status = check_key_in_hostkeys(ip_hostkeys, host_key, 950 &ip_found); 951 if (host_status == HOST_CHANGED && 952 (ip_status != HOST_CHANGED || 953 (ip_found != NULL && 954 !sshkey_equal(ip_found->key, host_found->key)))) 955 host_ip_differ = 1; 956 } else 957 ip_status = host_status; 958 959 switch (host_status) { 960 case HOST_OK: 961 /* The host is known and the key matches. */ 962 debug("Host '%.200s' is known and matches the %s host %s.", 963 host, type, want_cert ? "certificate" : "key"); 964 debug("Found %s in %s:%lu", want_cert ? "CA key" : "key", 965 host_found->file, host_found->line); 966 if (want_cert && 967 !check_host_cert(options.host_key_alias == NULL ? 968 hostname : options.host_key_alias, host_key)) 969 goto fail; 970 if (options.check_host_ip && ip_status == HOST_NEW) { 971 if (readonly || want_cert) 972 logit("%s host key for IP address " 973 "'%.128s' not in list of known hosts.", 974 type, ip); 975 else if (!add_host_to_hostfile(user_hostfiles[0], ip, 976 host_key, options.hash_known_hosts)) 977 logit("Failed to add the %s host key for IP " 978 "address '%.128s' to the list of known " 979 "hosts (%.500s).", type, ip, 980 user_hostfiles[0]); 981 else 982 logit("Warning: Permanently added the %s host " 983 "key for IP address '%.128s' to the list " 984 "of known hosts.", type, ip); 985 } else if (options.visual_host_key) { 986 fp = sshkey_fingerprint(host_key, 987 options.fingerprint_hash, SSH_FP_DEFAULT); 988 ra = sshkey_fingerprint(host_key, 989 options.fingerprint_hash, SSH_FP_RANDOMART); 990 if (fp == NULL || ra == NULL) 991 fatal("%s: sshkey_fingerprint fail", __func__); 992 logit("Host key fingerprint is %s\n%s", fp, ra); 993 free(ra); 994 free(fp); 995 } 996 hostkey_trusted = 1; 997 break; 998 case HOST_NEW: 999 if (options.host_key_alias == NULL && port != 0 && 1000 port != SSH_DEFAULT_PORT) { 1001 debug("checking without port identifier"); 1002 if (check_host_key(hostname, hostaddr, 0, host_key, 1003 ROQUIET, user_hostfiles, num_user_hostfiles, 1004 system_hostfiles, num_system_hostfiles) == 0) { 1005 debug("found matching key w/out port"); 1006 break; 1007 } 1008 } 1009 if (readonly || want_cert) 1010 goto fail; 1011 /* The host is new. */ 1012 if (options.strict_host_key_checking == 1013 SSH_STRICT_HOSTKEY_YES) { 1014 /* 1015 * User has requested strict host key checking. We 1016 * will not add the host key automatically. The only 1017 * alternative left is to abort. 1018 */ 1019 error("No %s host key is known for %.200s and you " 1020 "have requested strict checking.", type, host); 1021 goto fail; 1022 } else if (options.strict_host_key_checking == 1023 SSH_STRICT_HOSTKEY_ASK) { 1024 char msg1[1024], msg2[1024]; 1025 1026 if (show_other_keys(host_hostkeys, host_key)) 1027 snprintf(msg1, sizeof(msg1), 1028 "\nbut keys of different type are already" 1029 " known for this host."); 1030 else 1031 snprintf(msg1, sizeof(msg1), "."); 1032 /* The default */ 1033 fp = sshkey_fingerprint(host_key, 1034 options.fingerprint_hash, SSH_FP_DEFAULT); 1035 ra = sshkey_fingerprint(host_key, 1036 options.fingerprint_hash, SSH_FP_RANDOMART); 1037 if (fp == NULL || ra == NULL) 1038 fatal("%s: sshkey_fingerprint fail", __func__); 1039 msg2[0] = '\0'; 1040 if (options.verify_host_key_dns) { 1041 if (matching_host_key_dns) 1042 snprintf(msg2, sizeof(msg2), 1043 "Matching host key fingerprint" 1044 " found in DNS.\n"); 1045 else 1046 snprintf(msg2, sizeof(msg2), 1047 "No matching host key fingerprint" 1048 " found in DNS.\n"); 1049 } 1050 snprintf(msg, sizeof(msg), 1051 "The authenticity of host '%.200s (%s)' can't be " 1052 "established%s\n" 1053 "%s key fingerprint is %s.%s%s\n%s" 1054 "Are you sure you want to continue connecting " 1055 "(yes/no)? ", 1056 host, ip, msg1, type, fp, 1057 options.visual_host_key ? "\n" : "", 1058 options.visual_host_key ? ra : "", 1059 msg2); 1060 free(ra); 1061 free(fp); 1062 if (!confirm(msg)) 1063 goto fail; 1064 hostkey_trusted = 1; /* user explicitly confirmed */ 1065 } 1066 /* 1067 * If in "new" or "off" strict mode, add the key automatically 1068 * to the local known_hosts file. 1069 */ 1070 if (options.check_host_ip && ip_status == HOST_NEW) { 1071 snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); 1072 hostp = hostline; 1073 if (options.hash_known_hosts) { 1074 /* Add hash of host and IP separately */ 1075 r = add_host_to_hostfile(user_hostfiles[0], 1076 host, host_key, options.hash_known_hosts) && 1077 add_host_to_hostfile(user_hostfiles[0], ip, 1078 host_key, options.hash_known_hosts); 1079 } else { 1080 /* Add unhashed "host,ip" */ 1081 r = add_host_to_hostfile(user_hostfiles[0], 1082 hostline, host_key, 1083 options.hash_known_hosts); 1084 } 1085 } else { 1086 r = add_host_to_hostfile(user_hostfiles[0], host, 1087 host_key, options.hash_known_hosts); 1088 hostp = host; 1089 } 1090 1091 if (!r) 1092 logit("Failed to add the host to the list of known " 1093 "hosts (%.500s).", user_hostfiles[0]); 1094 else 1095 logit("Warning: Permanently added '%.200s' (%s) to the " 1096 "list of known hosts.", hostp, type); 1097 break; 1098 case HOST_REVOKED: 1099 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 1100 error("@ WARNING: REVOKED HOST KEY DETECTED! @"); 1101 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 1102 error("The %s host key for %s is marked as revoked.", type, host); 1103 error("This could mean that a stolen key is being used to"); 1104 error("impersonate this host."); 1105 1106 /* 1107 * If strict host key checking is in use, the user will have 1108 * to edit the key manually and we can only abort. 1109 */ 1110 if (options.strict_host_key_checking != 1111 SSH_STRICT_HOSTKEY_OFF) { 1112 error("%s host key for %.200s was revoked and you have " 1113 "requested strict checking.", type, host); 1114 goto fail; 1115 } 1116 goto continue_unsafe; 1117 1118 case HOST_CHANGED: 1119 if (want_cert) { 1120 /* 1121 * This is only a debug() since it is valid to have 1122 * CAs with wildcard DNS matches that don't match 1123 * all hosts that one might visit. 1124 */ 1125 debug("Host certificate authority does not " 1126 "match %s in %s:%lu", CA_MARKER, 1127 host_found->file, host_found->line); 1128 goto fail; 1129 } 1130 if (readonly == ROQUIET) 1131 goto fail; 1132 if (options.check_host_ip && host_ip_differ) { 1133 char *key_msg; 1134 if (ip_status == HOST_NEW) 1135 key_msg = "is unknown"; 1136 else if (ip_status == HOST_OK) 1137 key_msg = "is unchanged"; 1138 else 1139 key_msg = "has a different value"; 1140 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 1141 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); 1142 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 1143 error("The %s host key for %s has changed,", type, host); 1144 error("and the key for the corresponding IP address %s", ip); 1145 error("%s. This could either mean that", key_msg); 1146 error("DNS SPOOFING is happening or the IP address for the host"); 1147 error("and its host key have changed at the same time."); 1148 if (ip_status != HOST_NEW) 1149 error("Offending key for IP in %s:%lu", 1150 ip_found->file, ip_found->line); 1151 } 1152 /* The host key has changed. */ 1153 warn_changed_key(host_key); 1154 error("Add correct host key in %.100s to get rid of this message.", 1155 user_hostfiles[0]); 1156 error("Offending %s key in %s:%lu", 1157 sshkey_type(host_found->key), 1158 host_found->file, host_found->line); 1159 1160 /* 1161 * If strict host key checking is in use, the user will have 1162 * to edit the key manually and we can only abort. 1163 */ 1164 if (options.strict_host_key_checking != 1165 SSH_STRICT_HOSTKEY_OFF) { 1166 error("%s host key for %.200s has changed and you have " 1167 "requested strict checking.", type, host); 1168 goto fail; 1169 } 1170 1171 continue_unsafe: 1172 /* 1173 * If strict host key checking has not been requested, allow 1174 * the connection but without MITM-able authentication or 1175 * forwarding. 1176 */ 1177 if (options.password_authentication) { 1178 error("Password authentication is disabled to avoid " 1179 "man-in-the-middle attacks."); 1180 options.password_authentication = 0; 1181 cancelled_forwarding = 1; 1182 } 1183 if (options.kbd_interactive_authentication) { 1184 error("Keyboard-interactive authentication is disabled" 1185 " to avoid man-in-the-middle attacks."); 1186 options.kbd_interactive_authentication = 0; 1187 options.challenge_response_authentication = 0; 1188 cancelled_forwarding = 1; 1189 } 1190 if (options.challenge_response_authentication) { 1191 error("Challenge/response authentication is disabled" 1192 " to avoid man-in-the-middle attacks."); 1193 options.challenge_response_authentication = 0; 1194 cancelled_forwarding = 1; 1195 } 1196 if (options.forward_agent) { 1197 error("Agent forwarding is disabled to avoid " 1198 "man-in-the-middle attacks."); 1199 options.forward_agent = 0; 1200 cancelled_forwarding = 1; 1201 } 1202 if (options.forward_x11) { 1203 error("X11 forwarding is disabled to avoid " 1204 "man-in-the-middle attacks."); 1205 options.forward_x11 = 0; 1206 cancelled_forwarding = 1; 1207 } 1208 if (options.num_local_forwards > 0 || 1209 options.num_remote_forwards > 0) { 1210 error("Port forwarding is disabled to avoid " 1211 "man-in-the-middle attacks."); 1212 options.num_local_forwards = 1213 options.num_remote_forwards = 0; 1214 cancelled_forwarding = 1; 1215 } 1216 if (options.tun_open != SSH_TUNMODE_NO) { 1217 error("Tunnel forwarding is disabled to avoid " 1218 "man-in-the-middle attacks."); 1219 options.tun_open = SSH_TUNMODE_NO; 1220 cancelled_forwarding = 1; 1221 } 1222 if (options.exit_on_forward_failure && cancelled_forwarding) 1223 fatal("Error: forwarding disabled due to host key " 1224 "check failure"); 1225 1226 /* 1227 * XXX Should permit the user to change to use the new id. 1228 * This could be done by converting the host key to an 1229 * identifying sentence, tell that the host identifies itself 1230 * by that sentence, and ask the user if he/she wishes to 1231 * accept the authentication. 1232 */ 1233 break; 1234 case HOST_FOUND: 1235 fatal("internal error"); 1236 break; 1237 } 1238 1239 if (options.check_host_ip && host_status != HOST_CHANGED && 1240 ip_status == HOST_CHANGED) { 1241 snprintf(msg, sizeof(msg), 1242 "Warning: the %s host key for '%.200s' " 1243 "differs from the key for the IP address '%.128s'" 1244 "\nOffending key for IP in %s:%lu", 1245 type, host, ip, ip_found->file, ip_found->line); 1246 if (host_status == HOST_OK) { 1247 len = strlen(msg); 1248 snprintf(msg + len, sizeof(msg) - len, 1249 "\nMatching host key in %s:%lu", 1250 host_found->file, host_found->line); 1251 } 1252 if (options.strict_host_key_checking == 1253 SSH_STRICT_HOSTKEY_ASK) { 1254 strlcat(msg, "\nAre you sure you want " 1255 "to continue connecting (yes/no)? ", sizeof(msg)); 1256 if (!confirm(msg)) 1257 goto fail; 1258 } else if (options.strict_host_key_checking != 1259 SSH_STRICT_HOSTKEY_OFF) { 1260 logit("%s", msg); 1261 error("Exiting, you have requested strict checking."); 1262 goto fail; 1263 } else { 1264 logit("%s", msg); 1265 } 1266 } 1267 1268 if (!hostkey_trusted && options.update_hostkeys) { 1269 debug("%s: hostkey not known or explicitly trusted: " 1270 "disabling UpdateHostkeys", __func__); 1271 options.update_hostkeys = 0; 1272 } 1273 1274 free(ip); 1275 free(host); 1276 if (host_hostkeys != NULL) 1277 free_hostkeys(host_hostkeys); 1278 if (ip_hostkeys != NULL) 1279 free_hostkeys(ip_hostkeys); 1280 return 0; 1281 1282 fail: 1283 if (want_cert && host_status != HOST_REVOKED) { 1284 /* 1285 * No matching certificate. Downgrade cert to raw key and 1286 * search normally. 1287 */ 1288 debug("No matching CA found. Retry with plain key"); 1289 if ((r = sshkey_from_private(host_key, &raw_key)) != 0) 1290 fatal("%s: sshkey_from_private: %s", 1291 __func__, ssh_err(r)); 1292 if ((r = sshkey_drop_cert(raw_key)) != 0) 1293 fatal("Couldn't drop certificate: %s", ssh_err(r)); 1294 host_key = raw_key; 1295 goto retry; 1296 } 1297 sshkey_free(raw_key); 1298 free(ip); 1299 free(host); 1300 if (host_hostkeys != NULL) 1301 free_hostkeys(host_hostkeys); 1302 if (ip_hostkeys != NULL) 1303 free_hostkeys(ip_hostkeys); 1304 return -1; 1305 } 1306 1307 /* returns 0 if key verifies or -1 if key does NOT verify */ 1308 int 1309 verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key) 1310 { 1311 u_int i; 1312 int r = -1, flags = 0; 1313 char valid[64], *fp = NULL, *cafp = NULL; 1314 struct sshkey *plain = NULL; 1315 1316 if ((fp = sshkey_fingerprint(host_key, 1317 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { 1318 error("%s: fingerprint host key: %s", __func__, ssh_err(r)); 1319 r = -1; 1320 goto out; 1321 } 1322 1323 if (sshkey_is_cert(host_key)) { 1324 if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, 1325 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { 1326 error("%s: fingerprint CA key: %s", 1327 __func__, ssh_err(r)); 1328 r = -1; 1329 goto out; 1330 } 1331 sshkey_format_cert_validity(host_key->cert, 1332 valid, sizeof(valid)); 1333 debug("Server host certificate: %s %s, serial %llu " 1334 "ID \"%s\" CA %s %s valid %s", 1335 sshkey_ssh_name(host_key), fp, 1336 (unsigned long long)host_key->cert->serial, 1337 host_key->cert->key_id, 1338 sshkey_ssh_name(host_key->cert->signature_key), cafp, 1339 valid); 1340 for (i = 0; i < host_key->cert->nprincipals; i++) { 1341 debug2("Server host certificate hostname: %s", 1342 host_key->cert->principals[i]); 1343 } 1344 } else { 1345 debug("Server host key: %s %s", sshkey_ssh_name(host_key), fp); 1346 } 1347 1348 if (sshkey_equal(previous_host_key, host_key)) { 1349 debug2("%s: server host key %s %s matches cached key", 1350 __func__, sshkey_type(host_key), fp); 1351 r = 0; 1352 goto out; 1353 } 1354 1355 /* Check in RevokedHostKeys file if specified */ 1356 if (options.revoked_host_keys != NULL) { 1357 r = sshkey_check_revoked(host_key, options.revoked_host_keys); 1358 switch (r) { 1359 case 0: 1360 break; /* not revoked */ 1361 case SSH_ERR_KEY_REVOKED: 1362 error("Host key %s %s revoked by file %s", 1363 sshkey_type(host_key), fp, 1364 options.revoked_host_keys); 1365 r = -1; 1366 goto out; 1367 default: 1368 error("Error checking host key %s %s in " 1369 "revoked keys file %s: %s", sshkey_type(host_key), 1370 fp, options.revoked_host_keys, ssh_err(r)); 1371 r = -1; 1372 goto out; 1373 } 1374 } 1375 1376 if (options.verify_host_key_dns) { 1377 /* 1378 * XXX certs are not yet supported for DNS, so downgrade 1379 * them and try the plain key. 1380 */ 1381 if ((r = sshkey_from_private(host_key, &plain)) != 0) 1382 goto out; 1383 if (sshkey_is_cert(plain)) 1384 sshkey_drop_cert(plain); 1385 if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { 1386 if (flags & DNS_VERIFY_FOUND) { 1387 if (options.verify_host_key_dns == 1 && 1388 flags & DNS_VERIFY_MATCH && 1389 flags & DNS_VERIFY_SECURE) { 1390 r = 0; 1391 goto out; 1392 } 1393 if (flags & DNS_VERIFY_MATCH) { 1394 matching_host_key_dns = 1; 1395 } else { 1396 warn_changed_key(plain); 1397 error("Update the SSHFP RR in DNS " 1398 "with the new host key to get rid " 1399 "of this message."); 1400 } 1401 } 1402 } 1403 } 1404 r = check_host_key(host, hostaddr, options.port, host_key, RDRW, 1405 options.user_hostfiles, options.num_user_hostfiles, 1406 options.system_hostfiles, options.num_system_hostfiles); 1407 1408 out: 1409 sshkey_free(plain); 1410 free(fp); 1411 free(cafp); 1412 if (r == 0 && host_key != NULL) { 1413 sshkey_free(previous_host_key); 1414 r = sshkey_from_private(host_key, &previous_host_key); 1415 } 1416 1417 return r; 1418 } 1419 1420 /* 1421 * Starts a dialog with the server, and authenticates the current user on the 1422 * server. This does not need any extra privileges. The basic connection 1423 * to the server must already have been established before this is called. 1424 * If login fails, this function prints an error and never returns. 1425 * This function does not require super-user privileges. 1426 */ 1427 void 1428 ssh_login(Sensitive *sensitive, const char *orighost, 1429 struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) 1430 { 1431 char *host; 1432 char *server_user, *local_user; 1433 1434 local_user = xstrdup(pw->pw_name); 1435 server_user = options.user ? options.user : local_user; 1436 1437 /* Convert the user-supplied hostname into all lowercase. */ 1438 host = xstrdup(orighost); 1439 lowercase(host); 1440 1441 /* Exchange protocol version identification strings with the server. */ 1442 ssh_exchange_identification(timeout_ms); 1443 1444 /* Put the connection into non-blocking mode. */ 1445 packet_set_nonblocking(); 1446 1447 /* key exchange */ 1448 /* authenticate user */ 1449 debug("Authenticating to %s:%d as '%s'", host, port, server_user); 1450 ssh_kex2(host, hostaddr, port); 1451 ssh_userauth2(local_user, server_user, host, sensitive); 1452 free(local_user); 1453 } 1454 1455 void 1456 ssh_put_password(char *password) 1457 { 1458 int size; 1459 char *padded; 1460 1461 if (datafellows & SSH_BUG_PASSWORDPAD) { 1462 packet_put_cstring(password); 1463 return; 1464 } 1465 size = ROUNDUP(strlen(password) + 1, 32); 1466 padded = xcalloc(1, size); 1467 strlcpy(padded, password, size); 1468 packet_put_string(padded, size); 1469 explicit_bzero(padded, size); 1470 free(padded); 1471 } 1472 1473 /* print all known host keys for a given host, but skip keys of given type */ 1474 static int 1475 show_other_keys(struct hostkeys *hostkeys, struct sshkey *key) 1476 { 1477 int type[] = { 1478 KEY_RSA, 1479 KEY_DSA, 1480 KEY_ECDSA, 1481 KEY_ED25519, 1482 KEY_XMSS, 1483 -1 1484 }; 1485 int i, ret = 0; 1486 char *fp, *ra; 1487 const struct hostkey_entry *found; 1488 1489 for (i = 0; type[i] != -1; i++) { 1490 if (type[i] == key->type) 1491 continue; 1492 if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) 1493 continue; 1494 fp = sshkey_fingerprint(found->key, 1495 options.fingerprint_hash, SSH_FP_DEFAULT); 1496 ra = sshkey_fingerprint(found->key, 1497 options.fingerprint_hash, SSH_FP_RANDOMART); 1498 if (fp == NULL || ra == NULL) 1499 fatal("%s: sshkey_fingerprint fail", __func__); 1500 logit("WARNING: %s key found for host %s\n" 1501 "in %s:%lu\n" 1502 "%s key fingerprint %s.", 1503 key_type(found->key), 1504 found->host, found->file, found->line, 1505 key_type(found->key), fp); 1506 if (options.visual_host_key) 1507 logit("%s", ra); 1508 free(ra); 1509 free(fp); 1510 ret = 1; 1511 } 1512 return ret; 1513 } 1514 1515 static void 1516 warn_changed_key(struct sshkey *host_key) 1517 { 1518 char *fp; 1519 1520 fp = sshkey_fingerprint(host_key, options.fingerprint_hash, 1521 SSH_FP_DEFAULT); 1522 if (fp == NULL) 1523 fatal("%s: sshkey_fingerprint fail", __func__); 1524 1525 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 1526 error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); 1527 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 1528 error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); 1529 error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); 1530 error("It is also possible that a host key has just been changed."); 1531 error("The fingerprint for the %s key sent by the remote host is\n%s.", 1532 key_type(host_key), fp); 1533 error("Please contact your system administrator."); 1534 1535 free(fp); 1536 } 1537 1538 /* 1539 * Execute a local command 1540 */ 1541 int 1542 ssh_local_cmd(const char *args) 1543 { 1544 char *shell; 1545 pid_t pid; 1546 int status; 1547 void (*osighand)(int); 1548 1549 if (!options.permit_local_command || 1550 args == NULL || !*args) 1551 return (1); 1552 1553 if ((shell = getenv("SHELL")) == NULL || *shell == '\0') 1554 shell = _PATH_BSHELL; 1555 1556 osighand = signal(SIGCHLD, SIG_DFL); 1557 pid = fork(); 1558 if (pid == 0) { 1559 signal(SIGPIPE, SIG_DFL); 1560 debug3("Executing %s -c \"%s\"", shell, args); 1561 execl(shell, shell, "-c", args, (char *)NULL); 1562 error("Couldn't execute %s -c \"%s\": %s", 1563 shell, args, strerror(errno)); 1564 _exit(1); 1565 } else if (pid == -1) 1566 fatal("fork failed: %.100s", strerror(errno)); 1567 while (waitpid(pid, &status, 0) == -1) 1568 if (errno != EINTR) 1569 fatal("Couldn't wait for child: %s", strerror(errno)); 1570 signal(SIGCHLD, osighand); 1571 1572 if (!WIFEXITED(status)) 1573 return (1); 1574 1575 return (WEXITSTATUS(status)); 1576 } 1577 1578 void 1579 maybe_add_key_to_agent(char *authfile, const struct sshkey *private, 1580 char *comment, char *passphrase) 1581 { 1582 int auth_sock = -1, r; 1583 1584 if (options.add_keys_to_agent == 0) 1585 return; 1586 1587 if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { 1588 debug3("no authentication agent, not adding key"); 1589 return; 1590 } 1591 1592 if (options.add_keys_to_agent == 2 && 1593 !ask_permission("Add key %s (%s) to agent?", authfile, comment)) { 1594 debug3("user denied adding this key"); 1595 close(auth_sock); 1596 return; 1597 } 1598 1599 if ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0, 1600 (options.add_keys_to_agent == 3), 0)) == 0) 1601 debug("identity added to agent: %s", authfile); 1602 else 1603 debug("could not add identity to agent: %s (%d)", authfile, r); 1604 close(auth_sock); 1605 } 1606