diff --git a/hostfile.c b/hostfile.c index a4a355972..a91dbbd94 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.79 2020/03/06 18:25:12 markus Exp $ */ +/* $OpenBSD: hostfile.c,v 1.80 2020/05/13 09:52:41 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -406,6 +406,18 @@ lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, found) == HOST_FOUND); } +int +lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker) +{ + u_int i; + + for (i = 0; i < hostkeys->num_entries; i++) { + if (hostkeys->entries[i].marker == (HostkeyMarker)want_marker) + return 1; + } + return 0; +} + static int write_host_entry(FILE *f, const char *host, const char *ip, const struct sshkey *key, int store_hash) diff --git a/hostfile.h b/hostfile.h index bd2104373..49fcbb7e8 100644 --- a/hostfile.h +++ b/hostfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.h,v 1.24 2015/02/16 22:08:57 djm Exp $ */ +/* $OpenBSD: hostfile.h,v 1.25 2020/05/13 09:52:41 djm Exp $ */ /* * Author: Tatu Ylonen @@ -39,6 +39,7 @@ HostStatus check_key_in_hostkeys(struct hostkeys *, struct sshkey *, const struct hostkey_entry **); int lookup_key_in_hostkeys_by_type(struct hostkeys *, int, const struct hostkey_entry **); +int lookup_marker_in_hostkeys(struct hostkeys *, int); int hostfile_read_key(char **, u_int *, struct sshkey *); int add_host_to_hostfile(const char *, const char *, diff --git a/sshconnect2.c b/sshconnect2.c index 1a6545edf..08b4f8550 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.321 2020/04/17 03:38:47 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.322 2020/05/13 09:52:41 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -135,11 +135,23 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) while ((alg = strsep(&avail, ",")) && *alg != '\0') { if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) fatal("%s: unknown alg %s", __func__, alg); - if (lookup_key_in_hostkeys_by_type(hostkeys, - sshkey_type_plain(ktype), NULL)) + /* + * If we have a @cert-authority marker in known_hosts then + * prefer all certificate algorithms. + */ + if (sshkey_type_is_cert(ktype) && + lookup_marker_in_hostkeys(hostkeys, MRK_CA)) { ALG_APPEND(first, alg); - else - ALG_APPEND(last, alg); + continue; + } + /* If the key appears in known_hosts then prefer it */ + if (lookup_key_in_hostkeys_by_type(hostkeys, + sshkey_type_plain(ktype), NULL)) { + ALG_APPEND(first, alg); + continue; + } + /* Otherwise, put it last */ + ALG_APPEND(last, alg); } #undef ALG_APPEND xasprintf(&ret, "%s%s%s", first,