version 1.156, 2004/01/25 03:49:09 |
version 1.156.2.2, 2005/03/10 17:15:05 |
|
|
#include "readconf.h" |
#include "readconf.h" |
#include "atomicio.h" |
#include "atomicio.h" |
#include "misc.h" |
#include "misc.h" |
#include "readpass.h" |
|
|
|
#include "dns.h" |
#include "dns.h" |
|
|
|
|
* second). If proxy_command is non-NULL, it specifies the command (with %h |
* second). If proxy_command is non-NULL, it specifies the command (with %h |
* and %p substituted for host and port, respectively) to use to contact |
* and %p substituted for host and port, respectively) to use to contact |
* the daemon. |
* the daemon. |
* Return values: |
|
* 0 for OK |
|
* ECONNREFUSED if we got a "Connection Refused" by the peer on any address |
|
* ECONNABORTED if we failed without a "Connection refused" |
|
* Suitable error messages for the connection failure will already have been |
|
* printed. |
|
*/ |
*/ |
int |
int |
ssh_connect(const char *host, struct sockaddr_storage * hostaddr, |
ssh_connect(const char *host, struct sockaddr_storage * hostaddr, |
|
|
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
struct addrinfo hints, *ai, *aitop; |
struct addrinfo hints, *ai, *aitop; |
struct servent *sp; |
struct servent *sp; |
/* |
|
* Did we get only other errors than "Connection refused" (which |
|
* should block fallback to rsh and similar), or did we get at least |
|
* one "Connection refused"? |
|
*/ |
|
int full_failure = 1; |
|
|
|
debug2("ssh_connect: needpriv %d", needpriv); |
debug2("ssh_connect: needpriv %d", needpriv); |
|
|
|
|
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); |
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); |
break; |
break; |
} else { |
} else { |
if (errno == ECONNREFUSED) |
|
full_failure = 0; |
|
debug("connect to address %s port %s: %s", |
debug("connect to address %s port %s: %s", |
ntop, strport, strerror(errno)); |
ntop, strport, strerror(errno)); |
/* |
/* |
|
|
|
|
/* Return failure if we didn't get a successful connection. */ |
/* Return failure if we didn't get a successful connection. */ |
if (attempt >= connection_attempts) { |
if (attempt >= connection_attempts) { |
logit("ssh: connect to host %s port %s: %s", |
error("ssh: connect to host %s port %s: %s", |
host, strport, strerror(errno)); |
host, strport, strerror(errno)); |
return full_failure ? ECONNABORTED : ECONNREFUSED; |
return (-1); |
} |
} |
|
|
debug("Connection established."); |
debug("Connection established."); |
|
|
char hostline[1000], *hostp, *fp; |
char hostline[1000], *hostp, *fp; |
HostStatus host_status; |
HostStatus host_status; |
HostStatus ip_status; |
HostStatus ip_status; |
int local = 0, host_ip_differ = 0; |
int r, local = 0, host_ip_differ = 0; |
char ntop[NI_MAXHOST]; |
char ntop[NI_MAXHOST]; |
char msg[1024]; |
char msg[1024]; |
int len, host_line, ip_line; |
int len, host_line, ip_line; |
|
|
"'%.128s' not in list of known hosts.", |
"'%.128s' not in list of known hosts.", |
type, ip); |
type, ip); |
else if (!add_host_to_hostfile(user_hostfile, ip, |
else if (!add_host_to_hostfile(user_hostfile, ip, |
host_key)) |
host_key, options.hash_known_hosts)) |
logit("Failed to add the %s host key for IP " |
logit("Failed to add the %s host key for IP " |
"address '%.128s' to the list of known " |
"address '%.128s' to the list of known " |
"hosts (%.30s).", type, ip, user_hostfile); |
"hosts (%.30s).", type, ip, user_hostfile); |
|
|
if (!confirm(msg)) |
if (!confirm(msg)) |
goto fail; |
goto fail; |
} |
} |
if (options.check_host_ip && ip_status == HOST_NEW) { |
|
snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); |
|
hostp = hostline; |
|
} else |
|
hostp = host; |
|
|
|
/* |
/* |
* If not in strict mode, add the key automatically to the |
* If not in strict mode, add the key automatically to the |
* local known_hosts file. |
* local known_hosts file. |
*/ |
*/ |
if (!add_host_to_hostfile(user_hostfile, hostp, host_key)) |
if (options.check_host_ip && ip_status == HOST_NEW) { |
|
snprintf(hostline, sizeof(hostline), "%s,%s", |
|
host, ip); |
|
hostp = hostline; |
|
if (options.hash_known_hosts) { |
|
/* Add hash of host and IP separately */ |
|
r = add_host_to_hostfile(user_hostfile, host, |
|
host_key, options.hash_known_hosts) && |
|
add_host_to_hostfile(user_hostfile, ip, |
|
host_key, options.hash_known_hosts); |
|
} else { |
|
/* Add unhashed "host,ip" */ |
|
r = add_host_to_hostfile(user_hostfile, |
|
hostline, host_key, |
|
options.hash_known_hosts); |
|
} |
|
} else { |
|
r = add_host_to_hostfile(user_hostfile, host, host_key, |
|
options.hash_known_hosts); |
|
hostp = host; |
|
} |
|
|
|
if (!r) |
logit("Failed to add the host to the list of known " |
logit("Failed to add the host to the list of known " |
"hosts (%.500s).", user_hostfile); |
"hosts (%.500s).", user_hostfile); |
else |
else |
|
|
break; |
break; |
case HOST_CHANGED: |
case HOST_CHANGED: |
if (options.check_host_ip && host_ip_differ) { |
if (options.check_host_ip && host_ip_differ) { |
char *msg; |
char *key_msg; |
if (ip_status == HOST_NEW) |
if (ip_status == HOST_NEW) |
msg = "is unknown"; |
key_msg = "is unknown"; |
else if (ip_status == HOST_OK) |
else if (ip_status == HOST_OK) |
msg = "is unchanged"; |
key_msg = "is unchanged"; |
else |
else |
msg = "has a different value"; |
key_msg = "has a different value"; |
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); |
error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); |
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
error("The %s host key for %s has changed,", type, host); |
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 according IP address %s", ip); |
error("%s. This could either mean that", msg); |
error("%s. This could either mean that", key_msg); |
error("DNS SPOOFING is happening or the IP address for the host"); |
error("DNS SPOOFING is happening or the IP address for the host"); |
error("and its host key have changed at the same time."); |
error("and its host key have changed at the same time."); |
if (ip_status != HOST_NEW) |
if (ip_status != HOST_NEW) |