From b4c7cd1185c5dc0593d47eafcc1a34fda569dd1d Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 20 Dec 2020 23:36:51 +0000 Subject: upstream: load_hostkeys()/hostkeys_foreach() variants for FILE* Add load_hostkeys_file() and hostkeys_foreach_file() that accept a FILE* argument instead of opening the file directly. Original load_hostkeys() and hostkeys_foreach() are implemented using these new interfaces. Add a u_int note field to the hostkey_entry and hostkey_foreach_line structs that is passed directly from the load_hostkeys() and hostkeys_foreach() call. This is a lightweight way to annotate results between different invocations of load_hostkeys(). ok markus@ OpenBSD-Commit-ID: 6ff6db13ec9ee4edfa658b2c38baad0f505d8c20 --- hostfile.c | 54 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'hostfile.c') diff --git a/hostfile.c b/hostfile.c index 4ec7b671..c3a28178 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.86 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: hostfile.c,v 1.87 2020/12/20 23:36:51 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -260,6 +260,7 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx) hostkeys->entries[hostkeys->num_entries].key = l->key; l->key = NULL; /* steal it */ hostkeys->entries[hostkeys->num_entries].marker = l->marker; + hostkeys->entries[hostkeys->num_entries].note = l->note; hostkeys->num_entries++; ctx->num_loaded++; @@ -267,7 +268,8 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx) } void -load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) +load_hostkeys_file(struct hostkeys *hostkeys, const char *host, + const char *path, FILE *f, u_int note) { int r; struct load_callback_ctx ctx; @@ -276,8 +278,8 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) ctx.num_loaded = 0; ctx.hostkeys = hostkeys; - if ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, NULL, - HKF_WANT_MATCH|HKF_WANT_PARSE_KEY)) != 0) { + if ((r = hostkeys_foreach_file(path, f, record_hostkey, &ctx, host, + NULL, HKF_WANT_MATCH|HKF_WANT_PARSE_KEY, note)) != 0) { if (r != SSH_ERR_SYSTEM_ERROR && errno != ENOENT) debug_fr(r, "hostkeys_foreach failed for %s", path); } @@ -285,6 +287,21 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) debug3_f("loaded %lu keys from %s", ctx.num_loaded, host); } +void +load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path, + u_int note) +{ + FILE *f; + + if ((f = fopen(path, "r")) == NULL) { + debug_f("fopen %s: %s", path, strerror(errno)); + return; + } + + load_hostkeys_file(hostkeys, host, path, f, note); + fclose(f); +} + void free_hostkeys(struct hostkeys *hostkeys) { @@ -620,7 +637,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip, /* Remove stale/mismatching entries for the specified host */ if ((r = hostkeys_foreach(filename, host_delete, &ctx, host, ip, - HKF_WANT_PARSE_KEY)) != 0) { + HKF_WANT_PARSE_KEY, 0)) != 0) { oerrno = errno; error_fr(r, "hostkeys_foreach"); goto fail; @@ -733,10 +750,9 @@ match_maybe_hashed(const char *host, const char *names, int *was_hashed) } int -hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, - const char *host, const char *ip, u_int options) +hostkeys_foreach_file(const char *path, FILE *f, hostkeys_foreach_fn *callback, + void *ctx, const char *host, const char *ip, u_int options, u_int note) { - FILE *f; char *line = NULL, ktype[128]; u_long linenum = 0; char *cp, *cp2; @@ -749,10 +765,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, memset(&lineinfo, 0, sizeof(lineinfo)); if (host == NULL && (options & HKF_WANT_MATCH) != 0) return SSH_ERR_INVALID_ARGUMENT; - if ((f = fopen(path, "r")) == NULL) - return SSH_ERR_SYSTEM_ERROR; - debug3_f("reading file \"%s\"", path); while (getline(&line, &linesize, f) != -1) { linenum++; line[strcspn(line, "\n")] = '\0'; @@ -766,6 +779,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, lineinfo.marker = MRK_NONE; lineinfo.status = HKF_STATUS_OK; lineinfo.keytype = KEY_UNSPEC; + lineinfo.note = note; /* Skip any leading whitespace, comments and empty lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) @@ -902,6 +916,24 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, sshkey_free(lineinfo.key); free(lineinfo.line); free(line); + return r; +} + +int +hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, + const char *host, const char *ip, u_int options, u_int note) +{ + FILE *f; + int r, oerrno; + + if ((f = fopen(path, "r")) == NULL) + return SSH_ERR_SYSTEM_ERROR; + + debug3_f("reading file \"%s\"", path); + r = hostkeys_foreach_file(path, f, callback, ctx, host, ip, + options, note); + oerrno = errno; fclose(f); + errno = oerrno; return r; } -- cgit v1.2.3