=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sshconnect.c,v retrieving revision 1.147.2.2 retrieving revision 1.148 diff -u -r1.147.2.2 -r1.148 --- src/usr.bin/ssh/sshconnect.c 2004/08/19 22:37:32 1.147.2.2 +++ src/usr.bin/ssh/sshconnect.c 2003/09/18 07:52:54 1.148 @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.147.2.2 2004/08/19 22:37:32 brad Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.148 2003/09/18 07:52:54 markus Exp $"); #include @@ -31,13 +31,18 @@ #include "readconf.h" #include "atomicio.h" #include "misc.h" +#include "readpass.h" +#ifdef DNS #include "dns.h" +#endif char *client_version_string = NULL; char *server_version_string = NULL; -int matching_host_key_dns = 0; +#ifdef DNS +int verified_host_key_dns = 0; +#endif /* import */ extern Options options; @@ -47,7 +52,6 @@ extern pid_t proxy_command_pid; static int show_other_keys(const char *, Key *); -static void warn_changed_key(Key *); /* * Connect to the given ssh server using a proxy command. @@ -69,7 +73,7 @@ * Build the final command string in the buffer by making the * appropriate substitutions to the given proxy command. * - * Use "exec" to avoid "sh -c" processes on some platforms + * Use "exec" to avoid "sh -c" processes on some platforms * (e.g. Solaris) */ buffer_init(&command); @@ -226,12 +230,12 @@ if (timeout <= 0) return (connect(sockfd, serv_addr, addrlen)); - set_nonblock(sockfd); + if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + return (-1); + rc = connect(sockfd, serv_addr, addrlen); - if (rc == 0) { - unset_nonblock(sockfd); + if (rc == 0) return (0); - } if (errno != EINPROGRESS) return (-1); @@ -256,15 +260,15 @@ break; case -1: /* Select error */ - debug("select: %s", strerror(errno)); + debug("select: %s", strerror(errno)); break; case 1: /* Completed or failed */ optval = 0; optlen = sizeof(optval); - if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) { - debug("getsockopt: %s", strerror(errno)); + debug("getsockopt: %s", strerror(errno)); break; } if (optval != 0) { @@ -272,7 +276,6 @@ break; } result = 0; - unset_nonblock(sockfd); break; default: /* Should not occur */ @@ -411,8 +414,8 @@ debug("Connection established."); - /* Set SO_KEEPALIVE if requested. */ - if (options.tcp_keep_alive && + /* Set keepalives if requested. */ + if (options.keepalives && setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)) < 0) error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); @@ -559,7 +562,7 @@ int readonly, const char *user_hostfile, const char *system_hostfile) { Key *file_key; - const char *type = key_type(host_key); + char *type = key_type(host_key); char *ip = NULL; char hostline[1000], *hostp, *fp; HostStatus host_status; @@ -719,8 +722,9 @@ /* The default */ fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); msg2[0] = '\0'; +#ifdef DNS if (options.verify_host_key_dns) { - if (matching_host_key_dns) + if (verified_host_key_dns) snprintf(msg2, sizeof(msg2), "Matching host key fingerprint" " found in DNS.\n"); @@ -729,6 +733,7 @@ "No matching host key fingerprint" " found in DNS.\n"); } +#endif snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " "established%s\n" @@ -759,29 +764,39 @@ break; case HOST_CHANGED: if (options.check_host_ip && host_ip_differ) { - char *key_msg; + char *msg; if (ip_status == HOST_NEW) - key_msg = "is unknown"; + msg = "is unknown"; else if (ip_status == HOST_OK) - key_msg = "is unchanged"; + msg = "is unchanged"; else - key_msg = "has a different value"; + msg = "has a different value"; error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("The %s host key for %s has changed,", type, host); error("and the key for the according IP address %s", ip); - error("%s. This could either mean that", key_msg); + error("%s. This could either mean that", msg); error("DNS SPOOFING is happening or the IP address for the host"); error("and its host key have changed at the same time."); if (ip_status != HOST_NEW) error("Offending key for IP in %s:%d", ip_file, ip_line); } /* The host key has changed. */ - warn_changed_key(host_key); + fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); + error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); + error("It is also possible that the %s host key has just been changed.", type); + error("The fingerprint for the %s key sent by the remote host is\n%s.", + type, fp); + error("Please contact your system administrator."); error("Add correct host key in %.100s to get rid of this message.", user_hostfile); error("Offending key in %s:%d", host_file, host_line); + xfree(fp); /* * If strict host key checking is in use, the user will have @@ -884,27 +899,27 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) { struct stat st; - int flags = 0; - if (options.verify_host_key_dns && - verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { - - if (flags & DNS_VERIFY_FOUND) { - - if (options.verify_host_key_dns == 1 && - flags & DNS_VERIFY_MATCH && - flags & DNS_VERIFY_SECURE) - return 0; - - if (flags & DNS_VERIFY_MATCH) { - matching_host_key_dns = 1; - } else { - warn_changed_key(host_key); - error("Update the SSHFP RR in DNS with the new " - "host key to get rid of this message."); - } +#ifdef DNS + if (options.verify_host_key_dns) { + switch(verify_host_key_dns(host, hostaddr, host_key)) { + case DNS_VERIFY_OK: +#ifdef DNSSEC + return 0; +#else + verified_host_key_dns = 1; + break; +#endif + case DNS_VERIFY_FAILED: + return -1; + case DNS_VERIFY_ERROR: + break; + default: + debug3("bad return value from verify_host_key_dns"); + break; } } +#endif /* DNS */ /* return ok if the key can be found in an old keyfile */ if (stat(options.system_hostfile2, &st) == 0 || @@ -1029,25 +1044,4 @@ debug2("no key of type %d for host %s", type[i], host); } return (found); -} - -static void -warn_changed_key(Key *host_key) -{ - char *fp; - const char *type = key_type(host_key); - - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); - - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); - error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); - error("It is also possible that the %s host key has just been changed.", type); - error("The fingerprint for the %s key sent by the remote host is\n%s.", - type, fp); - error("Please contact your system administrator."); - - xfree(fp); }