]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: support multiple files in a ssh_config RevokedHostKeys
authordjm@openbsd.org <djm@openbsd.org>
Wed, 11 Feb 2026 22:57:55 +0000 (22:57 +0000)
committerDamien Miller <djm@mindrot.org>
Wed, 11 Feb 2026 23:30:11 +0000 (10:30 +1100)
directive bz3918; ok dtucker

OpenBSD-Commit-ID: 0ad2eacf836f912f347846ab84760799033dd348

readconf.c
readconf.h
ssh.c
sshconnect.c

index 1e7e240027ddcc02cc7d3ae56ca330757234aba7..064fd33a7d7bb9d32cc401afabb51997bf19d9e5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.408 2026/02/08 19:54:31 dtucker Exp $ */
+/* $OpenBSD: readconf.c,v 1.409 2026/02/11 22:57:55 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2326,8 +2326,38 @@ parse_pubkey_algos:
                goto parse_flag;
 
        case oRevokedHostKeys:
-               charptr = &options->revoked_host_keys;
-               goto parse_string;
+               uintptr = &options->num_revoked_host_keys;
+               cppptr = &options->revoked_host_keys;
+               found = *uintptr == 0;
+               while ((arg = argv_next(&ac, &av)) != NULL) {
+                       if (*arg == '\0') {
+                               error("%s line %d: keyword %s empty argument",
+                                   filename, linenum, keyword);
+                               goto out;
+                       }
+                       /* Allow "none" only in first position */
+                       if (strcasecmp(arg, "none") == 0) {
+                               if (nstrs > 0 || ac > 0) {
+                                       error("%s line %d: keyword %s \"none\" "
+                                           "argument must appear alone.",
+                                           filename, linenum, keyword);
+                                       goto out;
+                               }
+                       }
+                       opt_array_append(filename, linenum, keyword,
+                           &strs, &nstrs, arg);
+               }
+               if (nstrs == 0) {
+                       fatal("%s line %d: no %s specified",
+                           filename, linenum, keyword);
+               }
+               if (found && *activep) {
+                       *cppptr = strs;
+                       *uintptr = nstrs;
+                       strs = NULL; /* transferred */
+                       nstrs = 0;
+               }
+               break;
 
        case oFingerprintHash:
                intptr = &options->fingerprint_hash;
@@ -2785,6 +2815,7 @@ initialize_options(Options * options)
        options->canonicalize_fallback_local = -1;
        options->canonicalize_hostname = -1;
        options->revoked_host_keys = NULL;
+       options->num_revoked_host_keys = 0;
        options->fingerprint_hash = -1;
        options->update_hostkeys = -1;
        options->hostbased_accepted_algos = NULL;
@@ -3053,11 +3084,11 @@ fill_default_options(Options * options)
        CLEAR_ON_NONE(options->remote_command);
        CLEAR_ON_NONE(options->proxy_command);
        CLEAR_ON_NONE(options->control_path);
-       CLEAR_ON_NONE(options->revoked_host_keys);
        CLEAR_ON_NONE(options->pkcs11_provider);
        CLEAR_ON_NONE(options->sk_provider);
        CLEAR_ON_NONE(options->known_hosts_command);
        CLEAR_ON_NONE_ARRAY(channel_timeouts, num_channel_timeouts, "none");
+       CLEAR_ON_NONE_ARRAY(revoked_host_keys, num_revoked_host_keys, "none");
 #undef CLEAR_ON_NONE
 #undef CLEAR_ON_NONE_ARRAY
        if (options->jump_host != NULL &&
@@ -3168,6 +3199,7 @@ free_options(Options *o)
                free(o->permitted_cnames[i].source_list);
                free(o->permitted_cnames[i].target_list);
        }
+       FREE_ARRAY(u_int, o->num_revoked_host_keys, o->revoked_host_keys);
        free(o->revoked_host_keys);
        free(o->hostbased_accepted_algos);
        free(o->pubkey_accepted_algos);
@@ -3747,7 +3779,6 @@ dump_client_config(Options *o, const char *host)
        dump_cfg_string(oSecurityKeyProvider, o->sk_provider);
        dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
        dump_cfg_string(oPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
-       dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
        dump_cfg_string(oXAuthLocation, o->xauth_location);
        dump_cfg_string(oKnownHostsCommand, o->known_hosts_command);
        dump_cfg_string(oTag, o->tag);
@@ -3764,6 +3795,7 @@ dump_client_config(Options *o, const char *host)
        dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
        dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
        dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
+       dump_cfg_strarray_oneline(oRevokedHostKeys, o->num_revoked_host_keys, o->revoked_host_keys);
        dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
        dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
        dump_cfg_strarray_oneline(oLogVerbose,
index 942149f9ae3f01e0ae20e03d9bfdd1cf750d3633..4626d74a20af14c636539305b4f3618ea3643702 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.161 2025/08/11 10:55:38 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.162 2026/02/11 22:57:55 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -162,7 +162,8 @@ typedef struct {
        int     num_permitted_cnames;
        struct allowed_cname *permitted_cnames;
 
-       char    *revoked_host_keys;
+       u_int   num_revoked_host_keys;
+       char    **revoked_host_keys;
 
        int      fingerprint_hash;
 
diff --git a/ssh.c b/ssh.c
index ce4648f99dbf78b4ddfa8ca54324f83edcd3f352..8c4b79be46b9d310a334f9698fd1acf225e3b656 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.623 2026/02/11 17:05:32 dtucker Exp $ */
+/* $OpenBSD: ssh.c,v 1.624 2026/02/11 22:57:55 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1536,12 +1536,13 @@ main(int ac, char **av)
                options.identity_agent = cp;
        }
 
-       if (options.revoked_host_keys != NULL) {
-               p = tilde_expand_filename(options.revoked_host_keys, getuid());
+       for (j = 0; j < options.num_revoked_host_keys; j++) {
+               p = tilde_expand_filename(options.revoked_host_keys[j],
+                   getuid());
                cp = default_client_percent_dollar_expand(p, cinfo);
                free(p);
-               free(options.revoked_host_keys);
-               options.revoked_host_keys = cp;
+               free(options.revoked_host_keys[j]);
+               options.revoked_host_keys[j] = cp;
        }
 
        if (options.forward_agent_sock_path != NULL) {
index a0dcf6f5f958ab1193097ed9bada0e62dba76005..16bdb1c1e474897d69bf2eae9b72d2da410ea8d3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.379 2026/02/11 17:05:32 dtucker Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.380 2026/02/11 22:57:55 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1508,22 +1508,23 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key,
                goto out;
        }
 
-       /* Check in RevokedHostKeys file if specified */
-       if (options.revoked_host_keys != NULL) {
-               r = sshkey_check_revoked(host_key, options.revoked_host_keys);
+       /* Check in RevokedHostKeys files if specified */
+       for (i = 0; i < options.num_revoked_host_keys; i++) {
+               r = sshkey_check_revoked(host_key,
+                   options.revoked_host_keys[i]);
                switch (r) {
                case 0:
                        break; /* not revoked */
                case SSH_ERR_KEY_REVOKED:
                        error("Host key %s %s revoked by file %s",
                            sshkey_type(host_key), fp,
-                           options.revoked_host_keys);
+                           options.revoked_host_keys[i]);
                        r = -1;
                        goto out;
                default:
                        error_r(r, "Error checking host key %s %s in "
                            "revoked keys file %s", sshkey_type(host_key),
-                           fp, options.revoked_host_keys);
+                           fp, options.revoked_host_keys[i]);
                        r = -1;
                        goto out;
                }