[openssh-commits] [openssh] 10/11: upstream: allow UpdateKnownHosts=yes to function when multiple

git+noreply at mindrot.org git+noreply at mindrot.org
Sat Jan 25 11:36:36 AEDT 2020


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

djm pushed a commit to branch master
in repository openssh.

commit 7955633a554397bc24913cec9fd7285002935f7e
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Sat Jan 25 00:21:08 2020 +0000

    upstream: allow UpdateKnownHosts=yes to function when multiple
    
    known_hosts files are in use. When updating host keys, ssh will now search
    subsequent known_hosts files, but will add new/changed host keys to the first
    specified file only. bz#2738
    
    ok markus@
    
    OpenBSD-Commit-ID: 6ded6d878a03e57d5aa20bab9c31f92e929dbc6c
---
 clientloop.c | 57 +++++++++++++++++++++++++++++++++++++++++++--------------
 hostfile.c   |  3 ++-
 ssh.c        |  4 ++--
 3 files changed, 47 insertions(+), 17 deletions(-)

diff --git a/clientloop.c b/clientloop.c
index d4c23d55..874e1286 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.332 2020/01/23 07:10:22 dtucker Exp $ */
+/* $OpenBSD: clientloop.c,v 1.333 2020/01/25 00:21:08 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -1895,6 +1895,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
 	    SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE;
 	char *fp, *response;
 	size_t i;
+	struct stat sb;
 
 	for (i = 0; i < ctx->nkeys; i++) {
 		if (ctx->keys_seen[i] != 2)
@@ -1941,19 +1942,37 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
 		if (was_raw)
 			enter_raw_mode(1);
 	}
-
+	if (options.update_hostkeys == 0)
+		return;
 	/*
 	 * Now that all the keys are verified, we can go ahead and replace
 	 * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't
 	 * cancel the operation).
 	 */
-	if (options.update_hostkeys != 0 &&
-	    (r = hostfile_replace_entries(options.user_hostfiles[0],
-	    ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys,
-	    options.hash_known_hosts, 0,
-	    options.fingerprint_hash)) != 0)
-		error("%s: hostfile_replace_entries failed: %s",
-		    __func__, ssh_err(r));
+	for (i = 0; i < options.num_user_hostfiles; i++) {
+		/*
+		 * NB. keys are only added to hostfiles[0], for the rest we
+		 * just delete the hostname entries.
+		 */
+		if (stat(options.user_hostfiles[i], &sb) != 0) {
+			if (errno == ENOENT) {
+				debug("%s: known hosts file %s does not exist",
+				    __func__, strerror(errno));
+			} else {
+				error("%s: known hosts file %s inaccessible",
+				    __func__, strerror(errno));
+			}
+			continue;
+		}
+		if ((r = hostfile_replace_entries(options.user_hostfiles[i],
+		    ctx->host_str, ctx->ip_str,
+		    i == 0 ? ctx->keys : NULL, i == 0 ? ctx->nkeys : 0,
+		    options.hash_known_hosts, 0,
+		    options.fingerprint_hash)) != 0) {
+			error("%s: hostfile_replace_entries failed for %s: %s",
+			    __func__, options.user_hostfiles[i], ssh_err(r));
+		}
+	}
 }
 
 static void
@@ -2146,11 +2165,21 @@ client_input_hostkeys(struct ssh *ssh)
 	    options.check_host_ip ? &ctx->ip_str : NULL);
 
 	/* Find which keys we already know about. */
-	if ((r = hostkeys_foreach(options.user_hostfiles[0], hostkeys_find,
-	    ctx, ctx->host_str, ctx->ip_str,
-	    HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) {
-		error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
-		goto out;
+	for (i = 0; i < options.num_user_hostfiles; i++) {
+		debug("%s: searching %s for %s / %s", __func__,
+		    options.user_hostfiles[i], ctx->host_str, ctx->ip_str);
+		if ((r = hostkeys_foreach(options.user_hostfiles[i],
+		    hostkeys_find, ctx, ctx->host_str, ctx->ip_str,
+		    HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) {
+			if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
+				error("%s: hostkeys file %s does not exist",
+				    __func__, options.user_hostfiles[i]);
+				continue;
+			}
+			error("%s: hostkeys_foreach failed for %s: %s",
+			    __func__, options.user_hostfiles[i], ssh_err(r));
+			goto out;
+		}
 	}
 
 	/* Figure out if we have any new keys to add */
diff --git a/hostfile.c b/hostfile.c
index 96ab880d..4a0349a6 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.76 2019/07/07 01:05:00 dtucker Exp $ */
+/* $OpenBSD: hostfile.c,v 1.77 2020/01/25 00:21:08 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -566,6 +566,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
 	/* Remove all entries for the specified host from the file */
 	if ((r = hostkeys_foreach(filename, host_delete, &ctx, host, ip,
 	    HKF_WANT_PARSE_KEY)) != 0) {
+		oerrno = errno;
 		error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
 		goto fail;
 	}
diff --git a/ssh.c b/ssh.c
index 8931ecf8..4998ebc1 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.514 2020/01/25 00:03:36 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.515 2020/01/25 00:21:08 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -1248,7 +1248,7 @@ main(int ac, char **av)
 	    strcmp(options.proxy_command, "-") == 0 &&
 	    options.proxy_use_fdpass)
 		fatal("ProxyCommand=- and ProxyUseFDPass are incompatible");
-	if (options.control_persist &&
+	if (options.control_persist && options.control_path != NULL &&
 	    options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
 		debug("UpdateHostKeys=ask is incompatible with ControlPersist; "
 		    "disabling");

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


More information about the openssh-commits mailing list