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 #include "includes.h" 16 RCSID("$OpenBSD: sshconnect.c,v 1.119 2002/01/21 15:13:51 markus Exp $"); 17 RCSID("$FreeBSD$"); 18 19 #include <openssl/bn.h> 20 21 #include "ssh.h" 22 #include "xmalloc.h" 23 #include "rsa.h" 24 #include "buffer.h" 25 #include "packet.h" 26 #include "uidswap.h" 27 #include "compat.h" 28 #include "key.h" 29 #include "sshconnect.h" 30 #include "hostfile.h" 31 #include "log.h" 32 #include "readconf.h" 33 #include "atomicio.h" 34 #include "misc.h" 35 #include "readpass.h" 36 37 char *client_version_string = NULL; 38 char *server_version_string = NULL; 39 40 extern Options options; 41 extern char *__progname; 42 43 static const char * 44 sockaddr_ntop(struct sockaddr *sa) 45 { 46 void *addr; 47 static char addrbuf[INET6_ADDRSTRLEN]; 48 49 switch (sa->sa_family) { 50 case AF_INET: 51 addr = &((struct sockaddr_in *)sa)->sin_addr; 52 break; 53 case AF_INET6: 54 addr = &((struct sockaddr_in6 *)sa)->sin6_addr; 55 break; 56 default: 57 /* This case should be protected against elsewhere */ 58 abort(); /* XXX abort is bad -- do something else */ 59 } 60 inet_ntop(sa->sa_family, addr, addrbuf, sizeof(addrbuf)); 61 return addrbuf; 62 } 63 64 /* 65 * Connect to the given ssh server using a proxy command. 66 */ 67 static int 68 ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, 69 const char *proxy_command) 70 { 71 Buffer command; 72 const char *cp; 73 char *command_string; 74 int pin[2], pout[2]; 75 pid_t pid; 76 char strport[NI_MAXSERV]; 77 78 /* Convert the port number into a string. */ 79 snprintf(strport, sizeof strport, "%hu", port); 80 81 /* Build the final command string in the buffer by making the 82 appropriate substitutions to the given proxy command. */ 83 buffer_init(&command); 84 for (cp = proxy_command; *cp; cp++) { 85 if (cp[0] == '%' && cp[1] == '%') { 86 buffer_append(&command, "%", 1); 87 cp++; 88 continue; 89 } 90 if (cp[0] == '%' && cp[1] == 'h') { 91 buffer_append(&command, host, strlen(host)); 92 cp++; 93 continue; 94 } 95 if (cp[0] == '%' && cp[1] == 'p') { 96 buffer_append(&command, strport, strlen(strport)); 97 cp++; 98 continue; 99 } 100 buffer_append(&command, cp, 1); 101 } 102 buffer_append(&command, "\0", 1); 103 104 /* Get the final command string. */ 105 command_string = buffer_ptr(&command); 106 107 /* Create pipes for communicating with the proxy. */ 108 if (pipe(pin) < 0 || pipe(pout) < 0) 109 fatal("Could not create pipes to communicate with the proxy: %.100s", 110 strerror(errno)); 111 112 debug("Executing proxy command: %.500s", command_string); 113 114 /* Fork and execute the proxy command. */ 115 if ((pid = fork()) == 0) { 116 char *argv[10]; 117 118 /* Child. Permanently give up superuser privileges. */ 119 permanently_set_uid(pw); 120 121 /* Redirect stdin and stdout. */ 122 close(pin[1]); 123 if (pin[0] != 0) { 124 if (dup2(pin[0], 0) < 0) 125 perror("dup2 stdin"); 126 close(pin[0]); 127 } 128 close(pout[0]); 129 if (dup2(pout[1], 1) < 0) 130 perror("dup2 stdout"); 131 /* Cannot be 1 because pin allocated two descriptors. */ 132 close(pout[1]); 133 134 /* Stderr is left as it is so that error messages get 135 printed on the user's terminal. */ 136 argv[0] = _PATH_BSHELL; 137 argv[1] = "-c"; 138 argv[2] = command_string; 139 argv[3] = NULL; 140 141 /* Execute the proxy command. Note that we gave up any 142 extra privileges above. */ 143 execv(argv[0], argv); 144 perror(argv[0]); 145 exit(1); 146 } 147 /* Parent. */ 148 if (pid < 0) 149 fatal("fork failed: %.100s", strerror(errno)); 150 151 /* Close child side of the descriptors. */ 152 close(pin[0]); 153 close(pout[1]); 154 155 /* Free the command name. */ 156 buffer_free(&command); 157 158 /* Set the connection file descriptors. */ 159 packet_set_connection(pout[0], pin[1]); 160 161 /* Indicate OK return */ 162 return 0; 163 } 164 165 /* 166 * Creates a (possibly privileged) socket for use as the ssh connection. 167 */ 168 static int 169 ssh_create_socket(struct passwd *pw, int privileged, int family) 170 { 171 int sock, gaierr; 172 struct addrinfo hints, *res; 173 174 /* 175 * If we are running as root and want to connect to a privileged 176 * port, bind our own socket to a privileged port. 177 */ 178 if (privileged) { 179 int p = IPPORT_RESERVED - 1; 180 sock = rresvport_af(&p, family); 181 if (sock < 0) 182 error("rresvport: af=%d %.100s", family, strerror(errno)); 183 else 184 debug("Allocated local port %d.", p); 185 return sock; 186 } 187 /* 188 * Just create an ordinary socket on arbitrary port. We use 189 * the user's uid to create the socket. 190 */ 191 temporarily_use_uid(pw); 192 sock = socket(family, SOCK_STREAM, 0); 193 if (sock < 0) 194 error("socket: %.100s", strerror(errno)); 195 restore_uid(); 196 197 /* Bind the socket to an alternative local IP address */ 198 if (options.bind_address == NULL) 199 return sock; 200 201 memset(&hints, 0, sizeof(hints)); 202 hints.ai_family = family; 203 hints.ai_socktype = SOCK_STREAM; 204 hints.ai_flags = AI_PASSIVE; 205 gaierr = getaddrinfo(options.bind_address, "0", &hints, &res); 206 if (gaierr) { 207 error("getaddrinfo: %s: %s", options.bind_address, 208 gai_strerror(gaierr)); 209 close(sock); 210 return -1; 211 } 212 if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { 213 error("bind: %s: %s", options.bind_address, strerror(errno)); 214 close(sock); 215 freeaddrinfo(res); 216 return -1; 217 } 218 freeaddrinfo(res); 219 return sock; 220 } 221 222 /* 223 * Opens a TCP/IP connection to the remote server on the given host. 224 * The address of the remote host will be returned in hostaddr. 225 * If port is 0, the default port will be used. If anonymous is zero, 226 * a privileged port will be allocated to make the connection. 227 * This requires super-user privileges if anonymous is false. 228 * Connection_attempts specifies the maximum number of tries (one per 229 * second). If proxy_command is non-NULL, it specifies the command (with %h 230 * and %p substituted for host and port, respectively) to use to contact 231 * the daemon. 232 * Return values: 233 * 0 for OK 234 * ECONNREFUSED if we got a "Connection Refused" by the peer on any address 235 * ECONNABORTED if we failed without a "Connection refused" 236 * Suitable error messages for the connection failure will already have been 237 * printed. 238 */ 239 int 240 ssh_connect(const char *host, struct sockaddr_storage * hostaddr, 241 u_short port, int family, int connection_attempts, 242 int anonymous, struct passwd *pw, const char *proxy_command) 243 { 244 int gaierr; 245 int on = 1; 246 int sock = -1, attempt; 247 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 248 struct addrinfo hints, *ai, *aitop; 249 struct linger linger; 250 struct servent *sp; 251 /* 252 * Did we get only other errors than "Connection refused" (which 253 * should block fallback to rsh and similar), or did we get at least 254 * one "Connection refused"? 255 */ 256 int full_failure = 1; 257 258 debug("ssh_connect: getuid %u geteuid %u anon %d", 259 (u_int) getuid(), (u_int) geteuid(), anonymous); 260 261 /* Get default port if port has not been set. */ 262 if (port == 0) { 263 sp = getservbyname(SSH_SERVICE_NAME, "tcp"); 264 if (sp) 265 port = ntohs(sp->s_port); 266 else 267 port = SSH_DEFAULT_PORT; 268 } 269 /* If a proxy command is given, connect using it. */ 270 if (proxy_command != NULL) 271 return ssh_proxy_connect(host, port, pw, proxy_command); 272 273 /* No proxy command. */ 274 275 memset(&hints, 0, sizeof(hints)); 276 hints.ai_family = family; 277 hints.ai_socktype = SOCK_STREAM; 278 snprintf(strport, sizeof strport, "%d", port); 279 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) 280 fatal("%s: %.100s: %s", __progname, host, 281 gai_strerror(gaierr)); 282 283 /* 284 * Try to connect several times. On some machines, the first time 285 * will sometimes fail. In general socket code appears to behave 286 * quite magically on many machines. 287 */ 288 for (attempt = 0; ;) { 289 if (attempt > 0) 290 debug("Trying again..."); 291 292 /* Loop through addresses for this host, and try each one in 293 sequence until the connection succeeds. */ 294 for (ai = aitop; ai; ai = ai->ai_next) { 295 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 296 continue; 297 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, 298 ntop, sizeof(ntop), strport, sizeof(strport), 299 NI_NUMERICHOST|NI_NUMERICSERV) != 0) { 300 error("ssh_connect: getnameinfo failed"); 301 continue; 302 } 303 debug("Connecting to %.200s [%.100s] port %s.", 304 host, ntop, strport); 305 306 /* Create a socket for connecting. */ 307 sock = ssh_create_socket(pw, 308 !anonymous && geteuid() == 0, 309 ai->ai_family); 310 if (sock < 0) 311 /* Any error is already output */ 312 continue; 313 314 /* Connect to the host. We use the user's uid in the 315 * hope that it will help with tcp_wrappers showing 316 * the remote uid as root. 317 */ 318 temporarily_use_uid(pw); 319 if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { 320 /* Successful connection. */ 321 memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); 322 restore_uid(); 323 break; 324 } else { 325 if (errno == ECONNREFUSED) 326 full_failure = 0; 327 log("ssh: connect to address %s port %s: %s", 328 sockaddr_ntop(ai->ai_addr), strport, 329 strerror(errno)); 330 restore_uid(); 331 /* 332 * Close the failed socket; there appear to 333 * be some problems when reusing a socket for 334 * which connect() has already returned an 335 * error. 336 */ 337 close(sock); 338 } 339 } 340 if (ai) 341 break; /* Successful connection. */ 342 343 attempt++; 344 if (attempt >= connection_attempts) 345 break; 346 /* Sleep a moment before retrying. */ 347 sleep(1); 348 } 349 350 freeaddrinfo(aitop); 351 352 /* Return failure if we didn't get a successful connection. */ 353 if (attempt >= connection_attempts) 354 return full_failure ? ECONNABORTED : ECONNREFUSED; 355 356 debug("Connection established."); 357 358 /* 359 * Set socket options. We would like the socket to disappear as soon 360 * as it has been closed for whatever reason. 361 */ 362 /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ 363 linger.l_onoff = 1; 364 linger.l_linger = 5; 365 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger)); 366 367 /* Set keepalives if requested. */ 368 if (options.keepalives && 369 setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, 370 sizeof(on)) < 0) 371 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 372 373 /* Set the connection. */ 374 packet_set_connection(sock, sock); 375 376 return 0; 377 } 378 379 /* 380 * Waits for the server identification string, and sends our own 381 * identification string. 382 */ 383 static void 384 ssh_exchange_identification(void) 385 { 386 char buf[256], remote_version[256]; /* must be same size! */ 387 int remote_major, remote_minor, i, mismatch; 388 int connection_in = packet_get_connection_in(); 389 int connection_out = packet_get_connection_out(); 390 int minor1 = PROTOCOL_MINOR_1; 391 392 /* Read other side\'s version identification. */ 393 for (;;) { 394 for (i = 0; i < sizeof(buf) - 1; i++) { 395 int len = atomicio(read, connection_in, &buf[i], 1); 396 if (len < 0) 397 fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); 398 if (len != 1) 399 fatal("ssh_exchange_identification: Connection closed by remote host"); 400 if (buf[i] == '\r') { 401 buf[i] = '\n'; 402 buf[i + 1] = 0; 403 continue; /**XXX wait for \n */ 404 } 405 if (buf[i] == '\n') { 406 buf[i + 1] = 0; 407 break; 408 } 409 } 410 buf[sizeof(buf) - 1] = 0; 411 if (strncmp(buf, "SSH-", 4) == 0) 412 break; 413 debug("ssh_exchange_identification: %s", buf); 414 } 415 server_version_string = xstrdup(buf); 416 417 /* 418 * Check that the versions match. In future this might accept 419 * several versions and set appropriate flags to handle them. 420 */ 421 if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", 422 &remote_major, &remote_minor, remote_version) != 3) 423 fatal("Bad remote protocol version identification: '%.100s'", buf); 424 debug("Remote protocol version %d.%d, remote software version %.100s", 425 remote_major, remote_minor, remote_version); 426 427 compat_datafellows(remote_version); 428 mismatch = 0; 429 430 switch (remote_major) { 431 case 1: 432 if (remote_minor == 99 && 433 (options.protocol & SSH_PROTO_2) && 434 !(options.protocol & SSH_PROTO_1_PREFERRED)) { 435 enable_compat20(); 436 break; 437 } 438 if (!(options.protocol & SSH_PROTO_1)) { 439 mismatch = 1; 440 break; 441 } 442 if (remote_minor < 3) { 443 fatal("Remote machine has too old SSH software version."); 444 } else if (remote_minor == 3 || remote_minor == 4) { 445 /* We speak 1.3, too. */ 446 enable_compat13(); 447 minor1 = 3; 448 if (options.forward_agent) { 449 log("Agent forwarding disabled for protocol 1.3"); 450 options.forward_agent = 0; 451 } 452 } 453 break; 454 case 2: 455 if (options.protocol & SSH_PROTO_2) { 456 enable_compat20(); 457 break; 458 } 459 /* FALLTHROUGH */ 460 default: 461 mismatch = 1; 462 break; 463 } 464 if (mismatch) 465 fatal("Protocol major versions differ: %d vs. %d", 466 (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, 467 remote_major); 468 /* Send our own protocol version identification. */ 469 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", 470 compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, 471 compat20 ? PROTOCOL_MINOR_2 : minor1, 472 SSH_VERSION); 473 if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) 474 fatal("write: %.100s", strerror(errno)); 475 client_version_string = xstrdup(buf); 476 chop(client_version_string); 477 chop(server_version_string); 478 debug("Local version string %.100s", client_version_string); 479 } 480 481 /* defaults to 'no' */ 482 static int 483 confirm(const char *prompt) 484 { 485 const char *msg, *again = "Please type 'yes' or 'no': "; 486 char *p; 487 int ret = -1; 488 489 if (options.batch_mode) 490 return 0; 491 for (msg = prompt;;msg = again) { 492 p = read_passphrase(msg, RP_ECHO); 493 if (p == NULL || 494 (p[0] == '\0') || (p[0] == '\n') || 495 strncasecmp(p, "no", 2) == 0) 496 ret = 0; 497 if (strncasecmp(p, "yes", 3) == 0) 498 ret = 1; 499 if (p) 500 xfree(p); 501 if (ret != -1) 502 return ret; 503 } 504 } 505 506 /* 507 * check whether the supplied host key is valid, return -1 if the key 508 * is not valid. the user_hostfile will not be updated if 'readonly' is true. 509 */ 510 511 static int 512 check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, 513 int readonly, const char *user_hostfile, const char *system_hostfile) 514 { 515 Key *file_key; 516 char *type = key_type(host_key); 517 char *ip = NULL; 518 char hostline[1000], *hostp, *fp; 519 HostStatus host_status; 520 HostStatus ip_status; 521 int local = 0, host_ip_differ = 0; 522 char ntop[NI_MAXHOST]; 523 char msg[1024]; 524 int len, host_line, ip_line; 525 const char *host_file = NULL, *ip_file = NULL; 526 527 /* 528 * Force accepting of the host key for loopback/localhost. The 529 * problem is that if the home directory is NFS-mounted to multiple 530 * machines, localhost will refer to a different machine in each of 531 * them, and the user will get bogus HOST_CHANGED warnings. This 532 * essentially disables host authentication for localhost; however, 533 * this is probably not a real problem. 534 */ 535 /** hostaddr == 0! */ 536 switch (hostaddr->sa_family) { 537 case AF_INET: 538 local = (ntohl(((struct sockaddr_in *)hostaddr)-> 539 sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; 540 break; 541 case AF_INET6: 542 local = IN6_IS_ADDR_LOOPBACK( 543 &(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); 544 break; 545 default: 546 local = 0; 547 break; 548 } 549 if (options.no_host_authentication_for_localhost == 1 && local && 550 options.host_key_alias == NULL) { 551 debug("Forcing accepting of host key for " 552 "loopback/localhost."); 553 return 0; 554 } 555 556 /* 557 * We don't have the remote ip-address for connections 558 * using a proxy command 559 */ 560 if (options.proxy_command == NULL) { 561 if (getnameinfo(hostaddr, hostaddr->sa_len, ntop, sizeof(ntop), 562 NULL, 0, NI_NUMERICHOST) != 0) 563 fatal("check_host_key: getnameinfo failed"); 564 ip = xstrdup(ntop); 565 } else { 566 ip = xstrdup("<no hostip for proxy command>"); 567 } 568 /* 569 * Turn off check_host_ip if the connection is to localhost, via proxy 570 * command or if we don't have a hostname to compare with 571 */ 572 if (options.check_host_ip && 573 (local || strcmp(host, ip) == 0 || options.proxy_command != NULL)) 574 options.check_host_ip = 0; 575 576 /* 577 * Allow the user to record the key under a different name. This is 578 * useful for ssh tunneling over forwarded connections or if you run 579 * multiple sshd's on different ports on the same machine. 580 */ 581 if (options.host_key_alias != NULL) { 582 host = options.host_key_alias; 583 debug("using hostkeyalias: %s", host); 584 } 585 586 /* 587 * Store the host key from the known host file in here so that we can 588 * compare it with the key for the IP address. 589 */ 590 file_key = key_new(host_key->type); 591 592 /* 593 * Check if the host key is present in the user\'s list of known 594 * hosts or in the systemwide list. 595 */ 596 host_file = user_hostfile; 597 host_status = check_host_in_hostfile(host_file, host, host_key, 598 file_key, &host_line); 599 if (host_status == HOST_NEW) { 600 host_file = system_hostfile; 601 host_status = check_host_in_hostfile(host_file, host, host_key, 602 file_key, &host_line); 603 } 604 /* 605 * Also perform check for the ip address, skip the check if we are 606 * localhost or the hostname was an ip address to begin with 607 */ 608 if (options.check_host_ip) { 609 Key *ip_key = key_new(host_key->type); 610 611 ip_file = user_hostfile; 612 ip_status = check_host_in_hostfile(ip_file, ip, host_key, 613 ip_key, &ip_line); 614 if (ip_status == HOST_NEW) { 615 ip_file = system_hostfile; 616 ip_status = check_host_in_hostfile(ip_file, ip, 617 host_key, ip_key, &ip_line); 618 } 619 if (host_status == HOST_CHANGED && 620 (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key))) 621 host_ip_differ = 1; 622 623 key_free(ip_key); 624 } else 625 ip_status = host_status; 626 627 key_free(file_key); 628 629 switch (host_status) { 630 case HOST_OK: 631 /* The host is known and the key matches. */ 632 debug("Host '%.200s' is known and matches the %s host key.", 633 host, type); 634 debug("Found key in %s:%d", host_file, host_line); 635 if (options.check_host_ip && ip_status == HOST_NEW) { 636 if (readonly) 637 log("%s host key for IP address " 638 "'%.128s' not in list of known hosts.", 639 type, ip); 640 else if (!add_host_to_hostfile(user_hostfile, ip, 641 host_key)) 642 log("Failed to add the %s host key for IP " 643 "address '%.128s' to the list of known " 644 "hosts (%.30s).", type, ip, user_hostfile); 645 else 646 log("Warning: Permanently added the %s host " 647 "key for IP address '%.128s' to the list " 648 "of known hosts.", type, ip); 649 } 650 break; 651 case HOST_NEW: 652 if (readonly) 653 goto fail; 654 /* The host is new. */ 655 if (options.strict_host_key_checking == 1) { 656 /* 657 * User has requested strict host key checking. We 658 * will not add the host key automatically. The only 659 * alternative left is to abort. 660 */ 661 error("No %s host key is known for %.200s and you " 662 "have requested strict checking.", type, host); 663 goto fail; 664 } else if (options.strict_host_key_checking == 2) { 665 /* The default */ 666 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); 667 snprintf(msg, sizeof(msg), 668 "The authenticity of host '%.200s (%s)' can't be " 669 "established.\n" 670 "%s key fingerprint is %s.\n" 671 "Are you sure you want to continue connecting " 672 "(yes/no)? ", host, ip, type, fp); 673 xfree(fp); 674 if (!confirm(msg)) 675 goto fail; 676 } 677 if (options.check_host_ip && ip_status == HOST_NEW) { 678 snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); 679 hostp = hostline; 680 } else 681 hostp = host; 682 683 /* 684 * If not in strict mode, add the key automatically to the 685 * local known_hosts file. 686 */ 687 if (!add_host_to_hostfile(user_hostfile, hostp, host_key)) 688 log("Failed to add the host to the list of known " 689 "hosts (%.500s).", user_hostfile); 690 else 691 log("Warning: Permanently added '%.200s' (%s) to the " 692 "list of known hosts.", hostp, type); 693 break; 694 case HOST_CHANGED: 695 if (options.check_host_ip && host_ip_differ) { 696 char *msg; 697 if (ip_status == HOST_NEW) 698 msg = "is unknown"; 699 else if (ip_status == HOST_OK) 700 msg = "is unchanged"; 701 else 702 msg = "has a different value"; 703 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 704 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); 705 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 706 error("The %s host key for %s has changed,", type, host); 707 error("and the key for the according IP address %s", ip); 708 error("%s. This could either mean that", msg); 709 error("DNS SPOOFING is happening or the IP address for the host"); 710 error("and its host key have changed at the same time."); 711 if (ip_status != HOST_NEW) 712 error("Offending key for IP in %s:%d", ip_file, ip_line); 713 } 714 /* The host key has changed. */ 715 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); 716 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 717 error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); 718 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 719 error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); 720 error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); 721 error("It is also possible that the %s host key has just been changed.", type); 722 error("The fingerprint for the %s key sent by the remote host is\n%s.", 723 type, fp); 724 error("Please contact your system administrator."); 725 error("Add correct host key in %.100s to get rid of this message.", 726 user_hostfile); 727 error("Offending key in %s:%d", host_file, host_line); 728 xfree(fp); 729 730 /* 731 * If strict host key checking is in use, the user will have 732 * to edit the key manually and we can only abort. 733 */ 734 if (options.strict_host_key_checking) { 735 error("%s host key for %.200s has changed and you have " 736 "requested strict checking.", type, host); 737 goto fail; 738 } 739 740 /* 741 * If strict host key checking has not been requested, allow 742 * the connection but without password authentication or 743 * agent forwarding. 744 */ 745 if (options.password_authentication) { 746 error("Password authentication is disabled to avoid " 747 "man-in-the-middle attacks."); 748 options.password_authentication = 0; 749 } 750 if (options.forward_agent) { 751 error("Agent forwarding is disabled to avoid " 752 "man-in-the-middle attacks."); 753 options.forward_agent = 0; 754 } 755 if (options.forward_x11) { 756 error("X11 forwarding is disabled to avoid " 757 "man-in-the-middle attacks."); 758 options.forward_x11 = 0; 759 } 760 if (options.num_local_forwards > 0 || 761 options.num_remote_forwards > 0) { 762 error("Port forwarding is disabled to avoid " 763 "man-in-the-middle attacks."); 764 options.num_local_forwards = 765 options.num_remote_forwards = 0; 766 } 767 /* 768 * XXX Should permit the user to change to use the new id. 769 * This could be done by converting the host key to an 770 * identifying sentence, tell that the host identifies itself 771 * by that sentence, and ask the user if he/she whishes to 772 * accept the authentication. 773 */ 774 break; 775 } 776 777 if (options.check_host_ip && host_status != HOST_CHANGED && 778 ip_status == HOST_CHANGED) { 779 snprintf(msg, sizeof(msg), 780 "Warning: the %s host key for '%.200s' " 781 "differs from the key for the IP address '%.128s'" 782 "\nOffending key for IP in %s:%d", 783 type, host, ip, ip_file, ip_line); 784 if (host_status == HOST_OK) { 785 len = strlen(msg); 786 snprintf(msg + len, sizeof(msg) - len, 787 "\nMatching host key in %s:%d", 788 host_file, host_line); 789 } 790 if (options.strict_host_key_checking == 1) { 791 log(msg); 792 error("Exiting, you have requested strict checking."); 793 goto fail; 794 } else if (options.strict_host_key_checking == 2) { 795 strlcat(msg, "\nAre you sure you want " 796 "to continue connecting (yes/no)? ", sizeof(msg)); 797 if (!confirm(msg)) 798 goto fail; 799 } else { 800 log(msg); 801 } 802 } 803 804 xfree(ip); 805 return 0; 806 807 fail: 808 xfree(ip); 809 return -1; 810 } 811 812 int 813 verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) 814 { 815 struct stat st; 816 817 /* return ok if the key can be found in an old keyfile */ 818 if (stat(options.system_hostfile2, &st) == 0 || 819 stat(options.user_hostfile2, &st) == 0) { 820 if (check_host_key(host, hostaddr, host_key, /*readonly*/ 1, 821 options.user_hostfile2, options.system_hostfile2) == 0) 822 return 0; 823 } 824 return check_host_key(host, hostaddr, host_key, /*readonly*/ 0, 825 options.user_hostfile, options.system_hostfile); 826 } 827 828 /* 829 * Starts a dialog with the server, and authenticates the current user on the 830 * server. This does not need any extra privileges. The basic connection 831 * to the server must already have been established before this is called. 832 * If login fails, this function prints an error and never returns. 833 * This function does not require super-user privileges. 834 */ 835 void 836 ssh_login(Key **keys, int nkeys, const char *orighost, 837 struct sockaddr *hostaddr, struct passwd *pw) 838 { 839 char *host, *cp; 840 char *server_user, *local_user; 841 842 local_user = xstrdup(pw->pw_name); 843 server_user = options.user ? options.user : local_user; 844 845 /* Convert the user-supplied hostname into all lowercase. */ 846 host = xstrdup(orighost); 847 for (cp = host; *cp; cp++) 848 if (isupper(*cp)) 849 *cp = tolower(*cp); 850 851 /* Exchange protocol version identification strings with the server. */ 852 ssh_exchange_identification(); 853 854 /* Put the connection into non-blocking mode. */ 855 packet_set_nonblocking(); 856 857 /* key exchange */ 858 /* authenticate user */ 859 if (compat20) { 860 ssh_kex2(host, hostaddr); 861 ssh_userauth2(local_user, server_user, host, keys, nkeys); 862 } else { 863 ssh_kex(host, hostaddr); 864 ssh_userauth1(local_user, server_user, host, keys, nkeys); 865 } 866 } 867 868 void 869 ssh_put_password(char *password) 870 { 871 int size; 872 char *padded; 873 874 if (datafellows & SSH_BUG_PASSWORDPAD) { 875 packet_put_cstring(password); 876 return; 877 } 878 size = roundup(strlen(password) + 1, 32); 879 padded = xmalloc(size); 880 memset(padded, 0, size); 881 strlcpy(padded, password, size); 882 packet_put_string(padded, size); 883 memset(padded, 0, size); 884 xfree(padded); 885 } 886