X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/6d8216ff13019a82c3c9e3a97fe7f7a3ba39d1e6..HEAD:/sshconnect.c diff --git a/sshconnect.c b/sshconnect.c index 26767077..63c4650f 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.208 2008/06/12 23:24:58 ian Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.218 2010/01/13 00:19:04 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -28,6 +28,7 @@ #include #include +#include #include #ifdef HAVE_PATHS_H #include @@ -56,6 +57,7 @@ #include "atomicio.h" #include "misc.h" #include "dns.h" +#include "roaming.h" #include "version.h" char *client_version_string = NULL; @@ -70,10 +72,6 @@ extern uid_t original_real_uid; extern uid_t original_effective_uid; extern pid_t proxy_command_pid; -#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ -#define INET6_ADDRSTRLEN 46 -#endif - static int show_other_keys(const char *, Key *); static void warn_changed_key(Key *); @@ -194,8 +192,11 @@ ssh_create_socket(int privileged, struct addrinfo *ai) return sock; } sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (sock < 0) + if (sock < 0) { error("socket: %.100s", strerror(errno)); + return -1; + } + fcntl(sock, F_SETFD, FD_CLOEXEC); /* Bind the socket to an alternative local IP address */ if (options.bind_address == NULL) @@ -417,7 +418,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, * Waits for the server identification string, and sends our own * identification string. */ -static void +void ssh_exchange_identification(int timeout_ms) { char buf[256], remote_version[256]; /* must be same size! */ @@ -456,7 +457,7 @@ ssh_exchange_identification(int timeout_ms) } } - len = atomicio(read, connection_in, &buf[i], 1); + len = roaming_atomicio(read, connection_in, &buf[i], 1); if (len != 1 && errno == EPIPE) fatal("ssh_exchange_identification: " @@ -537,11 +538,12 @@ ssh_exchange_identification(int timeout_ms) (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, remote_major); /* Send our own protocol version identification. */ - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, compat20 ? PROTOCOL_MINOR_2 : minor1, - SSH_VERSION); - if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) + SSH_VERSION, compat20 ? "\r\n" : "\n"); + if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf)) + != strlen(buf)) fatal("write: %.100s", strerror(errno)); client_version_string = xstrdup(buf); chop(client_version_string); @@ -596,9 +598,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, int salen; char ntop[NI_MAXHOST]; char msg[1024]; - int len, host_line, ip_line; + int len, host_line, ip_line, cancelled_forwarding = 0; const char *host_file = NULL, *ip_file = NULL; - int display_randomart; /* * Force accepting of the host key for loopback/localhost. The @@ -645,12 +646,6 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, ip = xstrdup(""); } - /* - * check_host_ip may be set to zero in the next step, so if it - * conveys a request to display the random art, save it away. - */ - display_randomart = (options.check_host_ip == SSHCTL_CHECKHOSTIP_FPR); - /* * Turn off check_host_ip if the connection is to localhost, via proxy * command or if we don't have a hostname to compare with @@ -735,7 +730,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, logit("Warning: Permanently added the %s host " "key for IP address '%.128s' to the list " "of known hosts.", type, ip); - } else if (display_randomart) { + } else if (options.visual_host_key) { fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); ra = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_RANDOMART); @@ -748,8 +743,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, if (options.host_key_alias == NULL && port != 0 && port != SSH_DEFAULT_PORT) { debug("checking without port identifier"); - if (check_host_key(hostname, hostaddr, 0, host_key, 2, - user_hostfile, system_hostfile) == 0) { + if (check_host_key(hostname, hostaddr, 0, host_key, + ROQUIET, user_hostfile, system_hostfile) == 0) { debug("found matching key w/out port"); break; } @@ -793,10 +788,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " "established%s\n" - "%s key fingerprint is %s.\n%s\n%s" + "%s key fingerprint is %s.%s%s\n%s" "Are you sure you want to continue connecting " "(yes/no)? ", - host, ip, msg1, type, fp, ra, msg2); + host, ip, msg1, type, fp, + options.visual_host_key ? "\n" : "", + options.visual_host_key ? ra : "", + msg2); xfree(ra); xfree(fp); if (!confirm(msg)) @@ -882,27 +880,32 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, error("Password authentication is disabled to avoid " "man-in-the-middle attacks."); options.password_authentication = 0; + cancelled_forwarding = 1; } 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; + cancelled_forwarding = 1; } if (options.challenge_response_authentication) { error("Challenge/response authentication is disabled" " to avoid man-in-the-middle attacks."); options.challenge_response_authentication = 0; + cancelled_forwarding = 1; } if (options.forward_agent) { error("Agent forwarding is disabled to avoid " "man-in-the-middle attacks."); options.forward_agent = 0; + cancelled_forwarding = 1; } if (options.forward_x11) { error("X11 forwarding is disabled to avoid " "man-in-the-middle attacks."); options.forward_x11 = 0; + cancelled_forwarding = 1; } if (options.num_local_forwards > 0 || options.num_remote_forwards > 0) { @@ -910,17 +913,23 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, "man-in-the-middle attacks."); options.num_local_forwards = options.num_remote_forwards = 0; + cancelled_forwarding = 1; } if (options.tun_open != SSH_TUNMODE_NO) { error("Tunnel forwarding is disabled to avoid " "man-in-the-middle attacks."); options.tun_open = SSH_TUNMODE_NO; + cancelled_forwarding = 1; } + if (options.exit_on_forward_failure && cancelled_forwarding) + fatal("Error: forwarding disabled due to host key " + "check failure"); + /* * XXX Should permit the user to change to use the new id. * This could be done by converting the host key to an * identifying sentence, tell that the host identifies itself - * by that sentence, and ask the user if he/she whishes to + * by that sentence, and ask the user if he/she wishes to * accept the authentication. */ break;