[openssh-commits] [openssh] 05/06: upstream: support multiple files in a ssh_config RevokedHostKeys

git+noreply at mindrot.org git+noreply at mindrot.org
Thu Feb 12 10:30:33 AEDT 2026


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 2f51e29b9a0ffd7acb9dc70d90defa466b5695d4
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Wed Feb 11 22:57:55 2026 +0000

    upstream: support multiple files in a ssh_config RevokedHostKeys
    
    directive bz3918; ok dtucker
    
    OpenBSD-Commit-ID: 0ad2eacf836f912f347846ab84760799033dd348
---
 readconf.c   | 42 +++++++++++++++++++++++++++++++++++++-----
 readconf.h   |  5 +++--
 ssh.c        | 11 ++++++-----
 sshconnect.c | 13 +++++++------
 4 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/readconf.c b/readconf.c
index 1e7e24002..064fd33a7 100644
--- a/readconf.c
+++ b/readconf.c
@@ -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 at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at 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,
diff --git a/readconf.h b/readconf.h
index 942149f9a..4626d74a2 100644
--- a/readconf.h
+++ b/readconf.h
@@ -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 at 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 ce4648f99..8c4b79be4 100644
--- 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 at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at 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) {
diff --git a/sshconnect.c b/sshconnect.c
index a0dcf6f5f..16bdb1c1e 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -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 at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at 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;
 		}

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list