=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sshconnect.c,v retrieving revision 1.137.2.2 retrieving revision 1.138 diff -u -r1.137.2.2 -r1.138 --- src/usr.bin/ssh/sshconnect.c 2004/03/04 18:18:17 1.137.2.2 +++ src/usr.bin/ssh/sshconnect.c 2003/04/08 20:21:29 1.138 @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.137.2.2 2004/03/04 18:18:17 brad Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.138 2003/04/08 20:21:29 itojun Exp $"); #include @@ -33,13 +33,9 @@ #include "misc.h" #include "readpass.h" -#include "dns.h" - char *client_version_string = NULL; char *server_version_string = NULL; -int matching_host_key_dns = 0; - /* import */ extern Options options; extern char *__progname; @@ -48,7 +44,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. @@ -70,7 +65,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); @@ -164,7 +159,7 @@ * Creates a (possibly privileged) socket for use as the ssh connection. */ static int -ssh_create_socket(int privileged, struct addrinfo *ai) +ssh_create_socket(int privileged, int family) { int sock, gaierr; struct addrinfo hints, *res; @@ -176,16 +171,15 @@ if (privileged) { int p = IPPORT_RESERVED - 1; PRIV_START; - sock = rresvport_af(&p, ai->ai_family); + sock = rresvport_af(&p, family); PRIV_END; if (sock < 0) - error("rresvport: af=%d %.100s", ai->ai_family, - strerror(errno)); + error("rresvport: af=%d %.100s", family, strerror(errno)); else debug("Allocated local port %d.", p); return sock; } - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + sock = socket(family, SOCK_STREAM, 0); if (sock < 0) error("socket: %.100s", strerror(errno)); @@ -194,9 +188,8 @@ return sock; memset(&hints, 0, sizeof(hints)); - hints.ai_family = ai->ai_family; - hints.ai_socktype = ai->ai_socktype; - hints.ai_protocol = ai->ai_protocol; + hints.ai_family = family; + hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; gaierr = getaddrinfo(options.bind_address, "0", &hints, &res); if (gaierr) { @@ -215,75 +208,6 @@ return sock; } -static int -timeout_connect(int sockfd, const struct sockaddr *serv_addr, - socklen_t addrlen, int timeout) -{ - fd_set *fdset; - struct timeval tv; - socklen_t optlen; - int fdsetsz, optval, rc, result = -1; - - if (timeout <= 0) - return (connect(sockfd, serv_addr, addrlen)); - - set_nonblock(sockfd); - rc = connect(sockfd, serv_addr, addrlen); - if (rc == 0) { - unset_nonblock(sockfd); - return (0); - } - if (errno != EINPROGRESS) - return (-1); - - fdsetsz = howmany(sockfd + 1, NFDBITS) * sizeof(fd_mask); - fdset = (fd_set *)xmalloc(fdsetsz); - - memset(fdset, 0, fdsetsz); - FD_SET(sockfd, fdset); - tv.tv_sec = timeout; - tv.tv_usec = 0; - - for(;;) { - rc = select(sockfd + 1, NULL, fdset, NULL, &tv); - if (rc != -1 || errno != EINTR) - break; - } - - switch(rc) { - case 0: - /* Timed out */ - errno = ETIMEDOUT; - break; - case -1: - /* Select error */ - debug("select: %s", strerror(errno)); - break; - case 1: - /* Completed or failed */ - optval = 0; - optlen = sizeof(optval); - if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, - &optlen) == -1) { - debug("getsockopt: %s", strerror(errno)); - break; - } - if (optval != 0) { - errno = optval; - break; - } - result = 0; - unset_nonblock(sockfd); - break; - default: - /* Should not occur */ - fatal("Bogus return (%d) from select()", rc); - } - - xfree(fdset); - return (result); -} - /* * Opens a TCP/IP connection to the remote server on the given host. * The address of the remote host will be returned in hostaddr. @@ -367,13 +291,12 @@ host, ntop, strport); /* Create a socket for connecting. */ - sock = ssh_create_socket(needpriv, ai); + sock = ssh_create_socket(needpriv, ai->ai_family); if (sock < 0) /* Any error is already output */ continue; - if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, - options.connection_timeout) >= 0) { + if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { /* Successful connection. */ memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); break; @@ -412,8 +335,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)); @@ -518,7 +441,7 @@ compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, compat20 ? PROTOCOL_MINOR_2 : minor1, SSH_VERSION); - if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) + if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) fatal("write: %.100s", strerror(errno)); client_version_string = xstrdup(buf); chop(client_version_string); @@ -560,7 +483,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; @@ -568,7 +491,7 @@ int local = 0, host_ip_differ = 0; char ntop[NI_MAXHOST]; char msg[1024]; - int len, host_line, ip_line; + int len, host_line, ip_line, has_keys; const char *host_file = NULL, *ip_file = NULL; /* @@ -709,34 +632,19 @@ "have requested strict checking.", type, host); goto fail; } else if (options.strict_host_key_checking == 2) { - char msg1[1024], msg2[1024]; - - if (show_other_keys(host, host_key)) - snprintf(msg1, sizeof(msg1), - "\nbut keys of different type are already" - " known for this host."); - else - snprintf(msg1, sizeof(msg1), "."); + has_keys = show_other_keys(host, host_key); /* The default */ fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); - msg2[0] = '\0'; - if (options.verify_host_key_dns) { - if (matching_host_key_dns) - snprintf(msg2, sizeof(msg2), - "Matching host key fingerprint" - " found in DNS.\n"); - else - snprintf(msg2, sizeof(msg2), - "No matching host key fingerprint" - " found in DNS.\n"); - } snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " "established%s\n" - "%s key fingerprint is %s.\n%s" + "%s key fingerprint is %s.\n" "Are you sure you want to continue connecting " "(yes/no)? ", - host, ip, msg1, type, fp, msg2); + host, ip, + has_keys ? ",\nbut keys of different type are already " + "known for this host." : ".", + type, fp); xfree(fp); if (!confirm(msg)) goto fail; @@ -779,10 +687,20 @@ 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 @@ -796,7 +714,7 @@ /* * If strict host key checking has not been requested, allow - * the connection but without MITM-able authentication or + * the connection but without password authentication or * agent forwarding. */ if (options.password_authentication) { @@ -804,17 +722,6 @@ "man-in-the-middle attacks."); options.password_authentication = 0; } - if (options.kbd_interactive_authentication) { - error("Keyboard-interactive authentication is disabled" - " to avoid man-in-the-middle attacks."); - options.kbd_interactive_authentication = 0; - options.challenge_response_authentication = 0; - } - if (options.challenge_response_authentication) { - error("Challenge/response authentication is disabled" - " to avoid man-in-the-middle attacks."); - options.challenge_response_authentication = 0; - } if (options.forward_agent) { error("Agent forwarding is disabled to avoid " "man-in-the-middle attacks."); @@ -859,7 +766,7 @@ host_file, host_line); } if (options.strict_host_key_checking == 1) { - logit("%s", msg); + logit(msg); error("Exiting, you have requested strict checking."); goto fail; } else if (options.strict_host_key_checking == 2) { @@ -868,7 +775,7 @@ if (!confirm(msg)) goto fail; } else { - logit("%s", msg); + logit(msg); } } @@ -880,33 +787,11 @@ return -1; } -/* returns 0 if key verifies or -1 if key does NOT verify */ int 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."); - } - } - } - /* return ok if the key can be found in an old keyfile */ if (stat(options.system_hostfile2, &st) == 0 || stat(options.user_hostfile2, &st) == 0) { @@ -1030,25 +915,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); }