summaryrefslogtreecommitdiff
path: root/hostfile.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2015-01-18 21:48:09 +0000
committerDamien Miller <djm@mindrot.org>2015-01-20 00:20:44 +1100
commitec3d065df3a9557ea96b02d061fd821a18c1a0b9 (patch)
treeb45738be581f65a2d680dfb0406988216a0c49d3 /hostfile.c
parentc29811cc480a260e42fd88849fc86a80c1e91038 (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.c141
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
247void 247struct load_callback_ctx {
248load_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. */ 253static int
266 for (; *cp == ' ' || *cp == '\t'; cp++) 254record_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. */ 286void
296 cp = cp2; 287load_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
343void 307void
@@ -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
474int 437int
475add_host_to_hostfile(const char *filename, const char *host, 438add_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 }