=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/clientloop.c,v retrieving revision 1.346 retrieving revision 1.347 diff -u -r1.346 -r1.347 --- src/usr.bin/ssh/clientloop.c 2020/09/16 03:07:31 1.346 +++ src/usr.bin/ssh/clientloop.c 2020/10/03 08:12:59 1.347 @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.346 2020/09/16 03:07:31 dtucker Exp $ */ +/* $OpenBSD: clientloop.c,v 1.347 2020/10/03 08:12:59 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1814,6 +1814,10 @@ */ struct sshkey **old_keys; size_t nold; + + /* Various special cases. */ + int wildcard_hostspec; /* saw wildcard or pattern-list host name */ + int ca_available; /* saw CA key for this host */ }; static void @@ -1845,6 +1849,21 @@ if (l->status != HKF_STATUS_MATCHED || l->key == NULL) return 0; + if (l->marker == MRK_REVOKE) + return 0; + if (l->marker == MRK_CA) { + ctx->ca_available = 1; + return 0; + } + + /* UpdateHostkeys is skipped for wildcard host names */ + if (strchr(l->hosts, '*') != NULL || + strchr(l->hosts, ',') != NULL) { + debug3("%s: hostkeys file %s:%ld contains wildcard or pattern", + __func__, l->path, l->linenum); + ctx->wildcard_hostspec = 1; + } + /* Mark off keys we've already seen for this host */ for (i = 0; i < ctx->nkeys; i++) { if (sshkey_equal(l->key, ctx->keys[i])) { @@ -2190,7 +2209,17 @@ debug3("%s: %zu keys from server: %zu new, %zu retained. %zu to remove", __func__, ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold); - if (ctx->nnew == 0 && ctx->nold != 0) { + if (ctx->wildcard_hostspec && (ctx->nnew != 0 || ctx->nold != 0)) { + debug("%s: wildcard known hosts name found, " + "skipping UserKnownHostsFile update", __func__); + goto out; + } else if (sshkey_type_is_cert(ssh->kex->hostkey_type) && + ctx->ca_available && + (ssh->kex->flags & KEX_HOSTCERT_CONVERT) == 0) { + debug("%s: server offered certificate host key, " + "skipping UserKnownHostsFile update", __func__); + goto out; + } else if (ctx->nnew == 0 && ctx->nold != 0) { /* We have some keys to remove. Just do it. */ update_known_hosts(ctx); } else if (ctx->nnew != 0) {