diff options
-rw-r--r-- | sshconnect2.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index 4c4a61ba0..af00fb30c 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.319 2020/02/06 22:30:54 naddy Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.320 2020/02/06 22:48:23 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -119,7 +119,7 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) | |||
119 | for (i = 0; i < options.num_system_hostfiles; i++) | 119 | for (i = 0; i < options.num_system_hostfiles; i++) |
120 | load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); | 120 | load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); |
121 | 121 | ||
122 | oavail = avail = xstrdup(kex_default_pk_alg()); | 122 | oavail = avail = xstrdup(options.hostkeyalgorithms); |
123 | maxlen = strlen(avail) + 1; | 123 | maxlen = strlen(avail) + 1; |
124 | first = xmalloc(maxlen); | 124 | first = xmalloc(maxlen); |
125 | last = xmalloc(maxlen); | 125 | last = xmalloc(maxlen); |
@@ -161,11 +161,28 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) | |||
161 | { | 161 | { |
162 | char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; | 162 | char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; |
163 | char *s, *all_key; | 163 | char *s, *all_key; |
164 | int r; | 164 | int r, use_known_hosts_order = 0; |
165 | 165 | ||
166 | xxx_host = host; | 166 | xxx_host = host; |
167 | xxx_hostaddr = hostaddr; | 167 | xxx_hostaddr = hostaddr; |
168 | 168 | ||
169 | /* | ||
170 | * If the user has not specified HostkeyAlgorithms, or has only | ||
171 | * appended or removed algorithms from that list then prefer algorithms | ||
172 | * that are in the list that are supported by known_hosts keys. | ||
173 | */ | ||
174 | if (options.hostkeyalgorithms == NULL || | ||
175 | options.hostkeyalgorithms[0] == '-' || | ||
176 | options.hostkeyalgorithms[0] == '+') | ||
177 | use_known_hosts_order = 1; | ||
178 | |||
179 | /* Expand or fill in HostkeyAlgorithms */ | ||
180 | all_key = sshkey_alg_list(0, 0, 1, ','); | ||
181 | if (kex_assemble_names(&options.hostkeyalgorithms, | ||
182 | kex_default_pk_alg(), all_key) != 0) | ||
183 | fatal("%s: kex_assemble_namelist", __func__); | ||
184 | free(all_key); | ||
185 | |||
169 | if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) | 186 | if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) |
170 | fatal("%s: kex_names_cat", __func__); | 187 | fatal("%s: kex_names_cat", __func__); |
171 | myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); | 188 | myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); |
@@ -178,21 +195,15 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) | |||
178 | (char *)compression_alg_list(options.compression); | 195 | (char *)compression_alg_list(options.compression); |
179 | myproposal[PROPOSAL_MAC_ALGS_CTOS] = | 196 | myproposal[PROPOSAL_MAC_ALGS_CTOS] = |
180 | myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; | 197 | myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; |
181 | if (options.hostkeyalgorithms != NULL) { | 198 | if (use_known_hosts_order) { |
182 | all_key = sshkey_alg_list(0, 0, 1, ','); | 199 | /* Query known_hosts and prefer algorithms that appear there */ |
183 | if (kex_assemble_names(&options.hostkeyalgorithms, | ||
184 | kex_default_pk_alg(), all_key) != 0) | ||
185 | fatal("%s: kex_assemble_namelist", __func__); | ||
186 | free(all_key); | ||
187 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = | ||
188 | compat_pkalg_proposal(options.hostkeyalgorithms); | ||
189 | } else { | ||
190 | /* Enforce default */ | ||
191 | options.hostkeyalgorithms = xstrdup(kex_default_pk_alg()); | ||
192 | /* Prefer algorithms that we already have keys for */ | ||
193 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = | 200 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = |
194 | compat_pkalg_proposal( | 201 | compat_pkalg_proposal( |
195 | order_hostkeyalgs(host, hostaddr, port)); | 202 | order_hostkeyalgs(host, hostaddr, port)); |
203 | } else { | ||
204 | /* Use specified HostkeyAlgorithms exactly */ | ||
205 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = | ||
206 | compat_pkalg_proposal(options.hostkeyalgorithms); | ||
196 | } | 207 | } |
197 | 208 | ||
198 | if (options.rekey_limit || options.rekey_interval) | 209 | if (options.rekey_limit || options.rekey_interval) |