version 1.233, 2011/05/23 03:52:55 |
version 1.234, 2011/05/24 07:15:47 |
|
|
|
|
/* |
/* |
* check whether the supplied host key is valid, return -1 if the key |
* check whether the supplied host key is valid, return -1 if the key |
* is not valid. the user_hostfile will not be updated if 'readonly' is true. |
* is not valid. user_hostfile[0] will not be updated if 'readonly' is true. |
*/ |
*/ |
#define RDRW 0 |
#define RDRW 0 |
#define RDONLY 1 |
#define RDONLY 1 |
#define ROQUIET 2 |
#define ROQUIET 2 |
static int |
static int |
check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, |
check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, |
Key *host_key, int readonly, char *user_hostfile, |
Key *host_key, int readonly, |
char *system_hostfile) |
char **user_hostfiles, u_int num_user_hostfiles, |
|
char **system_hostfiles, u_int num_system_hostfiles) |
{ |
{ |
|
HostStatus host_status; |
|
HostStatus ip_status; |
Key *raw_key = NULL; |
Key *raw_key = NULL; |
const char *type; |
|
char *ip = NULL, *host = NULL; |
char *ip = NULL, *host = NULL; |
char hostline[1000], *hostp, *fp, *ra; |
char hostline[1000], *hostp, *fp, *ra; |
HostStatus host_status; |
|
HostStatus ip_status; |
|
int r, want_cert = key_is_cert(host_key), host_ip_differ = 0; |
|
int local = sockaddr_is_local(hostaddr); |
|
char msg[1024]; |
char msg[1024]; |
|
const char *type; |
|
const struct hostkey_entry *host_found, *ip_found; |
int len, cancelled_forwarding = 0; |
int len, cancelled_forwarding = 0; |
|
int local = sockaddr_is_local(hostaddr); |
|
int r, want_cert = key_is_cert(host_key), host_ip_differ = 0; |
struct hostkeys *host_hostkeys, *ip_hostkeys; |
struct hostkeys *host_hostkeys, *ip_hostkeys; |
const struct hostkey_entry *host_found, *ip_found; |
u_int i; |
|
|
/* |
/* |
* Force accepting of the host key for loopback/localhost. The |
* Force accepting of the host key for loopback/localhost. The |
|
|
options.check_host_ip = 0; |
options.check_host_ip = 0; |
|
|
host_hostkeys = init_hostkeys(); |
host_hostkeys = init_hostkeys(); |
load_hostkeys(host_hostkeys, host, user_hostfile); |
for (i = 0; i < num_user_hostfiles; i++) |
load_hostkeys(host_hostkeys, host, system_hostfile); |
load_hostkeys(host_hostkeys, host, user_hostfiles[i]); |
|
for (i = 0; i < num_system_hostfiles; i++) |
|
load_hostkeys(host_hostkeys, host, system_hostfiles[i]); |
|
|
ip_hostkeys = NULL; |
ip_hostkeys = NULL; |
if (!want_cert && options.check_host_ip) { |
if (!want_cert && options.check_host_ip) { |
ip_hostkeys = init_hostkeys(); |
ip_hostkeys = init_hostkeys(); |
load_hostkeys(ip_hostkeys, ip, user_hostfile); |
for (i = 0; i < num_user_hostfiles; i++) |
load_hostkeys(ip_hostkeys, ip, system_hostfile); |
load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]); |
|
for (i = 0; i < num_system_hostfiles; i++) |
|
load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]); |
} |
} |
|
|
retry: |
retry: |
|
|
logit("%s host key for IP address " |
logit("%s host key for IP address " |
"'%.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_hostfiles[0], ip, |
host_key, options.hash_known_hosts)) |
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_hostfiles[0]); |
else |
else |
logit("Warning: Permanently added the %s host " |
logit("Warning: Permanently added the %s host " |
"key for IP address '%.128s' to the list " |
"key for IP address '%.128s' to the list " |
|
|
port != SSH_DEFAULT_PORT) { |
port != SSH_DEFAULT_PORT) { |
debug("checking without port identifier"); |
debug("checking without port identifier"); |
if (check_host_key(hostname, hostaddr, 0, host_key, |
if (check_host_key(hostname, hostaddr, 0, host_key, |
ROQUIET, user_hostfile, system_hostfile) == 0) { |
ROQUIET, user_hostfiles, num_user_hostfiles, |
|
system_hostfiles, num_system_hostfiles) == 0) { |
debug("found matching key w/out port"); |
debug("found matching key w/out port"); |
break; |
break; |
} |
} |
|
|
hostp = hostline; |
hostp = hostline; |
if (options.hash_known_hosts) { |
if (options.hash_known_hosts) { |
/* Add hash of host and IP separately */ |
/* Add hash of host and IP separately */ |
r = add_host_to_hostfile(user_hostfile, host, |
r = add_host_to_hostfile(user_hostfiles[0], |
host_key, options.hash_known_hosts) && |
host, host_key, options.hash_known_hosts) && |
add_host_to_hostfile(user_hostfile, ip, |
add_host_to_hostfile(user_hostfiles[0], ip, |
host_key, options.hash_known_hosts); |
host_key, options.hash_known_hosts); |
} else { |
} else { |
/* Add unhashed "host,ip" */ |
/* Add unhashed "host,ip" */ |
r = add_host_to_hostfile(user_hostfile, |
r = add_host_to_hostfile(user_hostfiles[0], |
hostline, host_key, |
hostline, host_key, |
options.hash_known_hosts); |
options.hash_known_hosts); |
} |
} |
} else { |
} else { |
r = add_host_to_hostfile(user_hostfile, host, host_key, |
r = add_host_to_hostfile(user_hostfiles[0], host, |
options.hash_known_hosts); |
host_key, options.hash_known_hosts); |
hostp = host; |
hostp = host; |
} |
} |
|
|
if (!r) |
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_hostfiles[0]); |
else |
else |
logit("Warning: Permanently added '%.200s' (%s) to the " |
logit("Warning: Permanently added '%.200s' (%s) to the " |
"list of known hosts.", hostp, type); |
"list of known hosts.", hostp, type); |
|
|
/* The host key has changed. */ |
/* The host key has changed. */ |
warn_changed_key(host_key); |
warn_changed_key(host_key); |
error("Add correct host key in %.100s to get rid of this message.", |
error("Add correct host key in %.100s to get rid of this message.", |
user_hostfile); |
user_hostfiles[0]); |
error("Offending %s key in %s:%lu", key_type(host_found->key), |
error("Offending %s key in %s:%lu", key_type(host_found->key), |
host_found->file, host_found->line); |
host_found->file, host_found->line); |
|
|
|
|
int |
int |
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) |
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) |
{ |
{ |
struct stat st; |
|
int flags = 0; |
int flags = 0; |
char *fp; |
char *fp; |
|
|
|
|
} |
} |
} |
} |
|
|
/* return ok if the key can be found in an old keyfile */ |
return check_host_key(host, hostaddr, options.port, host_key, RDRW, |
if (stat(options.system_hostfile2, &st) == 0 || |
options.user_hostfiles, options.num_user_hostfiles, |
stat(options.user_hostfile2, &st) == 0) { |
options.system_hostfiles, options.num_system_hostfiles); |
if (check_host_key(host, hostaddr, options.port, host_key, |
|
RDONLY, options.user_hostfile2, |
|
options.system_hostfile2) == 0) |
|
return 0; |
|
} |
|
return check_host_key(host, hostaddr, options.port, host_key, |
|
RDRW, options.user_hostfile, options.system_hostfile); |
|
} |
} |
|
|
/* |
/* |