summaryrefslogtreecommitdiffstats
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 0cccbcc4..fab1e36b 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -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.
@@ -459,10 +459,8 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
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 ||
@@ -521,7 +519,9 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
/* 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);
@@ -1678,10 +1678,10 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt)
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 */
@@ -1799,16 +1799,30 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt)
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) {
@@ -1854,6 +1868,12 @@ userauth_pubkey(struct ssh *ssh)
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++)