upstream: add "ext-info-in-auth@openssh.com" extension
This adds another transport protocol extension to allow a sshd to send SSH2_MSG_EXT_INFO during user authentication, after the server has learned the username that is being logged in to. This lets sshd to update the acceptable signature algoritms for public key authentication, and allows these to be varied via sshd_config(5) "Match" directives, which are evaluated after the server learns the username being authenticated. Full details in the PROTOCOL file OpenBSD-Commit-ID: 1de7da7f2b6c32a46043d75fcd49b0cbb7db7779
This commit is contained in:
parent
1edb00c58f
commit
a7ed931cae
21
PROTOCOL
21
PROTOCOL
|
@ -163,6 +163,25 @@ b) After sending or receiving a SSH2_MSG_NEWKEYS message, reset the
|
|||
duration of the connection (i.e. not just the first
|
||||
SSH2_MSG_NEWKEYS).
|
||||
|
||||
1.10 transport: SSH2_MSG_EXT_INFO during user authentication
|
||||
|
||||
This protocol extension allows the SSH2_MSG_EXT_INFO to be sent
|
||||
during user authentication. RFC8308 does allow a second
|
||||
SSH2_MSG_EXT_INFO notification, but it may only be sent at the end
|
||||
of user authentication and this is too late to signal per-user
|
||||
server signature algorithms.
|
||||
|
||||
Support for receiving the SSH2_MSG_EXT_INFO message during user
|
||||
authentication is signalled by the client including a
|
||||
"ext-info-in-auth@openssh.com" key via its initial SSH2_MSG_EXT_INFO
|
||||
set after the SSH2_MSG_NEWKEYS message.
|
||||
|
||||
A server that supports this extension MAY send a second
|
||||
SSH2_MSG_EXT_INFO message any time after the client's first
|
||||
SSH2_MSG_USERAUTH_REQUEST, regardless of whether it succeed or fails.
|
||||
The client SHOULD be prepared to update the server-sig-algs that
|
||||
it received during an earlier SSH2_MSG_EXT_INFO with the later one.
|
||||
|
||||
2. Connection protocol changes
|
||||
|
||||
2.1. connection: Channel write close extension "eow@openssh.com"
|
||||
|
@ -771,4 +790,4 @@ master instance and later clients.
|
|||
OpenSSH extends the usual agent protocol. These changes are documented
|
||||
in the PROTOCOL.agent file.
|
||||
|
||||
$OpenBSD: PROTOCOL,v 1.50 2023/12/18 14:45:17 djm Exp $
|
||||
$OpenBSD: PROTOCOL,v 1.51 2023/12/18 14:45:49 djm Exp $
|
||||
|
|
8
auth2.c
8
auth2.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2.c,v 1.167 2023/08/28 09:48:11 djm Exp $ */
|
||||
/* $OpenBSD: auth2.c,v 1.168 2023/12/18 14:45:49 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -57,6 +57,7 @@
|
|||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "digest.h"
|
||||
#include "kex.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
@ -172,6 +173,8 @@ do_authentication2(struct ssh *ssh)
|
|||
Authctxt *authctxt = ssh->authctxt;
|
||||
|
||||
ssh_dispatch_init(ssh, &dispatch_protocol_error);
|
||||
if (ssh->kex->ext_info_c)
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_input_ext_info);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request);
|
||||
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success);
|
||||
ssh->authctxt = NULL;
|
||||
|
@ -211,6 +214,7 @@ input_service_request(int type, u_int32_t seq, struct ssh *ssh)
|
|||
debug("bad service request %s", service);
|
||||
ssh_packet_disconnect(ssh, "bad service request %s", service);
|
||||
}
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &dispatch_protocol_error);
|
||||
r = 0;
|
||||
out:
|
||||
free(service);
|
||||
|
@ -313,6 +317,8 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
|
|||
if (use_privsep)
|
||||
mm_inform_authserv(service, style);
|
||||
userauth_banner(ssh);
|
||||
if ((r = kex_server_update_ext_info(ssh)) != 0)
|
||||
fatal_fr(r, "kex_server_update_ext_info failed");
|
||||
if (auth2_setup_methods_lists(authctxt) != 0)
|
||||
ssh_packet_disconnect(ssh,
|
||||
"no authentication methods enabled");
|
||||
|
|
233
kex.c
233
kex.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kex.c,v 1.183 2023/12/18 14:45:17 djm Exp $ */
|
||||
/* $OpenBSD: kex.c,v 1.184 2023/12/18 14:45:49 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -353,7 +353,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX],
|
|||
if (kexalgos == NULL)
|
||||
kexalgos = defprop[PROPOSAL_KEX_ALGS];
|
||||
if ((cp = kex_names_cat(kexalgos, ssh->kex->server ?
|
||||
"kex-strict-s-v00@openssh.com" :
|
||||
"ext-info-s,kex-strict-s-v00@openssh.com" :
|
||||
"ext-info-c,kex-strict-c-v00@openssh.com")) == NULL)
|
||||
fatal_f("kex_names_cat");
|
||||
|
||||
|
@ -505,36 +505,138 @@ kex_reset_dispatch(struct ssh *ssh)
|
|||
SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
|
||||
}
|
||||
|
||||
void
|
||||
kex_set_server_sig_algs(struct ssh *ssh, const char *allowed_algs)
|
||||
{
|
||||
char *alg, *oalgs, *algs, *sigalgs;
|
||||
const char *sigalg;
|
||||
|
||||
/*
|
||||
* NB. allowed algorithms may contain certificate algorithms that
|
||||
* map to a specific plain signature type, e.g.
|
||||
* rsa-sha2-512-cert-v01@openssh.com => rsa-sha2-512
|
||||
* We need to be careful here to match these, retain the mapping
|
||||
* and only add each signature algorithm once.
|
||||
*/
|
||||
if ((sigalgs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
|
||||
fatal_f("sshkey_alg_list failed");
|
||||
oalgs = algs = xstrdup(allowed_algs);
|
||||
free(ssh->kex->server_sig_algs);
|
||||
ssh->kex->server_sig_algs = NULL;
|
||||
for ((alg = strsep(&algs, ",")); alg != NULL && *alg != '\0';
|
||||
(alg = strsep(&algs, ","))) {
|
||||
if ((sigalg = sshkey_sigalg_by_name(alg)) == NULL)
|
||||
continue;
|
||||
if (!has_any_alg(sigalg, sigalgs))
|
||||
continue;
|
||||
/* Don't add an algorithm twice. */
|
||||
if (ssh->kex->server_sig_algs != NULL &&
|
||||
has_any_alg(sigalg, ssh->kex->server_sig_algs))
|
||||
continue;
|
||||
xextendf(&ssh->kex->server_sig_algs, ",", "%s", sigalg);
|
||||
}
|
||||
free(oalgs);
|
||||
free(sigalgs);
|
||||
if (ssh->kex->server_sig_algs == NULL)
|
||||
ssh->kex->server_sig_algs = xstrdup("");
|
||||
}
|
||||
|
||||
static int
|
||||
kex_send_ext_info(struct ssh *ssh)
|
||||
kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m)
|
||||
{
|
||||
int r;
|
||||
char *algs;
|
||||
|
||||
debug("Sending SSH2_MSG_EXT_INFO");
|
||||
if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
|
||||
if (ssh->kex->server_sig_algs == NULL &&
|
||||
(ssh->kex->server_sig_algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
/* XXX filter algs list by allowed pubkey/hostbased types */
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, 3)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, algs)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh,
|
||||
if ((r = sshbuf_put_u32(m, 3)) != 0 ||
|
||||
(r = sshbuf_put_cstring(m, "server-sig-algs")) != 0 ||
|
||||
(r = sshbuf_put_cstring(m, ssh->kex->server_sig_algs)) != 0 ||
|
||||
(r = sshbuf_put_cstring(m,
|
||||
"publickey-hostbound@openssh.com")) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "0")) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "ping@openssh.com")) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "0")) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0) {
|
||||
(r = sshbuf_put_cstring(m, "0")) != 0 ||
|
||||
(r = sshbuf_put_cstring(m, "ping@openssh.com")) != 0 ||
|
||||
(r = sshbuf_put_cstring(m, "0")) != 0) {
|
||||
error_fr(r, "compose");
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
kex_compose_ext_info_client(struct ssh *ssh, struct sshbuf *m)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = sshbuf_put_u32(m, 1)) != 0 ||
|
||||
(r = sshbuf_put_cstring(m, "ext-info-in-auth@openssh.com")) != 0 ||
|
||||
(r = sshbuf_put_cstring(m, "0")) != 0) {
|
||||
error_fr(r, "compose");
|
||||
goto out;
|
||||
}
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
free(algs);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
kex_maybe_send_ext_info(struct ssh *ssh)
|
||||
{
|
||||
int r;
|
||||
struct sshbuf *m = NULL;
|
||||
|
||||
if ((ssh->kex->flags & KEX_INITIAL) == 0)
|
||||
return 0;
|
||||
if (!ssh->kex->ext_info_c && !ssh->kex->ext_info_s)
|
||||
return 0;
|
||||
|
||||
/* Compose EXT_INFO packet. */
|
||||
if ((m = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new failed");
|
||||
if (ssh->kex->ext_info_c &&
|
||||
(r = kex_compose_ext_info_server(ssh, m)) != 0)
|
||||
goto fail;
|
||||
if (ssh->kex->ext_info_s &&
|
||||
(r = kex_compose_ext_info_client(ssh, m)) != 0)
|
||||
goto fail;
|
||||
|
||||
/* Send the actual KEX_INFO packet */
|
||||
debug("Sending SSH2_MSG_EXT_INFO");
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
|
||||
(r = sshpkt_putb(ssh, m)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0) {
|
||||
error_f("send EXT_INFO");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
fail:
|
||||
sshbuf_free(m);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
kex_server_update_ext_info(struct ssh *ssh)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((ssh->kex->flags & KEX_HAS_EXT_INFO_IN_AUTH) == 0)
|
||||
return 0;
|
||||
|
||||
debug_f("Sending SSH2_MSG_EXT_INFO");
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, 1)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, ssh->kex->server_sig_algs)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0) {
|
||||
error_f("send EXT_INFO");
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kex_send_newkeys(struct ssh *ssh)
|
||||
{
|
||||
|
@ -546,9 +648,8 @@ kex_send_newkeys(struct ssh *ssh)
|
|||
return r;
|
||||
debug("SSH2_MSG_NEWKEYS sent");
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
|
||||
if (ssh->kex->ext_info_c && (ssh->kex->flags & KEX_INITIAL) != 0)
|
||||
if ((r = kex_send_ext_info(ssh)) != 0)
|
||||
return r;
|
||||
if ((r = kex_maybe_send_ext_info(ssh)) != 0)
|
||||
return r;
|
||||
debug("expecting SSH2_MSG_NEWKEYS");
|
||||
return 0;
|
||||
}
|
||||
|
@ -570,10 +671,61 @@ kex_ext_info_check_ver(struct kex *kex, const char *name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
kex_ext_info_client_parse(struct ssh *ssh, const char *name,
|
||||
const u_char *value, size_t vlen)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* NB. some messages are only accepted in the initial EXT_INFO */
|
||||
if (strcmp(name, "server-sig-algs") == 0) {
|
||||
/* Ensure no \0 lurking in value */
|
||||
if (memchr(value, '\0', vlen) != NULL) {
|
||||
error_f("nul byte in %s", name);
|
||||
return SSH_ERR_INVALID_FORMAT;
|
||||
}
|
||||
debug_f("%s=<%s>", name, value);
|
||||
free(ssh->kex->server_sig_algs);
|
||||
ssh->kex->server_sig_algs = xstrdup((const char *)value);
|
||||
} else if (ssh->kex->ext_info_received == 1 &&
|
||||
strcmp(name, "publickey-hostbound@openssh.com") == 0) {
|
||||
if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen,
|
||||
"0", KEX_HAS_PUBKEY_HOSTBOUND)) != 0) {
|
||||
return r;
|
||||
}
|
||||
} else if (ssh->kex->ext_info_received == 1 &&
|
||||
strcmp(name, "ping@openssh.com") == 0) {
|
||||
if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen,
|
||||
"0", KEX_HAS_PING)) != 0) {
|
||||
return r;
|
||||
}
|
||||
} else
|
||||
debug_f("%s (unrecognised)", name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
kex_ext_info_server_parse(struct ssh *ssh, const char *name,
|
||||
const u_char *value, size_t vlen)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (strcmp(name, "ext-info-in-auth@openssh.com") == 0) {
|
||||
if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen,
|
||||
"0", KEX_HAS_EXT_INFO_IN_AUTH)) != 0) {
|
||||
return r;
|
||||
}
|
||||
} else
|
||||
debug_f("%s (unrecognised)", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
|
||||
{
|
||||
struct kex *kex = ssh->kex;
|
||||
const int max_ext_info = kex->server ? 1 : 2;
|
||||
u_int32_t i, ninfo;
|
||||
char *name;
|
||||
u_char *val;
|
||||
|
@ -581,6 +733,10 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
|
|||
int r;
|
||||
|
||||
debug("SSH2_MSG_EXT_INFO received");
|
||||
if (++kex->ext_info_received > max_ext_info) {
|
||||
error("too many SSH2_MSG_EXT_INFO messages sent by peer");
|
||||
return dispatch_protocol_error(type, seq, ssh);
|
||||
}
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
|
||||
if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
|
||||
return r;
|
||||
|
@ -596,34 +752,16 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
|
|||
free(name);
|
||||
return r;
|
||||
}
|
||||
if (strcmp(name, "server-sig-algs") == 0) {
|
||||
/* Ensure no \0 lurking in value */
|
||||
if (memchr(val, '\0', vlen) != NULL) {
|
||||
error_f("nul byte in %s", name);
|
||||
free(name);
|
||||
free(val);
|
||||
return SSH_ERR_INVALID_FORMAT;
|
||||
}
|
||||
debug_f("%s=<%s>", name, val);
|
||||
kex->server_sig_algs = val;
|
||||
val = NULL;
|
||||
} else if (strcmp(name,
|
||||
"publickey-hostbound@openssh.com") == 0) {
|
||||
if ((r = kex_ext_info_check_ver(kex, name, val, vlen,
|
||||
"0", KEX_HAS_PUBKEY_HOSTBOUND)) != 0) {
|
||||
free(name);
|
||||
free(val);
|
||||
debug3_f("extension %s", name);
|
||||
if (kex->server) {
|
||||
if ((r = kex_ext_info_server_parse(ssh, name,
|
||||
val, vlen)) != 0)
|
||||
return r;
|
||||
}
|
||||
} else if (strcmp(name, "ping@openssh.com") == 0) {
|
||||
if ((r = kex_ext_info_check_ver(kex, name, val, vlen,
|
||||
"0", KEX_HAS_PING)) != 0) {
|
||||
free(name);
|
||||
free(val);
|
||||
} else {
|
||||
if ((r = kex_ext_info_client_parse(ssh, name,
|
||||
val, vlen)) != 0)
|
||||
return r;
|
||||
}
|
||||
} else
|
||||
debug_f("%s (unrecognised)", name);
|
||||
}
|
||||
free(name);
|
||||
free(val);
|
||||
}
|
||||
|
@ -637,6 +775,8 @@ kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh)
|
|||
int r;
|
||||
|
||||
debug("SSH2_MSG_NEWKEYS received");
|
||||
if (kex->ext_info_c && (kex->flags & KEX_INITIAL) != 0)
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_input_ext_info);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
|
||||
if ((r = sshpkt_get_end(ssh)) != 0)
|
||||
|
@ -1044,6 +1184,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq)
|
|||
kex->kex_strict = kexalgs_contains(peer,
|
||||
"kex-strict-c-v00@openssh.com");
|
||||
} else {
|
||||
kex->ext_info_s = kexalgs_contains(peer, "ext-info-s");
|
||||
kex->kex_strict = kexalgs_contains(peer,
|
||||
"kex-strict-s-v00@openssh.com");
|
||||
}
|
||||
|
|
7
kex.h
7
kex.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kex.h,v 1.120 2023/12/18 14:45:17 djm Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.121 2023/12/18 14:45:49 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -112,6 +112,7 @@ enum kex_exchange {
|
|||
#define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */
|
||||
#define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */
|
||||
#define KEX_HAS_PING 0x0020
|
||||
#define KEX_HAS_EXT_INFO_IN_AUTH 0x0040
|
||||
|
||||
struct sshenc {
|
||||
char *name;
|
||||
|
@ -149,7 +150,9 @@ struct kex {
|
|||
u_int kex_type;
|
||||
char *server_sig_algs;
|
||||
int ext_info_c;
|
||||
int ext_info_s;
|
||||
int kex_strict;
|
||||
int ext_info_received;
|
||||
struct sshbuf *my;
|
||||
struct sshbuf *peer;
|
||||
struct sshbuf *client_version;
|
||||
|
@ -209,6 +212,8 @@ int kex_protocol_error(int, u_int32_t, struct ssh *);
|
|||
int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *);
|
||||
int kex_send_newkeys(struct ssh *);
|
||||
int kex_start_rekex(struct ssh *);
|
||||
int kex_server_update_ext_info(struct ssh *);
|
||||
void kex_set_server_sig_algs(struct ssh *, const char *);
|
||||
|
||||
int kexgex_client(struct ssh *);
|
||||
int kexgex_server(struct ssh *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor_wrap.c,v 1.128 2023/03/31 00:44:29 dtucker Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.129 2023/12/18 14:45:49 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
|
@ -340,8 +340,8 @@ out:
|
|||
log_verbose_add(options.log_verbose[i]);
|
||||
process_permitopen(ssh, &options);
|
||||
process_channel_timeouts(ssh, &options);
|
||||
kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos);
|
||||
free(newopts);
|
||||
|
||||
sshbuf_free(m);
|
||||
|
||||
return (pw);
|
||||
|
|
|
@ -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++)
|
||||
|
|
4
sshd.c
4
sshd.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshd.c,v 1.600 2023/03/08 04:43:12 guenther Exp $ */
|
||||
/* $OpenBSD: sshd.c,v 1.601 2023/12/18 14:45:49 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -2405,7 +2405,9 @@ do_ssh2_kex(struct ssh *ssh)
|
|||
/* start key exchange */
|
||||
if ((r = kex_setup(ssh, myproposal)) != 0)
|
||||
fatal_r(r, "kex_setup");
|
||||
kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos);
|
||||
kex = ssh->kex;
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server;
|
||||
kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server;
|
||||
|
|
Loading…
Reference in New Issue