diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2020-12-20 23:36:52 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2020-12-20 23:36:52 +0000 |
commit | 3e8f1f8850f8749397bb476a2a0612e16cc3925f (patch) | |
tree | 906b12409526c635e0824e0ddfc0827076579ade /usr.bin | |
parent | 71ec876454db915001b54511612439261d6fb94d (diff) |
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@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/auth.c | 6 | ||||
-rw-r--r-- | usr.bin/ssh/clientloop.c | 6 | ||||
-rw-r--r-- | usr.bin/ssh/hostfile.c | 54 | ||||
-rw-r--r-- | usr.bin/ssh/hostfile.h | 17 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-keygen.c | 4 | ||||
-rw-r--r-- | usr.bin/ssh/sshconnect.c | 12 | ||||
-rw-r--r-- | usr.bin/ssh/sshconnect2.c | 11 |
7 files changed, 76 insertions, 34 deletions
diff --git a/usr.bin/ssh/auth.c b/usr.bin/ssh/auth.c index 886ec7dca26..c4c23407ea3 100644 --- a/usr.bin/ssh/auth.c +++ b/usr.bin/ssh/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.149 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.150 2020/12/20 23:36:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -378,7 +378,7 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host, const struct hostkey_entry *found; hostkeys = init_hostkeys(); - load_hostkeys(hostkeys, host, sysfile); + load_hostkeys(hostkeys, host, sysfile, 0); if (userfile != NULL) { user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); if (options.strict_modes && @@ -392,7 +392,7 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host, user_hostfile); } else { temporarily_use_uid(pw); - load_hostkeys(hostkeys, host, user_hostfile); + load_hostkeys(hostkeys, host, user_hostfile, 0); restore_uid(); } free(user_hostfile); diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index a1303134c8c..dddbe34e0b0 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.355 2020/10/29 02:47:23 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.356 2020/12/20 23:36:51 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1970,7 +1970,7 @@ check_old_keys_othernames(struct hostkeys_update_ctx *ctx) ctx->ip_str ? ctx->ip_str : "(none)"); if ((r = hostkeys_foreach(options.user_hostfiles[i], hostkeys_check_old, ctx, ctx->host_str, ctx->ip_str, - HKF_WANT_PARSE_KEY)) != 0) { + HKF_WANT_PARSE_KEY, 0)) != 0) { if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) { debug_f("hostkeys file %s does not exist", options.user_hostfiles[i]); @@ -2284,7 +2284,7 @@ client_input_hostkeys(struct ssh *ssh) ctx->ip_str ? ctx->ip_str : "(none)"); if ((r = hostkeys_foreach(options.user_hostfiles[i], hostkeys_find, ctx, ctx->host_str, ctx->ip_str, - HKF_WANT_PARSE_KEY)) != 0) { + HKF_WANT_PARSE_KEY, 0)) != 0) { if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) { debug_f("hostkeys file %s does not exist", options.user_hostfiles[i]); diff --git a/usr.bin/ssh/hostfile.c b/usr.bin/ssh/hostfile.c index edee48fe45c..6f21c368823 100644 --- a/usr.bin/ssh/hostfile.c +++ b/usr.bin/ssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -258,6 +258,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++; @@ -265,7 +266,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; @@ -274,8 +276,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); } @@ -284,6 +286,21 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) } 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) { u_int i; @@ -613,7 +630,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; @@ -726,10 +743,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; @@ -742,10 +758,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'; @@ -759,6 +772,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++) @@ -895,6 +909,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; } diff --git a/usr.bin/ssh/hostfile.h b/usr.bin/ssh/hostfile.h index 7ea31444db8..bc828eccf08 100644 --- a/usr.bin/ssh/hostfile.h +++ b/usr.bin/ssh/hostfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.h,v 1.27 2020/10/04 09:45:01 djm Exp $ */ +/* $OpenBSD: hostfile.h,v 1.28 2020/12/20 23:36:51 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -28,11 +28,15 @@ struct hostkey_entry { u_long line; struct sshkey *key; HostkeyMarker marker; + u_int note; /* caller-specific note/flag */ }; struct hostkeys; struct hostkeys *init_hostkeys(void); -void load_hostkeys(struct hostkeys *, const char *, const char *); +void load_hostkeys(struct hostkeys *, const char *, + const char *, u_int); +void load_hostkeys_file(struct hostkeys *, const char *, + const char *, FILE *, u_int note); void free_hostkeys(struct hostkeys *); HostStatus check_key_in_hostkeys(struct hostkeys *, struct sshkey *, @@ -93,6 +97,7 @@ struct hostkey_foreach_line { int keytype; /* Type of key; KEY_UNSPEC for invalid/comment lines */ struct sshkey *key; /* Key, if parsed ok and HKF_WANT_MATCH_HOST set */ const char *comment; /* Any comment following the key */ + u_int note; /* caller-specified note copied from arguments */ }; /* @@ -103,8 +108,12 @@ struct hostkey_foreach_line { typedef int hostkeys_foreach_fn(struct hostkey_foreach_line *l, void *ctx); /* Iterate over a hostkeys file */ -int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, - const char *host, const char *ip, u_int options); +int hostkeys_foreach(const char *path, + hostkeys_foreach_fn *callback, void *ctx, + const char *host, const char *ip, u_int options, u_int note); +int 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); void hostfile_create_user_ssh_dir(const char *, int); diff --git a/usr.bin/ssh/ssh-keygen.c b/usr.bin/ssh/ssh-keygen.c index 9b161a6f049..69886d4a738 100644 --- a/usr.bin/ssh/ssh-keygen.c +++ b/usr.bin/ssh/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.426 2020/11/28 12:52:32 dtucker Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.427 2020/12/20 23:36:51 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1318,7 +1318,7 @@ do_known_hosts(struct passwd *pw, const char *name, int find_host, foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0; if ((r = hostkeys_foreach(identity_file, (find_host || !hash_hosts) ? known_hosts_find_delete : known_hosts_hash, &ctx, name, NULL, - foreach_options)) != 0) { + foreach_options, 0)) != 0) { if (inplace) unlink(tmp); fatal_fr(r, "hostkeys_foreach"); diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c index f07d342a925..c757d9cd154 100644 --- a/usr.bin/ssh/sshconnect.c +++ b/usr.bin/ssh/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.345 2020/11/27 00:49:58 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.346 2020/12/20 23:36:51 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -735,7 +735,7 @@ hostkeys_find_by_key_hostfile(const char *file, const char *which, debug3_f("trying %s hostfile \"%s\"", which, file); if ((r = hostkeys_foreach(file, hostkeys_find_by_key_cb, ctx, - ctx->host, ctx->ip, HKF_WANT_PARSE_KEY)) != 0) { + ctx->host, ctx->ip, HKF_WANT_PARSE_KEY, 0)) != 0) { if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) { debug_f("hostkeys file %s does not exist", file); return 0; @@ -886,17 +886,17 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, host_hostkeys = init_hostkeys(); for (i = 0; i < num_user_hostfiles; i++) - load_hostkeys(host_hostkeys, host, user_hostfiles[i]); + load_hostkeys(host_hostkeys, host, user_hostfiles[i], 0); for (i = 0; i < num_system_hostfiles; i++) - load_hostkeys(host_hostkeys, host, system_hostfiles[i]); + load_hostkeys(host_hostkeys, host, system_hostfiles[i], 0); ip_hostkeys = NULL; if (!want_cert && options.check_host_ip) { ip_hostkeys = init_hostkeys(); for (i = 0; i < num_user_hostfiles; i++) - load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]); + load_hostkeys(ip_hostkeys, ip, user_hostfiles[i], 0); for (i = 0; i < num_system_hostfiles; i++) - load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]); + load_hostkeys(ip_hostkeys, ip, system_hostfiles[i], 0); } retry: diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c index 1abd3aac182..0a3e29ee343 100644 --- a/usr.bin/ssh/sshconnect2.c +++ b/usr.bin/ssh/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.336 2020/11/13 07:30:44 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.337 2020/12/20 23:36:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -124,10 +124,11 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); hostkeys = init_hostkeys(); for (i = 0; i < options.num_user_hostfiles; i++) - load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]); - for (i = 0; i < options.num_system_hostfiles; i++) - load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); - + load_hostkeys(hostkeys, hostname, options.user_hostfiles[i], 0); + for (i = 0; i < options.num_system_hostfiles; i++) { + load_hostkeys(hostkeys, hostname, + options.system_hostfiles[i], 0); + } /* * If a plain public key exists that matches the type of the best * preference HostkeyAlgorithms, then use the whole list as is. |