version 1.158, 2004/06/21 17:36:31 |
version 1.158.2.2, 2005/06/05 02:22:39 |
|
|
tv.tv_sec = timeout; |
tv.tv_sec = timeout; |
tv.tv_usec = 0; |
tv.tv_usec = 0; |
|
|
for(;;) { |
for (;;) { |
rc = select(sockfd + 1, NULL, fdset, NULL, &tv); |
rc = select(sockfd + 1, NULL, fdset, NULL, &tv); |
if (rc != -1 || errno != EINTR) |
if (rc != -1 || errno != EINTR) |
break; |
break; |
} |
} |
|
|
switch(rc) { |
switch (rc) { |
case 0: |
case 0: |
/* Timed out */ |
/* Timed out */ |
errno = ETIMEDOUT; |
errno = ETIMEDOUT; |
|
|
* 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 |