mirror of
https://github.com/openssh/openssh-portable.git
synced 2026-11-06 05:16:43 +00:00
upstream: Add WarnWeakCrypto to sshd
This option was previously available for the client only. This adds it to sshd, so allow logging of non-PQ key exchanges. ok markus, deraadt OpenBSD-Commit-ID: 524564b82a7a20a4ff984c948fb75aa2b0f9b707
This commit is contained in:
1 parent
cee6aedb1a
commit
813f670ccc
9 files changed
+95
-13
No files matched your search
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.c,v 1.194 2026/05/31 04:44:38 djm Exp $ */
|
||||
/* $OpenBSD: kex.c,v 1.195 2026/09/16 00:29:44 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@@ -289,6 +289,40 @@ kex_set_server_sig_algs(struct ssh *ssh, const char *allowed_algs)
|
||||
ssh->kex->server_sig_algs = xstrdup("");
|
||||
}
|
||||
|
||||
void
|
||||
kex_set_warn_weak_crypto(struct ssh *ssh, int warn_weak_crypto)
|
||||
{
|
||||
if (ssh != NULL && ssh->kex != NULL)
|
||||
ssh->kex->warn_weak_crypto = warn_weak_crypto != 0;
|
||||
}
|
||||
|
||||
void
|
||||
kex_check_warn_weak_crypto(struct ssh *ssh)
|
||||
{
|
||||
char remote_id[512];
|
||||
int rekeyed = 0;
|
||||
|
||||
if (ssh == NULL || ssh->kex == NULL || ssh->kex->name == NULL ||
|
||||
!ssh->kex->warn_weak_crypto || ssh->kex->non_pq_kex_warned)
|
||||
return;
|
||||
if (kex_is_pq_from_name(ssh->kex->name)) {
|
||||
ssh->kex->pq_kex_negotiated = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ssh->kex->pq_kex_negotiated)
|
||||
rekeyed = 1;
|
||||
if (!rekeyed && !ssh->kex->server)
|
||||
return; /* client logs initial KEX warning separately */
|
||||
|
||||
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
|
||||
logit("WARNING: %sconnection%s%s is not using a post-quantum "
|
||||
"key exchange algorithm: \"%s\"", rekeyed ? "rekeyed " : "",
|
||||
ssh->kex->server ? " from " : "",
|
||||
ssh->kex->server ? remote_id : "", ssh->kex->name);
|
||||
ssh->kex->non_pq_kex_warned = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m)
|
||||
{
|
||||
@@ -567,6 +601,7 @@ kex_input_newkeys(int type, uint32_t seq, struct ssh *ssh)
|
||||
kex->flags &= ~KEX_INITIAL;
|
||||
sshbuf_reset(kex->peer);
|
||||
kex->flags &= ~(KEX_INIT_SENT|KEX_INIT_RECVD);
|
||||
kex_check_warn_weak_crypto(ssh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.h,v 1.134 2026/08/08 07:27:54 djm Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.135 2026/09/16 00:29:44 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@@ -164,6 +164,9 @@ struct kex {
|
||||
struct sshkey *initial_hostkey;
|
||||
sig_atomic_t done;
|
||||
u_int flags;
|
||||
u_int warn_weak_crypto;
|
||||
u_int pq_kex_negotiated;
|
||||
u_int non_pq_kex_warned;
|
||||
int hash_alg;
|
||||
int ec_nid;
|
||||
char *failed_choice;
|
||||
@@ -223,6 +226,8 @@ 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 *);
|
||||
void kex_set_warn_weak_crypto(struct ssh *, int);
|
||||
void kex_check_warn_weak_crypto(struct ssh *);
|
||||
|
||||
int kexgex_client(struct ssh *);
|
||||
int kexgex_server(struct ssh *);
|
||||
|
||||
+2
-1
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.149 2026/09/16 00:13:58 djm Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.150 2026/09/16 00:29:44 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@@ -386,6 +386,7 @@ out:
|
||||
channel_set_tcp_keepalives(ssh,
|
||||
options.tcp_keep_alive == SSH_KEEPALIVES_ALL);
|
||||
kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos);
|
||||
kex_set_warn_weak_crypto(ssh, options.warn_weak_crypto);
|
||||
ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
|
||||
options.rekey_interval);
|
||||
sshbuf_free(m);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.c,v 1.342 2026/09/14 02:40:27 djm Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.343 2026/09/16 00:29:44 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -2432,7 +2432,10 @@ kex_to_blob(struct sshbuf *m, struct kex *kex)
|
||||
(r = sshbuf_put_stringb(m, kex->client_version)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->server_version)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->session_id)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->flags)) != 0)
|
||||
(r = sshbuf_put_u32(m, kex->flags)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->warn_weak_crypto)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->pq_kex_negotiated)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->non_pq_kex_warned)) != 0)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
@@ -2606,7 +2609,10 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
|
||||
(r = sshbuf_get_stringb(m, kex->client_version)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->server_version)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->session_id)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &kex->flags)) != 0)
|
||||
(r = sshbuf_get_u32(m, &kex->flags)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &kex->warn_weak_crypto)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &kex->pq_kex_negotiated)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &kex->non_pq_kex_warned)) != 0)
|
||||
goto out;
|
||||
if (kex->we_need > 1024) {
|
||||
r = SSH_ERR_INVALID_FORMAT;
|
||||
|
||||
+16
-1
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.c,v 1.455 2026/09/16 00:25:50 djm Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.456 2026/09/16 00:29:44 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@@ -1107,6 +1107,13 @@ static const struct multistate multistate_keepalives[] = {
|
||||
{ "no", SSH_KEEPALIVES_OFF },
|
||||
{ "transport", SSH_KEEPALIVES_TRANSPORT },
|
||||
{ "all", SSH_KEEPALIVES_ALL },
|
||||
};
|
||||
static const struct multistate multistate_warnweakcrypto[] = {
|
||||
{ "true", 1 },
|
||||
{ "false", 0 },
|
||||
{ "yes", 1 },
|
||||
{ "no", 0 },
|
||||
{ "no-pq-kex", 0 },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
|
||||
@@ -2606,6 +2613,11 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
multistate_ptr = multistate_flag;
|
||||
goto parse_multistate;
|
||||
|
||||
case sWarnWeakCrypto:
|
||||
intptr = &options->warn_weak_crypto;
|
||||
multistate_ptr = multistate_warnweakcrypto;
|
||||
goto parse_multistate;
|
||||
|
||||
case sDeprecated:
|
||||
case sIgnore:
|
||||
case sUnsupported:
|
||||
@@ -4140,6 +4152,8 @@ fmt_intarg(ServerOpCodes code, int val)
|
||||
return fmt_multistate_int(val, multistate_ignore_rhosts);
|
||||
case sTCPKeepAlive:
|
||||
return fmt_multistate_int(val, multistate_keepalives);
|
||||
case sWarnWeakCrypto:
|
||||
return fmt_multistate_int(val, multistate_warnweakcrypto);
|
||||
case sFingerprintHash:
|
||||
return ssh_digest_alg_name(val);
|
||||
default:
|
||||
@@ -4334,6 +4348,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
|
||||
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
|
||||
dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
|
||||
dump_cfg_fmtint(sWarnWeakCrypto, o->warn_weak_crypto);
|
||||
dump_cfg_fmtint(sRefuseConnection, o->refuse_connection);
|
||||
|
||||
/* string arguments */
|
||||
|
||||
+3
-2
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.h,v 1.182 2026/09/16 00:25:50 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.183 2026/09/16 00:29:44 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@@ -241,7 +241,8 @@ SSHCONF_INT(unused_connection_timeout, UnusedConnectionTimeout, SSHCFG_ALL, NULL
|
||||
SSHCONF_STRING(sshd_session_path, SshdSessionPath, SSHCFG_GLOBAL, SSHCFG_COPY_NONE) \
|
||||
SSHCONF_STRING(sshd_auth_path, SshdAuthPath, SSHCFG_GLOBAL, SSHCFG_COPY_NONE) \
|
||||
SSHCONF_INTFLAG(refuse_connection, RefuseConnection, SSHCFG_ALL, 0, SSHCFG_COPY_MATCH) \
|
||||
SSHCONF_STRING(agent_socket_path, AgentSocketPath, SSHCFG_ALL, SSHCFG_COPY_MATCH)
|
||||
SSHCONF_STRING(agent_socket_path, AgentSocketPath, SSHCFG_ALL, SSHCFG_COPY_MATCH) \
|
||||
SSHCONF_INT(warn_weak_crypto, WarnWeakCrypto, SSHCFG_GLOBAL, multistate_warnweakcrypto, 1, SSHCFG_COPY_NONE)
|
||||
|
||||
#define SSHD_CONFIG_ENTRIES_LEGACY \
|
||||
SSHCONF_DEPRECATE(ServerKeyBits, SSHCFG_GLOBAL, SSHCONF_DEPRECATED) \
|
||||
|
||||
+6
-2
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sshconnect.c,v 1.385 2026/09/16 00:13:58 djm Exp $ */
|
||||
/* $OpenBSD: sshconnect.c,v 1.386 2026/09/16 00:29:44 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -1657,10 +1657,14 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
|
||||
/* authenticate user */
|
||||
debug("Authenticating to %s:%d as '%s'", host, port, server_user);
|
||||
ssh_kex2(ssh, host, hostaddr, port, cinfo);
|
||||
kex_set_warn_weak_crypto(ssh, options.warn_weak_crypto &&
|
||||
!options.kex_algorithms_set);
|
||||
if (!options.kex_algorithms_set && ssh->kex != NULL &&
|
||||
ssh->kex->name != NULL && options.warn_weak_crypto &&
|
||||
!kex_is_pq_from_name(ssh->kex->name))
|
||||
!kex_is_pq_from_name(ssh->kex->name)) {
|
||||
warn_nonpq_kex();
|
||||
ssh->kex->non_pq_kex_warned = 1;
|
||||
}
|
||||
ssh_userauth2(ssh, local_user, server_user, host, sensitive);
|
||||
free(local_user);
|
||||
free(host);
|
||||
|
||||
+2
-1
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sshd-auth.c,v 1.19 2026/09/16 00:13:58 djm Exp $ */
|
||||
/* $OpenBSD: sshd-auth.c,v 1.20 2026/09/16 00:29:44 djm Exp $ */
|
||||
/*
|
||||
* SSH2 implementation:
|
||||
* Privilege Separation:
|
||||
@@ -798,6 +798,7 @@ do_ssh2_kex(struct ssh *ssh)
|
||||
if ((r = kex_setup(ssh, myproposal)) != 0)
|
||||
fatal_r(r, "kex_setup");
|
||||
kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos);
|
||||
kex_set_warn_weak_crypto(ssh, options.warn_weak_crypto);
|
||||
kex = ssh->kex;
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
+15
-1
@@ -33,7 +33,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.406 2026/09/16 00:25:50 djm Exp $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.407 2026/09/16 00:29:44 djm Exp $
|
||||
.Dd $Mdocdate: September 16 2026 $
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
@@ -2147,6 +2147,20 @@ Optionally specifies additional text to append to the SSH protocol banner
|
||||
sent by the server upon connection.
|
||||
The default is
|
||||
.Cm none .
|
||||
.It Cm WarnWeakCrypto
|
||||
Controls whether warnings are logged when the cryptographic algorithms
|
||||
negotiated for the connection are weak or otherwise recommended against.
|
||||
Warnings may be disabled by turning off a specific warning or by disabling
|
||||
all warnings.
|
||||
Warnings about connections that don't use a post-quantum key exchange
|
||||
may be disabled using the
|
||||
.Cm no-pq-kex
|
||||
flag.
|
||||
.Cm no
|
||||
will disable all warnings.
|
||||
The default, equivalent to
|
||||
.Cm yes ,
|
||||
is to enable all warnings.
|
||||
.It Cm X11DisplayOffset
|
||||
Specifies the first display number available for
|
||||
.Xr sshd 8 Ns 's
|
||||
|
||||
Reference in new issue
Block a user