version 1.60, 2015/01/18 21:40:23 |
version 1.61, 2015/01/18 21:48:09 |
|
|
return ret; |
return ret; |
} |
} |
|
|
void |
struct load_callback_ctx { |
load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) |
const char *host; |
|
u_long num_loaded; |
|
struct hostkeys *hostkeys; |
|
}; |
|
|
|
static int |
|
record_hostkey(struct hostkey_foreach_line *l, void *_ctx) |
{ |
{ |
FILE *f; |
struct load_callback_ctx *ctx = (struct load_callback_ctx *)_ctx; |
char line[8192]; |
struct hostkeys *hostkeys = ctx->hostkeys; |
u_long linenum = 0, num_loaded = 0; |
struct hostkey_entry *tmp; |
char *cp, *cp2, *hashed_host; |
|
HostkeyMarker marker; |
|
struct sshkey *key; |
|
u_int kbits; |
|
|
|
if ((f = fopen(path, "r")) == NULL) |
if (l->status == HKF_STATUS_INVALID) { |
return; |
error("%s:%ld: parse error in hostkeys file", |
debug3("%s: loading entries for host \"%.100s\" from file \"%s\"", |
l->path, l->linenum); |
__func__, host, path); |
return 0; |
while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { |
} |
cp = line; |
|
|
|
/* Skip any leading whitespace, comments and empty lines. */ |
debug3("%s: found %skey type %s in file %s:%lu", __func__, |
for (; *cp == ' ' || *cp == '\t'; cp++) |
l->marker == MRK_NONE ? "" : |
; |
(l->marker == MRK_CA ? "ca " : "revoked "), |
if (!*cp || *cp == '#' || *cp == '\n') |
sshkey_type(l->key), l->path, l->linenum); |
continue; |
if ((tmp = reallocarray(hostkeys->entries, |
|
hostkeys->num_entries + 1, sizeof(*hostkeys->entries))) == NULL) |
|
return SSH_ERR_ALLOC_FAIL; |
|
hostkeys->entries = tmp; |
|
hostkeys->entries[hostkeys->num_entries].host = xstrdup(ctx->host); |
|
hostkeys->entries[hostkeys->num_entries].file = xstrdup(l->path); |
|
hostkeys->entries[hostkeys->num_entries].line = l->linenum; |
|
hostkeys->entries[hostkeys->num_entries].key = l->key; |
|
l->key = NULL; /* steal it */ |
|
hostkeys->entries[hostkeys->num_entries].marker = l->marker; |
|
hostkeys->num_entries++; |
|
ctx->num_loaded++; |
|
|
if ((marker = check_markers(&cp)) == MRK_ERROR) { |
return 0; |
verbose("%s: invalid marker at %s:%lu", |
} |
__func__, path, linenum); |
|
continue; |
|
} |
|
|
|
/* Find the end of the host name portion. */ |
void |
for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) |
load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) |
; |
{ |
|
int r; |
|
struct load_callback_ctx ctx; |
|
|
/* Check if the host name matches. */ |
ctx.host = host; |
if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) { |
ctx.num_loaded = 0; |
if (*cp != HASH_DELIM) |
ctx.hostkeys = hostkeys; |
continue; |
|
hashed_host = host_hash(host, cp, (u_int) (cp2 - cp)); |
|
if (hashed_host == NULL) { |
|
debug("Invalid hashed host line %lu of %s", |
|
linenum, path); |
|
continue; |
|
} |
|
if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0) |
|
continue; |
|
} |
|
|
|
/* Got a match. Skip host name. */ |
if ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, |
cp = cp2; |
HKF_WANT_MATCH_HOST|HKF_WANT_PARSE_KEY)) != 0) { |
|
if (r != SSH_ERR_SYSTEM_ERROR && errno != ENOENT) |
/* |
debug("%s: hostkeys_foreach failed for %s: %s", |
* Extract the key from the line. This will skip any leading |
__func__, path, ssh_err(r)); |
* whitespace. Ignore badly formatted lines. |
|
*/ |
|
if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { |
|
error("%s: sshkey_new failed", __func__); |
|
break; |
|
} |
|
if (!hostfile_read_key(&cp, &kbits, key)) { |
|
sshkey_free(key); |
|
#ifdef WITH_SSH1 |
|
if ((key = sshkey_new(KEY_RSA1)) == NULL) { |
|
error("%s: sshkey_new failed", __func__); |
|
break; |
|
} |
|
if (!hostfile_read_key(&cp, &kbits, key)) { |
|
sshkey_free(key); |
|
continue; |
|
} |
|
#else |
|
continue; |
|
#endif |
|
} |
|
if (!hostfile_check_key(kbits, key, host, path, linenum)) |
|
continue; |
|
|
|
debug3("%s: found %skey type %s in file %s:%lu", __func__, |
|
marker == MRK_NONE ? "" : |
|
(marker == MRK_CA ? "ca " : "revoked "), |
|
sshkey_type(key), path, linenum); |
|
hostkeys->entries = xrealloc(hostkeys->entries, |
|
hostkeys->num_entries + 1, sizeof(*hostkeys->entries)); |
|
hostkeys->entries[hostkeys->num_entries].host = xstrdup(host); |
|
hostkeys->entries[hostkeys->num_entries].file = xstrdup(path); |
|
hostkeys->entries[hostkeys->num_entries].line = linenum; |
|
hostkeys->entries[hostkeys->num_entries].key = key; |
|
hostkeys->entries[hostkeys->num_entries].marker = marker; |
|
hostkeys->num_entries++; |
|
num_loaded++; |
|
} |
} |
debug3("%s: loaded %lu keys", __func__, num_loaded); |
if (ctx.num_loaded != 0) |
fclose(f); |
debug3("%s: loaded %lu keys from %s", __func__, |
return; |
ctx.num_loaded, host); |
} |
} |
|
|
void |
void |
|
|
* Appends an entry to the host file. Returns false if the entry could not |
* Appends an entry to the host file. Returns false if the entry could not |
* be appended. |
* be appended. |
*/ |
*/ |
|
|
int |
int |
add_host_to_hostfile(const char *filename, const char *host, |
add_host_to_hostfile(const char *filename, const char *host, |
const struct sshkey *key, int store_hash) |
const struct sshkey *key, int store_hash) |
|
|
|
|
if (store_hash) { |
if (store_hash) { |
if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { |
if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { |
error("add_host_to_hostfile: host_hash failed"); |
error("%s: host_hash failed", __func__); |
fclose(f); |
fclose(f); |
return 0; |
return 0; |
} |
} |