summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-07-04 13:49:31 +0000
committerDamien Miller <djm@mindrot.org>2018-07-04 23:51:52 +1000
commit312d2f2861a2598ed08587cb6c45c0e98a85408f (patch)
treee3bdc4facef48a89cd76fa793d9e70211b7ff8d2
parent303af5803bd74bf05d375c04e1a83b40c30b2be5 (diff)
upstream: repair PubkeyAcceptedKeyTypes (and friends) after RSA
signature work - returns ability to add/remove/specify algorithms by wildcard. Algorithm lists are now fully expanded when the server/client configs are finalised, so errors are reported early and the config dumps (e.g. "ssh -G ...") now list the actual algorithms selected. Clarify that, while wildcards are accepted in algorithm lists, they aren't full pattern-lists that support negation. (lots of) feedback, ok markus@ OpenBSD-Commit-ID: a8894c5c81f399a002f02ff4fe6b4fa46b1f3207
-rw-r--r--compat.c18
-rw-r--r--kex.c95
-rw-r--r--kex.h4
-rw-r--r--match.c36
-rw-r--r--match.h5
-rw-r--r--readconf.c38
-rw-r--r--servconf.c32
-rw-r--r--ssh_config.58
-rw-r--r--sshconnect2.c10
-rw-r--r--sshd_config.58
10 files changed, 187 insertions, 67 deletions
diff --git a/compat.c b/compat.c
index 8335f2a94..d8fd6eaf8 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.c,v 1.109 2018/07/03 11:42:12 djm Exp $ */ 1/* $OpenBSD: compat.c,v 1.110 2018/07/04 13:49:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -190,8 +190,8 @@ compat_cipher_proposal(char *cipher_prop)
190 if (!(datafellows & SSH_BUG_BIGENDIANAES)) 190 if (!(datafellows & SSH_BUG_BIGENDIANAES))
191 return cipher_prop; 191 return cipher_prop;
192 debug2("%s: original cipher proposal: %s", __func__, cipher_prop); 192 debug2("%s: original cipher proposal: %s", __func__, cipher_prop);
193 if ((cipher_prop = match_filter_list(cipher_prop, "aes*")) == NULL) 193 if ((cipher_prop = match_filter_blacklist(cipher_prop, "aes*")) == NULL)
194 fatal("match_filter_list failed"); 194 fatal("match_filter_blacklist failed");
195 debug2("%s: compat cipher proposal: %s", __func__, cipher_prop); 195 debug2("%s: compat cipher proposal: %s", __func__, cipher_prop);
196 if (*cipher_prop == '\0') 196 if (*cipher_prop == '\0')
197 fatal("No supported ciphers found"); 197 fatal("No supported ciphers found");
@@ -204,8 +204,8 @@ compat_pkalg_proposal(char *pkalg_prop)
204 if (!(datafellows & SSH_BUG_RSASIGMD5)) 204 if (!(datafellows & SSH_BUG_RSASIGMD5))
205 return pkalg_prop; 205 return pkalg_prop;
206 debug2("%s: original public key proposal: %s", __func__, pkalg_prop); 206 debug2("%s: original public key proposal: %s", __func__, pkalg_prop);
207 if ((pkalg_prop = match_filter_list(pkalg_prop, "ssh-rsa")) == NULL) 207 if ((pkalg_prop = match_filter_blacklist(pkalg_prop, "ssh-rsa")) == NULL)
208 fatal("match_filter_list failed"); 208 fatal("match_filter_blacklist failed");
209 debug2("%s: compat public key proposal: %s", __func__, pkalg_prop); 209 debug2("%s: compat public key proposal: %s", __func__, pkalg_prop);
210 if (*pkalg_prop == '\0') 210 if (*pkalg_prop == '\0')
211 fatal("No supported PK algorithms found"); 211 fatal("No supported PK algorithms found");
@@ -219,14 +219,14 @@ compat_kex_proposal(char *p)
219 return p; 219 return p;
220 debug2("%s: original KEX proposal: %s", __func__, p); 220 debug2("%s: original KEX proposal: %s", __func__, p);
221 if ((datafellows & SSH_BUG_CURVE25519PAD) != 0) 221 if ((datafellows & SSH_BUG_CURVE25519PAD) != 0)
222 if ((p = match_filter_list(p, 222 if ((p = match_filter_blacklist(p,
223 "curve25519-sha256@libssh.org")) == NULL) 223 "curve25519-sha256@libssh.org")) == NULL)
224 fatal("match_filter_list failed"); 224 fatal("match_filter_blacklist failed");
225 if ((datafellows & SSH_OLD_DHGEX) != 0) { 225 if ((datafellows & SSH_OLD_DHGEX) != 0) {
226 if ((p = match_filter_list(p, 226 if ((p = match_filter_blacklist(p,
227 "diffie-hellman-group-exchange-sha256," 227 "diffie-hellman-group-exchange-sha256,"
228 "diffie-hellman-group-exchange-sha1")) == NULL) 228 "diffie-hellman-group-exchange-sha1")) == NULL)
229 fatal("match_filter_list failed"); 229 fatal("match_filter_blacklist failed");
230 } 230 }
231 debug2("%s: compat KEX proposal: %s", __func__, p); 231 debug2("%s: compat KEX proposal: %s", __func__, p);
232 if (*p == '\0') 232 if (*p == '\0')
diff --git a/kex.c b/kex.c
index d0a5f1b66..2fd052e96 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.137 2018/07/03 11:39:54 djm Exp $ */ 1/* $OpenBSD: kex.c,v 1.138 2018/07/04 13:49:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -174,7 +174,7 @@ kex_names_cat(const char *a, const char *b)
174 size_t len; 174 size_t len;
175 175
176 if (a == NULL || *a == '\0') 176 if (a == NULL || *a == '\0')
177 return NULL; 177 return strdup(b);
178 if (b == NULL || *b == '\0') 178 if (b == NULL || *b == '\0')
179 return strdup(a); 179 return strdup(a);
180 if (strlen(b) > 1024*1024) 180 if (strlen(b) > 1024*1024)
@@ -209,27 +209,88 @@ kex_names_cat(const char *a, const char *b)
209 * specified names should be removed. 209 * specified names should be removed.
210 */ 210 */
211int 211int
212kex_assemble_names(const char *def, char **list) 212kex_assemble_names(char **listp, const char *def, const char *all)
213{ 213{
214 char *ret; 214 char *cp, *tmp, *patterns;
215 char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL;
216 int r = SSH_ERR_INTERNAL_ERROR;
215 217
216 if (list == NULL || *list == NULL || **list == '\0') { 218 if (listp == NULL || *listp == NULL || **listp == '\0') {
217 *list = strdup(def); 219 if ((*listp = strdup(def)) == NULL)
220 return SSH_ERR_ALLOC_FAIL;
218 return 0; 221 return 0;
219 } 222 }
220 if (**list == '+') { 223
221 if ((ret = kex_names_cat(def, *list + 1)) == NULL) 224 list = *listp;
222 return SSH_ERR_ALLOC_FAIL; 225 *listp = NULL;
223 free(*list); 226 if (*list == '+') {
224 *list = ret; 227 /* Append names to default list */
225 } else if (**list == '-') { 228 if ((tmp = kex_names_cat(def, list + 1)) == NULL) {
226 if ((ret = match_filter_list(def, *list + 1)) == NULL) 229 r = SSH_ERR_ALLOC_FAIL;
227 return SSH_ERR_ALLOC_FAIL; 230 goto fail;
228 free(*list); 231 }
229 *list = ret; 232 free(list);
233 list = tmp;
234 } else if (*list == '-') {
235 /* Remove names from default list */
236 if ((*listp = match_filter_blacklist(def, list + 1)) == NULL) {
237 r = SSH_ERR_ALLOC_FAIL;
238 goto fail;
239 }
240 free(list);
241 /* filtering has already been done */
242 return 0;
243 } else {
244 /* Explicit list, overrides default - just use "list" as is */
230 } 245 }
231 246
232 return 0; 247 /*
248 * The supplied names may be a pattern-list. For the -list case,
249 * the patterns are applied above. For the +list and explicit list
250 * cases we need to do it now.
251 */
252 ret = NULL;
253 if ((patterns = opatterns = strdup(list)) == NULL) {
254 r = SSH_ERR_ALLOC_FAIL;
255 goto fail;
256 }
257 /* Apply positive (i.e. non-negated) patterns from the list */
258 while ((cp = strsep(&patterns, ",")) != NULL) {
259 if (*cp == '!') {
260 /* negated matches are not supported here */
261 r = SSH_ERR_INVALID_ARGUMENT;
262 goto fail;
263 }
264 free(matching);
265 if ((matching = match_filter_whitelist(all, cp)) == NULL) {
266 r = SSH_ERR_ALLOC_FAIL;
267 goto fail;
268 }
269 if ((tmp = kex_names_cat(ret, matching)) == NULL) {
270 r = SSH_ERR_ALLOC_FAIL;
271 goto fail;
272 }
273 free(ret);
274 ret = tmp;
275 }
276 if (ret == NULL || *ret == '\0') {
277 /* An empty name-list is an error */
278 /* XXX better error code? */
279 r = SSH_ERR_INVALID_ARGUMENT;
280 goto fail;
281 }
282
283 /* success */
284 *listp = ret;
285 ret = NULL;
286 r = 0;
287
288 fail:
289 free(matching);
290 free(opatterns);
291 free(list);
292 free(ret);
293 return r;
233} 294}
234 295
235/* put algorithm proposal into buffer */ 296/* put algorithm proposal into buffer */
diff --git a/kex.h b/kex.h
index 6210630df..3ffae2df0 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.h,v 1.84 2018/07/03 11:39:54 djm Exp $ */ 1/* $OpenBSD: kex.h,v 1.85 2018/07/04 13:49:31 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -169,7 +169,7 @@ struct kex {
169int kex_names_valid(const char *); 169int kex_names_valid(const char *);
170char *kex_alg_list(char); 170char *kex_alg_list(char);
171char *kex_names_cat(const char *, const char *); 171char *kex_names_cat(const char *, const char *);
172int kex_assemble_names(const char *, char **); 172int kex_assemble_names(char **, const char *, const char *);
173 173
174int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); 174int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **);
175int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); 175int kex_setup(struct ssh *, char *[PROPOSAL_MAX]);
diff --git a/match.c b/match.c
index 3cf40306b..bb3e95f67 100644
--- a/match.c
+++ b/match.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: match.c,v 1.37 2017/03/10 04:24:55 djm Exp $ */ 1/* $OpenBSD: match.c,v 1.38 2018/07/04 13:49:31 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
@@ -294,16 +294,20 @@ match_list(const char *client, const char *server, u_int *next)
294} 294}
295 295
296/* 296/*
297 * Filters a comma-separated list of strings, excluding any entry matching 297 * Filter proposal using pattern-list filter.
298 * the 'filter' pattern list. Caller must free returned string. 298 * "blacklist" determines sense of filter:
299 * non-zero indicates that items matching filter should be excluded.
300 * zero indicates that only items matching filter should be included.
301 * returns NULL on allocation error, otherwise caller must free result.
299 */ 302 */
300char * 303static char *
301match_filter_list(const char *proposal, const char *filter) 304filter_list(const char *proposal, const char *filter, int blacklist)
302{ 305{
303 size_t len = strlen(proposal) + 1; 306 size_t len = strlen(proposal) + 1;
304 char *fix_prop = malloc(len); 307 char *fix_prop = malloc(len);
305 char *orig_prop = strdup(proposal); 308 char *orig_prop = strdup(proposal);
306 char *cp, *tmp; 309 char *cp, *tmp;
310 int r;
307 311
308 if (fix_prop == NULL || orig_prop == NULL) { 312 if (fix_prop == NULL || orig_prop == NULL) {
309 free(orig_prop); 313 free(orig_prop);
@@ -314,7 +318,8 @@ match_filter_list(const char *proposal, const char *filter)
314 tmp = orig_prop; 318 tmp = orig_prop;
315 *fix_prop = '\0'; 319 *fix_prop = '\0';
316 while ((cp = strsep(&tmp, ",")) != NULL) { 320 while ((cp = strsep(&tmp, ",")) != NULL) {
317 if (match_pattern_list(cp, filter, 0) != 1) { 321 r = match_pattern_list(cp, filter, 0);
322 if ((blacklist && r != 1) || (!blacklist && r == 1)) {
318 if (*fix_prop != '\0') 323 if (*fix_prop != '\0')
319 strlcat(fix_prop, ",", len); 324 strlcat(fix_prop, ",", len);
320 strlcat(fix_prop, cp, len); 325 strlcat(fix_prop, cp, len);
@@ -324,3 +329,22 @@ match_filter_list(const char *proposal, const char *filter)
324 return fix_prop; 329 return fix_prop;
325} 330}
326 331
332/*
333 * Filters a comma-separated list of strings, excluding any entry matching
334 * the 'filter' pattern list. Caller must free returned string.
335 */
336char *
337match_filter_blacklist(const char *proposal, const char *filter)
338{
339 return filter_list(proposal, filter, 1);
340}
341
342/*
343 * Filters a comma-separated list of strings, including only entries matching
344 * the 'filter' pattern list. Caller must free returned string.
345 */
346char *
347match_filter_whitelist(const char *proposal, const char *filter)
348{
349 return filter_list(proposal, filter, 0);
350}
diff --git a/match.h b/match.h
index 937ba0412..852b1a5cb 100644
--- a/match.h
+++ b/match.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: match.h,v 1.17 2017/02/03 23:01:19 djm Exp $ */ 1/* $OpenBSD: match.h,v 1.18 2018/07/04 13:49:31 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -20,7 +20,8 @@ int match_hostname(const char *, const char *);
20int match_host_and_ip(const char *, const char *, const char *); 20int match_host_and_ip(const char *, const char *, const char *);
21int match_user(const char *, const char *, const char *, const char *); 21int match_user(const char *, const char *, const char *, const char *);
22char *match_list(const char *, const char *, u_int *); 22char *match_list(const char *, const char *, u_int *);
23char *match_filter_list(const char *, const char *); 23char *match_filter_blacklist(const char *, const char *);
24char *match_filter_whitelist(const char *, const char *);
24 25
25/* addrmatch.c */ 26/* addrmatch.c */
26int addr_match_list(const char *, const char *); 27int addr_match_list(const char *, const char *);
diff --git a/readconf.c b/readconf.c
index 8d2029547..2bc27075f 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.291 2018/06/10 23:45:41 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.292 2018/07/04 13:49:31 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
@@ -1936,6 +1936,8 @@ fill_default_options_for_canonicalization(Options *options)
1936void 1936void
1937fill_default_options(Options * options) 1937fill_default_options(Options * options)
1938{ 1938{
1939 char *all_cipher, *all_mac, *all_kex, *all_key;
1940
1939 if (options->forward_agent == -1) 1941 if (options->forward_agent == -1)
1940 options->forward_agent = 0; 1942 options->forward_agent = 0;
1941 if (options->forward_x11 == -1) 1943 if (options->forward_x11 == -1)
@@ -2082,14 +2084,27 @@ fill_default_options(Options * options)
2082 options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 2084 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2083 if (options->update_hostkeys == -1) 2085 if (options->update_hostkeys == -1)
2084 options->update_hostkeys = 0; 2086 options->update_hostkeys = 0;
2085 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || 2087
2086 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || 2088 /* Expand KEX name lists */
2087 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || 2089 all_cipher = cipher_alg_list(',', 0);
2088 kex_assemble_names(KEX_DEFAULT_PK_ALG, 2090 all_mac = mac_alg_list(',');
2089 &options->hostbased_key_types) != 0 || 2091 all_kex = kex_alg_list(',');
2090 kex_assemble_names(KEX_DEFAULT_PK_ALG, 2092 all_key = sshkey_alg_list(0, 0, 1, ',');
2091 &options->pubkey_key_types) != 0) 2093 if (kex_assemble_names(&options->ciphers,
2094 KEX_CLIENT_ENCRYPT, all_cipher) != 0 ||
2095 kex_assemble_names(&options->macs,
2096 KEX_CLIENT_MAC, all_mac) != 0 ||
2097 kex_assemble_names(&options->kex_algorithms,
2098 KEX_CLIENT_KEX, all_kex) != 0 ||
2099 kex_assemble_names(&options->hostbased_key_types,
2100 KEX_DEFAULT_PK_ALG, all_key) != 0 ||
2101 kex_assemble_names(&options->pubkey_key_types,
2102 KEX_DEFAULT_PK_ALG, all_key) != 0)
2092 fatal("%s: kex_assemble_names failed", __func__); 2103 fatal("%s: kex_assemble_names failed", __func__);
2104 free(all_cipher);
2105 free(all_mac);
2106 free(all_kex);
2107 free(all_key);
2093 2108
2094#define CLEAR_ON_NONE(v) \ 2109#define CLEAR_ON_NONE(v) \
2095 do { \ 2110 do { \
@@ -2537,11 +2552,14 @@ void
2537dump_client_config(Options *o, const char *host) 2552dump_client_config(Options *o, const char *host)
2538{ 2553{
2539 int i; 2554 int i;
2540 char buf[8]; 2555 char buf[8], *all_key;
2541 2556
2542 /* This is normally prepared in ssh_kex2 */ 2557 /* This is normally prepared in ssh_kex2 */
2543 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) 2558 all_key = sshkey_alg_list(0, 0, 1, ',');
2559 if (kex_assemble_names( &o->hostkeyalgorithms,
2560 KEX_DEFAULT_PK_ALG, all_key) != 0)
2544 fatal("%s: kex_assemble_names failed", __func__); 2561 fatal("%s: kex_assemble_names failed", __func__);
2562 free(all_key);
2545 2563
2546 /* Most interesting options first: user, host, port */ 2564 /* Most interesting options first: user, host, port */
2547 dump_cfg_string(oUser, o->user); 2565 dump_cfg_string(oUser, o->user);
diff --git a/servconf.c b/servconf.c
index a41fdc26a..a54219f01 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.334 2018/07/03 10:59:35 djm Exp $ */ 2/* $OpenBSD: servconf.c,v 1.335 2018/07/04 13:49:31 djm Exp $ */
3/* 3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved 5 * All rights reserved
@@ -190,15 +190,29 @@ option_clear_or_none(const char *o)
190static void 190static void
191assemble_algorithms(ServerOptions *o) 191assemble_algorithms(ServerOptions *o)
192{ 192{
193 if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || 193 char *all_cipher, *all_mac, *all_kex, *all_key;
194 kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || 194
195 kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || 195 all_cipher = cipher_alg_list(',', 0);
196 kex_assemble_names(KEX_DEFAULT_PK_ALG, 196 all_mac = mac_alg_list(',');
197 &o->hostkeyalgorithms) != 0 || 197 all_kex = kex_alg_list(',');
198 kex_assemble_names(KEX_DEFAULT_PK_ALG, 198 all_key = sshkey_alg_list(0, 0, 1, ',');
199 &o->hostbased_key_types) != 0 || 199 if (kex_assemble_names(&o->ciphers,
200 kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) 200 KEX_SERVER_ENCRYPT, all_cipher) != 0 ||
201 kex_assemble_names(&o->macs,
202 KEX_SERVER_MAC, all_mac) != 0 ||
203 kex_assemble_names(&o->kex_algorithms,
204 KEX_SERVER_KEX, all_kex) != 0 ||
205 kex_assemble_names(&o->hostkeyalgorithms,
206 KEX_DEFAULT_PK_ALG, all_key) != 0 ||
207 kex_assemble_names(&o->hostbased_key_types,
208 KEX_DEFAULT_PK_ALG, all_key) != 0 ||
209 kex_assemble_names(&o->pubkey_key_types,
210 KEX_DEFAULT_PK_ALG, all_key) != 0)
201 fatal("kex_assemble_names failed"); 211 fatal("kex_assemble_names failed");
212 free(all_cipher);
213 free(all_mac);
214 free(all_kex);
215 free(all_key);
202} 216}
203 217
204static void 218static void
diff --git a/ssh_config.5 b/ssh_config.5
index eff9c5e61..df94d60db 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh_config.5,v 1.278 2018/07/03 11:39:54 djm Exp $ 36.\" $OpenBSD: ssh_config.5,v 1.279 2018/07/04 13:49:31 djm Exp $
37.Dd $Mdocdate: July 3 2018 $ 37.Dd $Mdocdate: July 4 2018 $
38.Dt SSH_CONFIG 5 38.Dt SSH_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -757,7 +757,7 @@ or
757(the default). 757(the default).
758.It Cm HostbasedKeyTypes 758.It Cm HostbasedKeyTypes
759Specifies the key types that will be used for hostbased authentication 759Specifies the key types that will be used for hostbased authentication
760as a comma-separated pattern list. 760as a comma-separated list of patterns.
761Alternately if the specified value begins with a 761Alternately if the specified value begins with a
762.Sq + 762.Sq +
763character, then the specified key types will be appended to the default set 763character, then the specified key types will be appended to the default set
@@ -1242,7 +1242,7 @@ The default is
1242.Cm no . 1242.Cm no .
1243.It Cm PubkeyAcceptedKeyTypes 1243.It Cm PubkeyAcceptedKeyTypes
1244Specifies the key types that will be used for public key authentication 1244Specifies the key types that will be used for public key authentication
1245as a comma-separated pattern list. 1245as a comma-separated list of patterns.
1246Alternately if the specified value begins with a 1246Alternately if the specified value begins with a
1247.Sq + 1247.Sq +
1248character, then the key types after it will be appended to the default 1248character, then the key types after it will be appended to the default
diff --git a/sshconnect2.c b/sshconnect2.c
index db95cb214..f3ccd53a9 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.274 2018/07/03 13:20:25 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.275 2018/07/04 13:49:31 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.
@@ -158,7 +158,7 @@ void
158ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 158ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
159{ 159{
160 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; 160 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
161 char *s; 161 char *s, *all_key;
162 struct kex *kex; 162 struct kex *kex;
163 int r; 163 int r;
164 164
@@ -178,9 +178,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
178 myproposal[PROPOSAL_MAC_ALGS_CTOS] = 178 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
179 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 179 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
180 if (options.hostkeyalgorithms != NULL) { 180 if (options.hostkeyalgorithms != NULL) {
181 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, 181 all_key = sshkey_alg_list(0, 0, 1, ',');
182 &options.hostkeyalgorithms) != 0) 182 if (kex_assemble_names(&options.hostkeyalgorithms,
183 KEX_DEFAULT_PK_ALG, all_key) != 0)
183 fatal("%s: kex_assemble_namelist", __func__); 184 fatal("%s: kex_assemble_namelist", __func__);
185 free(all_key);
184 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 186 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
185 compat_pkalg_proposal(options.hostkeyalgorithms); 187 compat_pkalg_proposal(options.hostkeyalgorithms);
186 } else { 188 } else {
diff --git a/sshd_config.5 b/sshd_config.5
index cc019ec7d..aa888796e 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: sshd_config.5,v 1.279 2018/07/03 11:39:54 djm Exp $ 36.\" $OpenBSD: sshd_config.5,v 1.280 2018/07/04 13:49:31 djm Exp $
37.Dd $Mdocdate: July 3 2018 $ 37.Dd $Mdocdate: July 4 2018 $
38.Dt SSHD_CONFIG 5 38.Dt SSHD_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -659,7 +659,7 @@ The default is
659.Cm yes . 659.Cm yes .
660.It Cm HostbasedAcceptedKeyTypes 660.It Cm HostbasedAcceptedKeyTypes
661Specifies the key types that will be accepted for hostbased authentication 661Specifies the key types that will be accepted for hostbased authentication
662as a comma-separated pattern list. 662as a list of comma-separated patterns.
663Alternately if the specified value begins with a 663Alternately if the specified value begins with a
664.Sq + 664.Sq +
665character, then the specified key types will be appended to the default set 665character, then the specified key types will be appended to the default set
@@ -1386,7 +1386,7 @@ The default is
1386.Cm yes . 1386.Cm yes .
1387.It Cm PubkeyAcceptedKeyTypes 1387.It Cm PubkeyAcceptedKeyTypes
1388Specifies the key types that will be accepted for public key authentication 1388Specifies the key types that will be accepted for public key authentication
1389as a comma-separated pattern list. 1389as a list of comma-separated patterns.
1390Alternately if the specified value begins with a 1390Alternately if the specified value begins with a
1391.Sq + 1391.Sq +
1392character, then the specified key types will be appended to the default set 1392character, then the specified key types will be appended to the default set