=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sshconnect2.c,v retrieving revision 1.370 retrieving revision 1.371 diff -u -r1.370 -r1.371 --- src/usr.bin/ssh/sshconnect2.c 2023/12/18 14:45:17 1.370 +++ src/usr.bin/ssh/sshconnect2.c 2023/12/18 14:45:49 1.371 @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.370 2023/12/18 14:45:17 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.371 2023/12/18 14:45:49 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -452,10 +452,8 @@ authctxt.mech_tried = 0; #endif authctxt.agent_fd = -1; - pubkey_prepare(ssh, &authctxt); - if (authctxt.method == NULL) { + if (authctxt.method == NULL) fatal_f("internal error: cannot send userauth none request"); - } if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_REQUEST)) != 0 || (r = sshpkt_put_cstring(ssh, "ssh-userauth")) != 0 || @@ -514,7 +512,9 @@ /* initial userauth request */ userauth_none(ssh); - ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_error); + /* accept EXT_INFO at any time during userauth */ + ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, ssh->kex->ext_info_s ? + &kex_input_ext_info : &input_userauth_error); ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); @@ -1671,10 +1671,10 @@ struct identity *id, *id2, *tmp; struct idlist agent, files, *preferred; struct sshkey *key; - int agent_fd = -1, i, r, found; + int disallowed, agent_fd = -1, i, r, found; size_t j; struct ssh_identitylist *idlist; - char *ident; + char *cp, *ident; TAILQ_INIT(&agent); /* keys from the agent */ TAILQ_INIT(&files); /* keys from the config file */ @@ -1792,16 +1792,30 @@ TAILQ_CONCAT(preferred, &files, next); /* finally, filter by PubkeyAcceptedAlgorithms */ TAILQ_FOREACH_SAFE(id, preferred, next, id2) { - if (id->key != NULL && !key_type_allowed_by_config(id->key)) { - debug("Skipping %s key %s - " - "corresponding algo not in PubkeyAcceptedAlgorithms", - sshkey_ssh_name(id->key), id->filename); - TAILQ_REMOVE(preferred, id, next); - sshkey_free(id->key); - free(id->filename); - memset(id, 0, sizeof(*id)); + disallowed = 0; + cp = NULL; + if (id->key == NULL) continue; + if (!key_type_allowed_by_config(id->key)) { + debug("Skipping %s key %s - corresponding algorithm " + "not in PubkeyAcceptedAlgorithms", + sshkey_ssh_name(id->key), id->filename); + disallowed = 1; + } else if (ssh->kex->server_sig_algs != NULL && + (cp = key_sig_algorithm(ssh, id->key)) == NULL) { + debug("Skipping %s key %s - corresponding algorithm " + "not supported by server", + sshkey_ssh_name(id->key), id->filename); + disallowed = 1; } + free(cp); + if (!disallowed) + continue; + /* remove key */ + TAILQ_REMOVE(preferred, id, next); + sshkey_free(id->key); + free(id->filename); + memset(id, 0, sizeof(*id)); } /* List the keys we plan on using */ TAILQ_FOREACH_SAFE(id, preferred, next, id2) { @@ -1847,6 +1861,12 @@ Identity *id; int sent = 0; char *ident; + static int prepared; + + if (!prepared) { + pubkey_prepare(ssh, authctxt); + prepared = 1; + } while ((id = TAILQ_FIRST(&authctxt->keys))) { if (id->tried++)