summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-01-25 00:21:08 +0000
committerDamien Miller <djm@mindrot.org>2020-01-25 11:35:56 +1100
commit7955633a554397bc24913cec9fd7285002935f7e (patch)
tree94808f0b095cf811cf322a432e9f20e84660b0f2 /clientloop.c
parente5a278a62ab49dffe96929fa8d8506c6928dba90 (diff)
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
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/clientloop.c b/clientloop.c
index d4c23d554..874e1286d 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.332 2020/01/23 07:10:22 dtucker Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.333 2020/01/25 00:21:08 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1895,6 +1895,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
1895 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE; 1895 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE;
1896 char *fp, *response; 1896 char *fp, *response;
1897 size_t i; 1897 size_t i;
1898 struct stat sb;
1898 1899
1899 for (i = 0; i < ctx->nkeys; i++) { 1900 for (i = 0; i < ctx->nkeys; i++) {
1900 if (ctx->keys_seen[i] != 2) 1901 if (ctx->keys_seen[i] != 2)
@@ -1941,19 +1942,37 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
1941 if (was_raw) 1942 if (was_raw)
1942 enter_raw_mode(1); 1943 enter_raw_mode(1);
1943 } 1944 }
1944 1945 if (options.update_hostkeys == 0)
1946 return;
1945 /* 1947 /*
1946 * Now that all the keys are verified, we can go ahead and replace 1948 * Now that all the keys are verified, we can go ahead and replace
1947 * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't 1949 * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't
1948 * cancel the operation). 1950 * cancel the operation).
1949 */ 1951 */
1950 if (options.update_hostkeys != 0 && 1952 for (i = 0; i < options.num_user_hostfiles; i++) {
1951 (r = hostfile_replace_entries(options.user_hostfiles[0], 1953 /*
1952 ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, 1954 * NB. keys are only added to hostfiles[0], for the rest we
1953 options.hash_known_hosts, 0, 1955 * just delete the hostname entries.
1954 options.fingerprint_hash)) != 0) 1956 */
1955 error("%s: hostfile_replace_entries failed: %s", 1957 if (stat(options.user_hostfiles[i], &sb) != 0) {
1956 __func__, ssh_err(r)); 1958 if (errno == ENOENT) {
1959 debug("%s: known hosts file %s does not exist",
1960 __func__, strerror(errno));
1961 } else {
1962 error("%s: known hosts file %s inaccessible",
1963 __func__, strerror(errno));
1964 }
1965 continue;
1966 }
1967 if ((r = hostfile_replace_entries(options.user_hostfiles[i],
1968 ctx->host_str, ctx->ip_str,
1969 i == 0 ? ctx->keys : NULL, i == 0 ? ctx->nkeys : 0,
1970 options.hash_known_hosts, 0,
1971 options.fingerprint_hash)) != 0) {
1972 error("%s: hostfile_replace_entries failed for %s: %s",
1973 __func__, options.user_hostfiles[i], ssh_err(r));
1974 }
1975 }
1957} 1976}
1958 1977
1959static void 1978static void
@@ -2146,11 +2165,21 @@ client_input_hostkeys(struct ssh *ssh)
2146 options.check_host_ip ? &ctx->ip_str : NULL); 2165 options.check_host_ip ? &ctx->ip_str : NULL);
2147 2166
2148 /* Find which keys we already know about. */ 2167 /* Find which keys we already know about. */
2149 if ((r = hostkeys_foreach(options.user_hostfiles[0], hostkeys_find, 2168 for (i = 0; i < options.num_user_hostfiles; i++) {
2150 ctx, ctx->host_str, ctx->ip_str, 2169 debug("%s: searching %s for %s / %s", __func__,
2151 HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) { 2170 options.user_hostfiles[i], ctx->host_str, ctx->ip_str);
2152 error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); 2171 if ((r = hostkeys_foreach(options.user_hostfiles[i],
2153 goto out; 2172 hostkeys_find, ctx, ctx->host_str, ctx->ip_str,
2173 HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) {
2174 if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
2175 error("%s: hostkeys file %s does not exist",
2176 __func__, options.user_hostfiles[i]);
2177 continue;
2178 }
2179 error("%s: hostkeys_foreach failed for %s: %s",
2180 __func__, options.user_hostfiles[i], ssh_err(r));
2181 goto out;
2182 }
2154 } 2183 }
2155 2184
2156 /* Figure out if we have any new keys to add */ 2185 /* Figure out if we have any new keys to add */