diff options
author | djm@openbsd.org <djm@openbsd.org> | 2015-01-18 21:48:09 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2015-01-20 00:20:44 +1100 |
commit | ec3d065df3a9557ea96b02d061fd821a18c1a0b9 (patch) | |
tree | b45738be581f65a2d680dfb0406988216a0c49d3 /hostfile.c | |
parent | c29811cc480a260e42fd88849fc86a80c1e91038 (diff) |
upstream commit
convert load_hostkeys() (hostkey ordering and
known_host matching) to use the new hostkey_foreach() iterator; ok markus
Diffstat (limited to 'hostfile.c')
-rw-r--r-- | hostfile.c | 141 |
1 files changed, 52 insertions, 89 deletions
diff --git a/hostfile.c b/hostfile.c index 5f0366310..ccb2af920 100644 --- a/hostfile.c +++ b/hostfile.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: hostfile.c,v 1.60 2015/01/18 21:40:23 djm Exp $ */ | 1 | /* $OpenBSD: hostfile.c,v 1.61 2015/01/18 21:48:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -244,100 +244,64 @@ init_hostkeys(void) | |||
244 | return ret; | 244 | return ret; |
245 | } | 245 | } |
246 | 246 | ||
247 | void | 247 | struct load_callback_ctx { |
248 | load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) | 248 | const char *host; |
249 | { | 249 | u_long num_loaded; |
250 | FILE *f; | 250 | struct hostkeys *hostkeys; |
251 | char line[8192]; | 251 | }; |
252 | u_long linenum = 0, num_loaded = 0; | ||
253 | char *cp, *cp2, *hashed_host; | ||
254 | HostkeyMarker marker; | ||
255 | struct sshkey *key; | ||
256 | u_int kbits; | ||
257 | |||
258 | if ((f = fopen(path, "r")) == NULL) | ||
259 | return; | ||
260 | debug3("%s: loading entries for host \"%.100s\" from file \"%s\"", | ||
261 | __func__, host, path); | ||
262 | while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { | ||
263 | cp = line; | ||
264 | 252 | ||
265 | /* Skip any leading whitespace, comments and empty lines. */ | 253 | static int |
266 | for (; *cp == ' ' || *cp == '\t'; cp++) | 254 | record_hostkey(struct hostkey_foreach_line *l, void *_ctx) |
267 | ; | 255 | { |
268 | if (!*cp || *cp == '#' || *cp == '\n') | 256 | struct load_callback_ctx *ctx = (struct load_callback_ctx *)_ctx; |
269 | continue; | 257 | struct hostkeys *hostkeys = ctx->hostkeys; |
258 | struct hostkey_entry *tmp; | ||
270 | 259 | ||
271 | if ((marker = check_markers(&cp)) == MRK_ERROR) { | 260 | if (l->status == HKF_STATUS_INVALID) { |
272 | verbose("%s: invalid marker at %s:%lu", | 261 | error("%s:%ld: parse error in hostkeys file", |
273 | __func__, path, linenum); | 262 | l->path, l->linenum); |
274 | continue; | 263 | return 0; |
275 | } | 264 | } |
276 | 265 | ||
277 | /* Find the end of the host name portion. */ | 266 | debug3("%s: found %skey type %s in file %s:%lu", __func__, |
278 | for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) | 267 | l->marker == MRK_NONE ? "" : |
279 | ; | 268 | (l->marker == MRK_CA ? "ca " : "revoked "), |
269 | sshkey_type(l->key), l->path, l->linenum); | ||
270 | if ((tmp = reallocarray(hostkeys->entries, | ||
271 | hostkeys->num_entries + 1, sizeof(*hostkeys->entries))) == NULL) | ||
272 | return SSH_ERR_ALLOC_FAIL; | ||
273 | hostkeys->entries = tmp; | ||
274 | hostkeys->entries[hostkeys->num_entries].host = xstrdup(ctx->host); | ||
275 | hostkeys->entries[hostkeys->num_entries].file = xstrdup(l->path); | ||
276 | hostkeys->entries[hostkeys->num_entries].line = l->linenum; | ||
277 | hostkeys->entries[hostkeys->num_entries].key = l->key; | ||
278 | l->key = NULL; /* steal it */ | ||
279 | hostkeys->entries[hostkeys->num_entries].marker = l->marker; | ||
280 | hostkeys->num_entries++; | ||
281 | ctx->num_loaded++; | ||
280 | 282 | ||
281 | /* Check if the host name matches. */ | 283 | return 0; |
282 | if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) { | 284 | } |
283 | if (*cp != HASH_DELIM) | ||
284 | continue; | ||
285 | hashed_host = host_hash(host, cp, (u_int) (cp2 - cp)); | ||
286 | if (hashed_host == NULL) { | ||
287 | debug("Invalid hashed host line %lu of %s", | ||
288 | linenum, path); | ||
289 | continue; | ||
290 | } | ||
291 | if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0) | ||
292 | continue; | ||
293 | } | ||
294 | 285 | ||
295 | /* Got a match. Skip host name. */ | 286 | void |
296 | cp = cp2; | 287 | load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) |
288 | { | ||
289 | int r; | ||
290 | struct load_callback_ctx ctx; | ||
297 | 291 | ||
298 | /* | 292 | ctx.host = host; |
299 | * Extract the key from the line. This will skip any leading | 293 | ctx.num_loaded = 0; |
300 | * whitespace. Ignore badly formatted lines. | 294 | ctx.hostkeys = hostkeys; |
301 | */ | ||
302 | if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { | ||
303 | error("%s: sshkey_new failed", __func__); | ||
304 | break; | ||
305 | } | ||
306 | if (!hostfile_read_key(&cp, &kbits, key)) { | ||
307 | sshkey_free(key); | ||
308 | #ifdef WITH_SSH1 | ||
309 | if ((key = sshkey_new(KEY_RSA1)) == NULL) { | ||
310 | error("%s: sshkey_new failed", __func__); | ||
311 | break; | ||
312 | } | ||
313 | if (!hostfile_read_key(&cp, &kbits, key)) { | ||
314 | sshkey_free(key); | ||
315 | continue; | ||
316 | } | ||
317 | #else | ||
318 | continue; | ||
319 | #endif | ||
320 | } | ||
321 | if (!hostfile_check_key(kbits, key, host, path, linenum)) | ||
322 | continue; | ||
323 | 295 | ||
324 | debug3("%s: found %skey type %s in file %s:%lu", __func__, | 296 | if ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, |
325 | marker == MRK_NONE ? "" : | 297 | HKF_WANT_MATCH_HOST|HKF_WANT_PARSE_KEY)) != 0) { |
326 | (marker == MRK_CA ? "ca " : "revoked "), | 298 | if (r != SSH_ERR_SYSTEM_ERROR && errno != ENOENT) |
327 | sshkey_type(key), path, linenum); | 299 | debug("%s: hostkeys_foreach failed for %s: %s", |
328 | hostkeys->entries = xrealloc(hostkeys->entries, | 300 | __func__, path, ssh_err(r)); |
329 | hostkeys->num_entries + 1, sizeof(*hostkeys->entries)); | ||
330 | hostkeys->entries[hostkeys->num_entries].host = xstrdup(host); | ||
331 | hostkeys->entries[hostkeys->num_entries].file = xstrdup(path); | ||
332 | hostkeys->entries[hostkeys->num_entries].line = linenum; | ||
333 | hostkeys->entries[hostkeys->num_entries].key = key; | ||
334 | hostkeys->entries[hostkeys->num_entries].marker = marker; | ||
335 | hostkeys->num_entries++; | ||
336 | num_loaded++; | ||
337 | } | 301 | } |
338 | debug3("%s: loaded %lu keys", __func__, num_loaded); | 302 | if (ctx.num_loaded != 0) |
339 | fclose(f); | 303 | debug3("%s: loaded %lu keys from %s", __func__, |
340 | return; | 304 | ctx.num_loaded, host); |
341 | } | 305 | } |
342 | 306 | ||
343 | void | 307 | void |
@@ -470,7 +434,6 @@ lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, | |||
470 | * Appends an entry to the host file. Returns false if the entry could not | 434 | * Appends an entry to the host file. Returns false if the entry could not |
471 | * be appended. | 435 | * be appended. |
472 | */ | 436 | */ |
473 | |||
474 | int | 437 | int |
475 | add_host_to_hostfile(const char *filename, const char *host, | 438 | add_host_to_hostfile(const char *filename, const char *host, |
476 | const struct sshkey *key, int store_hash) | 439 | const struct sshkey *key, int store_hash) |
@@ -487,7 +450,7 @@ add_host_to_hostfile(const char *filename, const char *host, | |||
487 | 450 | ||
488 | if (store_hash) { | 451 | if (store_hash) { |
489 | if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { | 452 | if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { |
490 | error("add_host_to_hostfile: host_hash failed"); | 453 | error("%s: host_hash failed", __func__); |
491 | fclose(f); | 454 | fclose(f); |
492 | return 0; | 455 | return 0; |
493 | } | 456 | } |