X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/c5daf22bbd1f885cca4ae4c1cf67352386f8e6b1..HEAD:/sshconnect.c diff --git a/sshconnect.c b/sshconnect.c index 0a4bf36b..63c4650f 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.205 2008/06/12 00:03:49 dtucker 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,30 +72,9 @@ 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 *); -static void -ms_subtract_diff(struct timeval *start, int *ms) -{ - struct timeval diff, finish; - - gettimeofday(&finish, NULL); - timersub(&finish, start, &diff); - *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); -} - -static void -ms_to_timeval(struct timeval *tv, int ms) -{ - tv->tv_sec = ms / 1000; - tv->tv_usec = (ms % 1000) * 1000; -} - /* * Connect to the given ssh server using a proxy command. */ @@ -178,6 +159,8 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) /* Set the connection file descriptors. */ packet_set_connection(pout[0], pin[1]); + packet_set_timeout(options.server_alive_interval, + options.server_alive_count_max); /* Indicate OK return */ return 0; @@ -209,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) @@ -422,6 +408,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, /* Set the connection. */ packet_set_connection(sock, sock); + packet_set_timeout(options.server_alive_interval, + options.server_alive_count_max); return 0; } @@ -430,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! */ @@ -469,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: " @@ -550,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); @@ -609,7 +598,7 @@ 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; /* @@ -656,6 +645,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, } else { ip = xstrdup(""); } + /* * 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 @@ -740,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 (options.check_host_ip == SSHCTL_CHECKHOSTIP_FPR) { + } 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); @@ -753,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; } @@ -798,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)) @@ -855,7 +848,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, 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("and the key for the corresponding IP address %s", ip); error("%s. This could either mean that", key_msg); error("DNS SPOOFING is happening or the IP address for the host"); error("and its host key have changed at the same time."); @@ -887,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) { @@ -915,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;