diff --git a/backport-CVE-2021-36368-added-option-to-disable-trivial-auth.patch b/backport-CVE-2021-36368-added-option-to-disable-trivial-auth.patch deleted file mode 100644 index 48e61f01c0a4840e3f8513bdd1db90bf759ed906..0000000000000000000000000000000000000000 --- a/backport-CVE-2021-36368-added-option-to-disable-trivial-auth.patch +++ /dev/null @@ -1,220 +0,0 @@ -Conflict:NA -Reference:https://github.com/openssh/openssh-portable/pull/258/files - ---- - readconf.c | 11 ++++++++++- - readconf.h | 2 ++ - scp.1 | 1 + - sftp.1 | 1 + - ssh.1 | 1 + - ssh_config | 1 + - ssh_config.5 | 7 +++++++ - sshconnect2.c | 13 ++++++++++++- - 8 files changed, 35 insertions(+), 2 deletions(-) - -diff --git a/readconf.c b/readconf.c -index d25f983..45c1c22 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -157,7 +157,7 @@ typedef enum { - oLogFacility, oLogLevel, oLogVerbose, oCiphers, oMacs, - oPubkeyAuthentication, - oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, -- oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, -+ oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, oDisableTrivialAuth, - oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider, - oClearAllForwardings, oNoHostAuthenticationForLocalhost, - oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, -@@ -250,6 +250,7 @@ static struct { - { "pubkeyauthentication", oPubkeyAuthentication }, - { "dsaauthentication", oPubkeyAuthentication }, /* alias */ - { "hostbasedauthentication", oHostbasedAuthentication }, -+ { "disabletrivialauth", oDisableTrivialAuth}, - { "identityfile", oIdentityFile }, - { "identityfile2", oIdentityFile }, /* obsolete */ - { "identitiesonly", oIdentitiesOnly }, -@@ -1124,6 +1125,10 @@ parse_time: - intptr = &options->hostbased_authentication; - goto parse_flag; - -+ case oDisableTrivialAuth: -+ intptr = &options->disable_trivial_auth; -+ goto parse_flag; -+ - case oGssAuthentication: - intptr = &options->gss_authentication; - goto parse_flag; -@@ -2392,6 +2397,7 @@ initialize_options(Options * options) - options->kbd_interactive_authentication = -1; - options->kbd_interactive_devices = NULL; - options->hostbased_authentication = -1; -+ options->disable_trivial_auth = -1; - options->batch_mode = -1; - options->check_host_ip = -1; - options->strict_host_key_checking = -1; -@@ -2562,6 +2568,8 @@ fill_default_options(Options * options) - options->kbd_interactive_authentication = 1; - if (options->hostbased_authentication == -1) - options->hostbased_authentication = 0; -+ if (options->disable_trivial_auth == -1) -+ options->disable_trivial_auth = 0; - if (options->batch_mode == -1) - options->batch_mode = 0; - if (options->check_host_ip == -1) -@@ -3362,6 +3370,7 @@ dump_client_config(Options *o, const char *host) - #endif /* GSSAPI */ - dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); - dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -+ dump_cfg_fmtint(oDisableTrivialAuth, o->disable_trivial_auth); - dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); - dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); - dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); -diff --git a/readconf.h b/readconf.h -index 00895ad..b391bd6 100644 ---- a/readconf.h -+++ b/readconf.h -@@ -38,6 +38,8 @@ typedef struct { - struct ForwardOptions fwd_opts; /* forwarding options */ - int pubkey_authentication; /* Try ssh2 pubkey authentication. */ - int hostbased_authentication; /* ssh2's rhosts_rsa */ -+ -+ int disable_trivial_auth; /* disable trivial authentications */ - int gss_authentication; /* Try GSS authentication */ - int gss_keyex; /* Try GSS key exchange */ - int gss_deleg_creds; /* Delegate GSS credentials */ -diff --git a/scp.1 b/scp.1 -index 874c5c2..e1f8191 100644 ---- a/scp.1 -+++ b/scp.1 -@@ -187,6 +187,7 @@ For full details of the options listed below, and their possible values, see - .It Host - .It HostbasedAcceptedAlgorithms - .It HostbasedAuthentication -+.It DisableTrivialAuth - .It HostKeyAlgorithms - .It HostKeyAlias - .It Hostname -diff --git a/sftp.1 b/sftp.1 -index 7eebeea..89b6773 100644 ---- a/sftp.1 -+++ b/sftp.1 -@@ -247,6 +247,7 @@ For full details of the options listed below, and their possible values, see - .It Host - .It HostbasedAcceptedAlgorithms - .It HostbasedAuthentication -+.It DisableTrivialAuth - .It HostKeyAlgorithms - .It HostKeyAlias - .It Hostname -diff --git a/ssh.1 b/ssh.1 -index 975ab39..1cb8d5c 100644 ---- a/ssh.1 -+++ b/ssh.1 -@@ -541,6 +541,7 @@ For full details of the options listed below, and their possible values, see - .It Host - .It HostbasedAcceptedAlgorithms - .It HostbasedAuthentication -+.It DisableTrivialAuth - .It HostKeyAlgorithms - .It HostKeyAlias - .It Hostname -diff --git a/ssh_config b/ssh_config -index b3a4922..169f30c 100644 ---- a/ssh_config -+++ b/ssh_config -@@ -22,6 +22,7 @@ - # ForwardX11 no - # PasswordAuthentication yes - # HostbasedAuthentication no -+# DisableTrivialAuth no - # GSSAPIAuthentication no - # GSSAPIDelegateCredentials no - # GSSAPIKeyExchange no -diff --git a/ssh_config.5 b/ssh_config.5 -index 6735401..fd82e05 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -955,6 +955,13 @@ The argument must be - or - .Cm no - (the default). -+.It Cm DisableTrivialAuth -+Disables trivial or incomplete authentications. -+The argument must be -+.Cm yes -+or -+.Cm no -+(the default). - .It Cm HostKeyAlgorithms - Specifies the host key signature algorithms - that the client wants to use in order of preference. -diff --git a/sshconnect2.c b/sshconnect2.c -index e90eb89..150d419 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -403,6 +403,7 @@ struct identity { - TAILQ_HEAD(idlist, identity); - - struct cauthctxt { -+ int is_trivial_auth; - const char *server_user; - const char *local_user; - const char *host; -@@ -531,6 +532,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user, - /* setup authentication context */ - memset(&authctxt, 0, sizeof(authctxt)); - authctxt.server_user = server_user; -+ authctxt.is_trivial_auth = 1; - authctxt.local_user = local_user; - authctxt.host = host; - authctxt.service = "ssh-connection"; /* service name */ -@@ -570,6 +572,10 @@ ssh_userauth2(struct ssh *ssh, const char *local_user, - - if (!authctxt.success) - fatal("Authentication failed."); -+ if (authctxt.is_trivial_auth == 1 && options.disable_trivial_auth == 1) { -+ fatal("Trivial authentication disabled."); -+ } -+ debug("Authentication succeeded (%s).", authctxt.method->name); - if (ssh_packet_connection_is_on_socket(ssh)) { - verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, - ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -@@ -968,6 +974,7 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) - fatal_fr(r, "send %u packet", type); - - gss_release_buffer(&ms, &send_tok); -+ authctxt->is_trivial_auth = 0; - } - - if (status == GSS_S_COMPLETE) { -@@ -1213,6 +1220,7 @@ static int - userauth_passwd(struct ssh *ssh) - { - Authctxt *authctxt = (Authctxt *)ssh->authctxt; -+ authctxt->is_trivial_auth = 0; - char *password, *prompt = NULL; - const char *host = options.host_key_alias ? options.host_key_alias : - authctxt->host; -@@ -2023,8 +2031,10 @@ userauth_pubkey(struct ssh *ssh) - id->isprivate = 0; - } - } -- if (sent) -+ if (sent) { -+ authctxt->is_trivial_auth = 0; - return (sent); -+ } - } - return (0); - } -@@ -2105,6 +2115,7 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) - - debug2_f("num_prompts %d", num_prompts); - for (i = 0; i < num_prompts; i++) { -+ authctxt->is_trivial_auth = 0; - if ((r = sshpkt_get_cstring(ssh, &prompt, NULL)) != 0 || - (r = sshpkt_get_u8(ssh, &echo)) != 0) - goto out; --- -2.27.0 - diff --git a/backport-CVE-2023-48795-upstream-implement-strict-key-exchange-in-ssh-and-ss.patch b/backport-CVE-2023-48795-upstream-implement-strict-key-exchange-in-ssh-and-ss.patch deleted file mode 100644 index 7f54a46e2c032d887eef416b2c18adb055bc6023..0000000000000000000000000000000000000000 --- a/backport-CVE-2023-48795-upstream-implement-strict-key-exchange-in-ssh-and-ss.patch +++ /dev/null @@ -1,499 +0,0 @@ -From 1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 18 Dec 2023 14:45:17 +0000 -Subject: [PATCH] upstream: implement "strict key exchange" in ssh and sshd - -This adds a protocol extension to improve the integrity of the SSH -transport protocol, particular in and around the initial key exchange -(KEX) phase. - -Full details of the extension are in the PROTOCOL file. - -with markus@ - -OpenBSD-Commit-ID: 2a66ac962f0a630d7945fee54004ed9e9c439f14 - -Reference:https://github.com/openssh/openssh-portable/commit/1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 ---- - PROTOCOL | 28 +++++++++++++- - kex.c | 84 ++++++++++++++++++++++++++-------------- - kex.h | 3 +- - packet.c | 103 +++++++++++++++++++++++++++++--------------------- - packet.h | 3 +- - sshconnect2.c | 12 ++---- - 6 files changed, 148 insertions(+), 85 deletions(-) - -diff --git a/PROTOCOL b/PROTOCOL -index d453c779b..ded935eb6 100644 ---- a/PROTOCOL -+++ b/PROTOCOL -@@ -137,6 +137,32 @@ than as a named global or channel request to allow pings with very - - This is identical to curve25519-sha256 as later published in RFC8731. - -+1.9 transport: strict key exchange extension -+ -+OpenSSH supports a number of transport-layer hardening measures under -+a "strict KEX" feature. This feature is signalled similarly to the -+RFC8308 ext-info feature: by including a additional algorithm in the -+initiial SSH2_MSG_KEXINIT kex_algorithms field. The client may append -+"kex-strict-c-v00@openssh.com" to its kex_algorithms and the server -+may append "kex-strict-s-v00@openssh.com". These pseudo-algorithms -+are only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored -+if they are present in subsequent SSH2_MSG_KEXINIT packets. -+ -+When an endpoint that supports this extension observes this algorithm -+name in a peer's KEXINIT packet, it MUST make the following changes to -+the the protocol: -+ -+a) During initial KEX, terminate the connection if any unexpected or -+ out-of-sequence packet is received. This includes terminating the -+ connection if the first packet received is not SSH2_MSG_KEXINIT. -+ Unexpected packets for the purpose of strict KEX include messages -+ that are otherwise valid at any time during the connection such as -+ SSH2_MSG_DEBUG and SSH2_MSG_IGNORE. -+b) After sending or receiving a SSH2_MSG_NEWKEYS message, reset the -+ packet sequence number to zero. This behaviour persists for the -+ duration of the connection (i.e. not just the first -+ SSH2_MSG_NEWKEYS). -+ - 2. Connection protocol changes - - 2.1. connection: Channel write close extension "eow@openssh.com" -@@ -745,4 +771,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.48 2022/11/07 01:53:01 dtucker Exp $ -+$OpenBSD: PROTOCOL,v 1.50 2023/12/18 14:45:17 djm Exp $ -diff --git a/kex.c b/kex.c -index aa5e792dd..d478ff6e7 100644 ---- a/kex.c -+++ b/kex.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: kex.c,v 1.178 2023/03/12 10:40:39 dtucker Exp $ */ -+/* $OpenBSD: kex.c,v 1.183 2023/12/18 14:45:17 djm Exp $ */ - /* - * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - * -@@ -65,7 +65,7 @@ - #endif - - /* prototype */ --static int kex_choose_conf(struct ssh *); -+static int kex_choose_conf(struct ssh *, uint32_t seq); - static int kex_input_newkeys(int, u_int32_t, struct ssh *); - - static const char * const proposal_names[PROPOSAL_MAX] = { -@@ -177,6 +177,18 @@ kex_names_valid(const char *names) - return 1; - } - -+/* returns non-zero if proposal contains any algorithm from algs */ -+static int -+has_any_alg(const char *proposal, const char *algs) -+{ -+ char *cp; -+ -+ if ((cp = match_list(proposal, algs, NULL)) == NULL) -+ return 0; -+ free(cp); -+ return 1; -+} -+ - /* - * Concatenate algorithm names, avoiding duplicates in the process. - * Caller must free returned string. -@@ -184,7 +196,7 @@ kex_names_valid(const char *names) - char * - kex_names_cat(const char *a, const char *b) - { -- char *ret = NULL, *tmp = NULL, *cp, *p, *m; -+ char *ret = NULL, *tmp = NULL, *cp, *p; - size_t len; - - if (a == NULL || *a == '\0') -@@ -201,10 +213,8 @@ kex_names_cat(const char *a, const char *b) - } - strlcpy(ret, a, len); - for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { -- if ((m = match_list(ret, p, NULL)) != NULL) { -- free(m); -+ if (has_any_alg(ret, p)) - continue; /* Algorithm already present */ -- } - if (strlcat(ret, ",", len) >= len || - strlcat(ret, p, len) >= len) { - free(tmp); -@@ -334,15 +344,23 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], - const char *defpropclient[PROPOSAL_MAX] = { KEX_CLIENT }; - const char **defprop = ssh->kex->server ? defpropserver : defpropclient; - u_int i; -+ char *cp; - - if (prop == NULL) - fatal_f("proposal missing"); - -+ /* Append EXT_INFO signalling to KexAlgorithms */ -+ 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-c,kex-strict-c-v00@openssh.com")) == NULL) -+ fatal_f("kex_names_cat"); -+ - for (i = 0; i < PROPOSAL_MAX; i++) { - switch(i) { - case PROPOSAL_KEX_ALGS: -- prop[i] = compat_kex_proposal(ssh, -- kexalgos ? kexalgos : defprop[i]); -+ prop[i] = compat_kex_proposal(ssh, cp); - break; - case PROPOSAL_ENC_ALGS_CTOS: - case PROPOSAL_ENC_ALGS_STOC: -@@ -363,6 +381,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], - prop[i] = xstrdup(defprop[i]); - } - } -+ free(cp); - } - - void -@@ -466,7 +485,12 @@ kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh) - { - int r; - -- error("kex protocol error: type %d seq %u", type, seq); -+ /* If in strict mode, any unexpected message is an error */ -+ if ((ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) { -+ ssh_packet_disconnect(ssh, "strict KEX violation: " -+ "unexpected packet type %u (seqnr %u)", type, seq); -+ } -+ error_f("type %u seq %u", type, seq); - if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || - (r = sshpkt_put_u32(ssh, seq)) != 0 || - (r = sshpkt_send(ssh)) != 0) -@@ -563,7 +587,7 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh) - if (ninfo >= 1024) { - error("SSH2_MSG_EXT_INFO with too many entries, expected " - "<=1024, received %u", ninfo); -- return SSH_ERR_INVALID_FORMAT; -+ return dispatch_protocol_error(type, seq, ssh); - } - for (i = 0; i < ninfo; i++) { - if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) -@@ -681,7 +705,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) - error_f("no kex"); - return SSH_ERR_INTERNAL_ERROR; - } -- ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL); -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error); - ptr = sshpkt_ptr(ssh, &dlen); - if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) - return r; -@@ -717,7 +741,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) - if (!(kex->flags & KEX_INIT_SENT)) - if ((r = kex_send_kexinit(ssh)) != 0) - return r; -- if ((r = kex_choose_conf(ssh)) != 0) -+ if ((r = kex_choose_conf(ssh, seq)) != 0) - return r; - - if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL) -@@ -981,20 +1005,14 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) - return (1); - } - --/* returns non-zero if proposal contains any algorithm from algs */ - static int --has_any_alg(const char *proposal, const char *algs) -+kexalgs_contains(char **peer, const char *ext) - { -- char *cp; -- -- if ((cp = match_list(proposal, algs, NULL)) == NULL) -- return 0; -- free(cp); -- return 1; -+ return has_any_alg(peer[PROPOSAL_KEX_ALGS], ext); - } - - static int --kex_choose_conf(struct ssh *ssh) -+kex_choose_conf(struct ssh *ssh, uint32_t seq) - { - struct kex *kex = ssh->kex; - struct newkeys *newkeys; -@@ -1019,13 +1037,23 @@ kex_choose_conf(struct ssh *ssh) - sprop=peer; - } - -- /* Check whether client supports ext_info_c */ -- if (kex->server && (kex->flags & KEX_INITIAL)) { -- char *ext; -- -- ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL); -- kex->ext_info_c = (ext != NULL); -- free(ext); -+ /* Check whether peer supports ext_info/kex_strict */ -+ if ((kex->flags & KEX_INITIAL) != 0) { -+ if (kex->server) { -+ kex->ext_info_c = kexalgs_contains(peer, "ext-info-c"); -+ kex->kex_strict = kexalgs_contains(peer, -+ "kex-strict-c-v00@openssh.com"); -+ } else { -+ kex->kex_strict = kexalgs_contains(peer, -+ "kex-strict-s-v00@openssh.com"); -+ } -+ if (kex->kex_strict) { -+ debug3_f("will use strict KEX ordering"); -+ if (seq != 0) -+ ssh_packet_disconnect(ssh, -+ "strict KEX violation: " -+ "KEXINIT was not the first packet"); -+ } - } - - /* Check whether client supports rsa-sha2 algorithms */ -diff --git a/kex.h b/kex.h -index 5f7ef784e..272ebb43d 100644 ---- a/kex.h -+++ b/kex.h -@@ -1,4 +1,4 @@ --/* $OpenBSD: kex.h,v 1.118 2023/03/06 12:14:48 dtucker Exp $ */ -+/* $OpenBSD: kex.h,v 1.120 2023/12/18 14:45:17 djm Exp $ */ - - /* - * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. -@@ -149,6 +149,7 @@ struct kex { - u_int kex_type; - char *server_sig_algs; - int ext_info_c; -+ int kex_strict; - struct sshbuf *my; - struct sshbuf *peer; - struct sshbuf *client_version; -diff --git a/packet.c b/packet.c -index 52017defb..beb214f99 100644 ---- a/packet.c -+++ b/packet.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: packet.c,v 1.309 2023/03/03 10:23:42 dtucker Exp $ */ -+/* $OpenBSD: packet.c,v 1.313 2023/12/18 14:45:17 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -1207,8 +1207,13 @@ ssh_packet_send2_wrapped(struct ssh *ssh) - sshbuf_dump(state->output, stderr); - #endif - /* increment sequence number for outgoing packets */ -- if (++state->p_send.seqnr == 0) -+ if (++state->p_send.seqnr == 0) { -+ if ((ssh->kex->flags & KEX_INITIAL) != 0) { -+ ssh_packet_disconnect(ssh, "outgoing sequence number " -+ "wrapped during initial key exchange"); -+ } - logit("outgoing seqnr wraps around"); -+ } - if (++state->p_send.packets == 0) - if (!(ssh->compat & SSH_BUG_NOREKEY)) - return SSH_ERR_NEED_REKEY; -@@ -1216,6 +1221,11 @@ ssh_packet_send2_wrapped(struct ssh *ssh) - state->p_send.bytes += len; - sshbuf_reset(state->outgoing_packet); - -+ if (type == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) { -+ debug_f("resetting send seqnr %u", state->p_send.seqnr); -+ state->p_send.seqnr = 0; -+ } -+ - if (type == SSH2_MSG_NEWKEYS) - r = ssh_set_newkeys(ssh, MODE_OUT); - else if (type == SSH2_MSG_USERAUTH_SUCCESS && state->server_side) -@@ -1344,8 +1354,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - /* Stay in the loop until we have received a complete packet. */ - for (;;) { - /* Try to read a packet from the buffer. */ -- r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p); -- if (r != 0) -+ if ((r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p)) != 0) - break; - /* If we got a packet, return it. */ - if (*typep != SSH_MSG_NONE) -@@ -1629,10 +1615,16 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) - goto out; - } -+ - if (seqnr_p != NULL) - *seqnr_p = state->p_read.seqnr; -- if (++state->p_read.seqnr == 0) -+ if (++state->p_read.seqnr == 0) { -+ if ((ssh->kex->flags & KEX_INITIAL) != 0) { -+ ssh_packet_disconnect(ssh, "incoming sequence number " -+ "wrapped during initial key exchange"); -+ } - logit("incoming seqnr wraps around"); -+ } - if (++state->p_read.packets == 0) - if (!(ssh->compat & SSH_BUG_NOREKEY)) - return SSH_ERR_NEED_REKEY; -@@ -1698,6 +1690,10 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - #endif - /* reset for next packet */ - state->packlen = 0; -+ if (*typep == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) { -+ debug_f("resetting read seqnr %u", state->p_read.seqnr); -+ state->p_read.seqnr = 0; -+ } - - if ((r = ssh_packet_check_rekey(ssh)) != 0) - return r; -@@ -1720,10 +1716,39 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - r = ssh_packet_read_poll2(ssh, typep, seqnr_p); - if (r != 0) - return r; -- if (*typep) { -- state->keep_alive_timeouts = 0; -- DBG(debug("received packet type %d", *typep)); -+ if (*typep == 0) { -+ /* no message ready */ -+ return 0; - } -+ state->keep_alive_timeouts = 0; -+ DBG(debug("received packet type %d", *typep)); -+ -+ /* Always process disconnect messages */ -+ if (*typep == SSH2_MSG_DISCONNECT) { -+ if ((r = sshpkt_get_u32(ssh, &reason)) != 0 || -+ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0) -+ return r; -+ /* Ignore normal client exit notifications */ -+ do_log2(ssh->state->server_side && -+ reason == SSH2_DISCONNECT_BY_APPLICATION ? -+ SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, -+ "Received disconnect from %s port %d:" -+ "%u: %.400s", ssh_remote_ipaddr(ssh), -+ ssh_remote_port(ssh), reason, msg); -+ free(msg); -+ return SSH_ERR_DISCONNECTED; -+ } -+ -+ /* -+ * Do not implicitly handle any messages here during initial -+ * KEX when in strict mode. They will be need to be allowed -+ * explicitly by the KEX dispatch table or they will generate -+ * protocol errors. -+ */ -+ if (ssh->kex != NULL && -+ (ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) -+ return 0; -+ /* Implicitly handle transport-level messages */ - switch (*typep) { - case SSH2_MSG_IGNORE: - debug3("Received SSH2_MSG_IGNORE"); -@@ -1738,19 +1763,6 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) - debug("Remote: %.900s", msg); - free(msg); - break; -- case SSH2_MSG_DISCONNECT: -- if ((r = sshpkt_get_u32(ssh, &reason)) != 0 || -- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0) -- return r; -- /* Ignore normal client exit notifications */ -- do_log2(ssh->state->server_side && -- reason == SSH2_DISCONNECT_BY_APPLICATION ? -- SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, -- "Received disconnect from %s port %d:" -- "%u: %.400s", ssh_remote_ipaddr(ssh), -- ssh_remote_port(ssh), reason, msg); -- free(msg); -- return SSH_ERR_DISCONNECTED; - case SSH2_MSG_UNIMPLEMENTED: - if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0) - return r; -@@ -2242,6 +2254,7 @@ kex_to_blob(struct sshbuf *m, struct kex *kex) - (r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 || - (r = sshbuf_put_u32(m, kex->hostkey_nid)) != 0 || - (r = sshbuf_put_u32(m, kex->kex_type)) != 0 || -+ (r = sshbuf_put_u32(m, kex->kex_strict)) != 0 || - (r = sshbuf_put_stringb(m, kex->my)) != 0 || - (r = sshbuf_put_stringb(m, kex->peer)) != 0 || - (r = sshbuf_put_stringb(m, kex->client_version)) != 0 || -@@ -2404,6 +2417,7 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp) - (r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 || - (r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_nid)) != 0 || - (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 || -+ (r = sshbuf_get_u32(m, &kex->kex_strict)) != 0 || - (r = sshbuf_get_stringb(m, kex->my)) != 0 || - (r = sshbuf_get_stringb(m, kex->peer)) != 0 || - (r = sshbuf_get_stringb(m, kex->client_version)) != 0 || -@@ -2732,6 +2746,7 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...) - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - -+ debug2_f("sending SSH2_MSG_DISCONNECT: %s", buf); - if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || - (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || - (r = sshpkt_put_cstring(ssh, buf)) != 0 || -diff --git a/packet.h b/packet.h -index 11925a27d..b2bc3215d 100644 ---- a/packet.h -+++ b/packet.h -@@ -1,4 +1,4 @@ --/* $OpenBSD: packet.h,v 1.94 2022/01/22 00:49:34 djm Exp $ */ -+/* $OpenBSD: packet.h,v 1.96 2023/12/18 14:45:17 djm Exp $ */ - - /* - * Author: Tatu Ylonen -diff --git a/sshconnect2.c b/sshconnect2.c -index df6caf817..0cccbcc43 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sshconnect2.c,v 1.366 2023/03/09 07:11:05 dtucker Exp $ */ -+/* $OpenBSD: sshconnect2.c,v 1.370 2023/12/18 14:45:17 djm Exp $ */ - /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * Copyright (c) 2008 Damien Miller. All rights reserved. -@@ -358,7 +358,6 @@ struct cauthmethod { - }; - - static int input_userauth_service_accept(int, u_int32_t, struct ssh *); --static int input_userauth_ext_info(int, u_int32_t, struct ssh *); - static int input_userauth_success(int, u_int32_t, struct ssh *); - static int input_userauth_failure(int, u_int32_t, struct ssh *); - static int input_userauth_banner(int, u_int32_t, struct ssh *); -@@ -472,7 +471,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user, - - ssh->authctxt = &authctxt; - ssh_dispatch_init(ssh, &input_userauth_error); -- ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info); -+ ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, kex_input_ext_info); - ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept); - ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */ - pubkey_cleanup(ssh); -@@ -531,12 +530,6 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) - return r; - } - --static int --input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh) --{ -- return kex_input_ext_info(type, seqnr, ssh); --} -- - void - userauth(struct ssh *ssh, char *authlist) - { -@@ -615,6 +608,7 @@ input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) - free(authctxt->methoddata); - authctxt->methoddata = NULL; - authctxt->success = 1; /* break out */ -+ ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, dispatch_protocol_error); - return 0; - } - --- -2.23.0 - diff --git a/backport-CVE-2023-51384-upstream-apply-destination-constraints-to-all-p11-ke.patch b/backport-CVE-2023-51384-upstream-apply-destination-constraints-to-all-p11-ke.patch deleted file mode 100644 index 5d5823e5967a1aed489497fa95cfd6c41d83b224..0000000000000000000000000000000000000000 --- a/backport-CVE-2023-51384-upstream-apply-destination-constraints-to-all-p11-ke.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 881d9c6af9da4257c69c327c4e2f1508b2fa754b Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 18 Dec 2023 14:46:12 +0000 -Subject: [PATCH] upstream: apply destination constraints to all p11 keys - -Previously applied only to the first key returned from each token. - -ok markus@ - -OpenBSD-Commit-ID: 36df3afb8eb94eec6b2541f063d0d164ef8b488d - -Reference:https://github.com/openssh/openssh-portable/commit/881d9c6af9da4257c69c327c4e2f1508b2fa754b ---- - ssh-agent.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 100 insertions(+), 5 deletions(-) - -diff --git a/ssh-agent.c b/ssh-agent.c -index f52861163..1d4c321eb 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: ssh-agent.c,v 1.297 2023/03/09 21:06:24 jcs Exp $ */ -+/* $OpenBSD: ssh-agent.c,v 1.301 2023/12/18 14:46:12 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -247,6 +247,91 @@ free_dest_constraints(struct dest_constraint *dcs, size_t ndcs) - free(dcs); - } - -+static void -+dup_dest_constraint_hop(const struct dest_constraint_hop *dch, -+ struct dest_constraint_hop *out) -+{ -+ u_int i; -+ int r; -+ -+ out->user = dch->user == NULL ? NULL : xstrdup(dch->user); -+ out->hostname = dch->hostname == NULL ? NULL : xstrdup(dch->hostname); -+ out->is_ca = dch->is_ca; -+ out->nkeys = dch->nkeys; -+ out->keys = out->nkeys == 0 ? NULL : -+ xcalloc(out->nkeys, sizeof(*out->keys)); -+ out->key_is_ca = out->nkeys == 0 ? NULL : -+ xcalloc(out->nkeys, sizeof(*out->key_is_ca)); -+ for (i = 0; i < dch->nkeys; i++) { -+ if (dch->keys[i] != NULL && -+ (r = sshkey_from_private(dch->keys[i], -+ &(out->keys[i]))) != 0) -+ fatal_fr(r, "copy key"); -+ out->key_is_ca[i] = dch->key_is_ca[i]; -+ } -+} -+ -+static struct dest_constraint * -+dup_dest_constraints(const struct dest_constraint *dcs, size_t ndcs) -+{ -+ size_t i; -+ struct dest_constraint *ret; -+ -+ if (ndcs == 0) -+ return NULL; -+ ret = xcalloc(ndcs, sizeof(*ret)); -+ for (i = 0; i < ndcs; i++) { -+ dup_dest_constraint_hop(&dcs[i].from, &ret[i].from); -+ dup_dest_constraint_hop(&dcs[i].to, &ret[i].to); -+ } -+ return ret; -+} -+ -+#ifdef DEBUG_CONSTRAINTS -+static void -+dump_dest_constraint_hop(const struct dest_constraint_hop *dch) -+{ -+ u_int i; -+ char *fp; -+ -+ debug_f("user %s hostname %s is_ca %d nkeys %u", -+ dch->user == NULL ? "(null)" : dch->user, -+ dch->hostname == NULL ? "(null)" : dch->hostname, -+ dch->is_ca, dch->nkeys); -+ for (i = 0; i < dch->nkeys; i++) { -+ fp = NULL; -+ if (dch->keys[i] != NULL && -+ (fp = sshkey_fingerprint(dch->keys[i], -+ SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL) -+ fatal_f("fingerprint failed"); -+ debug_f("key %u/%u: %s%s%s key_is_ca %d", i, dch->nkeys, -+ dch->keys[i] == NULL ? "" : sshkey_ssh_name(dch->keys[i]), -+ dch->keys[i] == NULL ? "" : " ", -+ dch->keys[i] == NULL ? "none" : fp, -+ dch->key_is_ca[i]); -+ free(fp); -+ } -+} -+#endif /* DEBUG_CONSTRAINTS */ -+ -+static void -+dump_dest_constraints(const char *context, -+ const struct dest_constraint *dcs, size_t ndcs) -+{ -+#ifdef DEBUG_CONSTRAINTS -+ size_t i; -+ -+ debug_f("%s: %zu constraints", context, ndcs); -+ for (i = 0; i < ndcs; i++) { -+ debug_f("constraint %zu / %zu: from: ", i, ndcs); -+ dump_dest_constraint_hop(&dcs[i].from); -+ debug_f("constraint %zu / %zu: to: ", i, ndcs); -+ dump_dest_constraint_hop(&dcs[i].to); -+ } -+ debug_f("done for %s", context); -+#endif /* DEBUG_CONSTRAINTS */ -+} -+ - static void - free_identity(Identity *id) - { -@@ -518,13 +603,22 @@ process_request_identities(SocketEntry *e) - Identity *id; - struct sshbuf *msg, *keys; - int r; -- u_int nentries = 0; -+ u_int i = 0, nentries = 0; -+ char *fp; - - debug2_f("entering"); - - if ((msg = sshbuf_new()) == NULL || (keys = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - TAILQ_FOREACH(id, &idtab->idlist, next) { -+ if ((fp = sshkey_fingerprint(id->key, SSH_FP_HASH_DEFAULT, -+ SSH_FP_DEFAULT)) == NULL) -+ fatal_f("fingerprint failed"); -+ debug_f("key %u / %u: %s %s", i++, idtab->nentries, -+ sshkey_ssh_name(id->key), fp); -+ dump_dest_constraints(__func__, -+ id->dest_constraints, id->ndest_constraints); -+ free(fp); - /* identity not visible, don't include in response */ - if (identity_permitted(id, e, NULL, NULL, NULL) != 0) - continue; -@@ -1224,6 +1318,7 @@ process_add_identity(SocketEntry *e) - sshbuf_reset(e->request); - goto out; - } -+ dump_dest_constraints(__func__, dest_constraints, ndest_constraints); - - if (sk_provider != NULL) { - if (!sshkey_is_sk(k)) { -@@ -1403,6 +1498,7 @@ process_add_smartcard_key(SocketEntry *e) - error_f("failed to parse constraints"); - goto send; - } -+ dump_dest_constraints(__func__, dest_constraints, ndest_constraints); - if (e->nsession_ids != 0 && !remote_add_provider) { - verbose("failed PKCS#11 add of \"%.100s\": remote addition of " - "providers is disabled", provider); -@@ -1438,10 +1534,9 @@ process_add_smartcard_key(SocketEntry *e) - } - id->death = death; - id->confirm = confirm; -- id->dest_constraints = dest_constraints; -+ id->dest_constraints = dup_dest_constraints( -+ dest_constraints, ndest_constraints); - id->ndest_constraints = ndest_constraints; -- dest_constraints = NULL; /* transferred */ -- ndest_constraints = 0; - TAILQ_INSERT_TAIL(&idtab->idlist, id, next); - idtab->nentries++; - success = 1; --- -2.33.0 - diff --git a/backport-CVE-2023-51385-upstream-ban-user-hostnames-with-most-shell-metachar.patch b/backport-CVE-2023-51385-upstream-ban-user-hostnames-with-most-shell-metachar.patch deleted file mode 100644 index d5e43e78bc7db60a0fec53da52f906fabf9bc5ea..0000000000000000000000000000000000000000 --- a/backport-CVE-2023-51385-upstream-ban-user-hostnames-with-most-shell-metachar.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 7ef3787c84b6b524501211b11a26c742f829af1a Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 18 Dec 2023 14:47:44 +0000 -Subject: [PATCH] upstream: ban user/hostnames with most shell metacharacters - -This makes ssh(1) refuse user or host names provided on the -commandline that contain most shell metacharacters. - -Some programs that invoke ssh(1) using untrusted data do not filter -metacharacters in arguments they supply. This could create -interactions with user-specified ProxyCommand and other directives -that allow shell injection attacks to occur. - -It's a mistake to invoke ssh(1) with arbitrary untrusted arguments, -but getting this stuff right can be tricky, so this should prevent -most obvious ways of creating risky situations. It however is not -and cannot be perfect: ssh(1) has no practical way of interpreting -what shell quoting rules are in use and how they interact with the -user's specified ProxyCommand. - -To allow configurations that use strange user or hostnames to -continue to work, this strictness is applied only to names coming -from the commandline. Names specified using User or Hostname -directives in ssh_config(5) are not affected. - -feedback/ok millert@ markus@ dtucker@ deraadt@ - -OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9 - -Reference:https://anongit.mindrot.org/openssh.git/commit?id=7ef3787c84b6b524501211b11a26c742f829af1a ---- - ssh.c | 41 ++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 40 insertions(+), 1 deletion(-) - -diff --git a/ssh.c b/ssh.c -index 35c48e62d..48d93ddf2 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: ssh.c,v 1.585 2023/02/10 04:40:28 djm Exp $ */ -+/* $OpenBSD: ssh.c,v 1.599 2023/12/18 14:47:44 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -626,6 +626,41 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo) - free(cinfo); - } - -+static int -+valid_hostname(const char *s) -+{ -+ size_t i; -+ -+ if (*s == '-') -+ return 0; -+ for (i = 0; s[i] != 0; i++) { -+ if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL || -+ isspace((u_char)s[i]) || iscntrl((u_char)s[i])) -+ return 0; -+ } -+ return 1; -+} -+ -+static int -+valid_ruser(const char *s) -+{ -+ size_t i; -+ -+ if (*s == '-') -+ return 0; -+ for (i = 0; s[i] != 0; i++) { -+ if (strchr("'`\";&<>|(){}", s[i]) != NULL) -+ return 0; -+ /* Disallow '-' after whitespace */ -+ if (isspace((u_char)s[i]) && s[i + 1] == '-') -+ return 0; -+ /* Disallow \ in last position */ -+ if (s[i] == '\\' && s[i + 1] == '\0') -+ return 0; -+ } -+ return 1; -+} -+ - /* - * Main program for the ssh client. - */ -@@ -1118,6 +1153,10 @@ main(int ac, char **av) - if (!host) - usage(); - -+ if (!valid_hostname(host)) -+ fatal("hostname contains invalid characters"); -+ if (options.user != NULL && !valid_ruser(options.user)) -+ fatal("remote username contains invalid characters"); - options.host_arg = xstrdup(host); - - /* Initialize the command to execute on remote host. */ --- -2.23.0 - diff --git a/backport-openssh-6.6p1-keyperm.patch b/backport-openssh-6.6p1-keyperm.patch deleted file mode 100644 index 333d106cd20a572bda6e26ec70ebc45c53a82a04..0000000000000000000000000000000000000000 --- a/backport-openssh-6.6p1-keyperm.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff -up openssh-8.2p1/authfile.c.keyperm openssh-8.2p1/authfile.c ---- openssh-8.2p1/authfile.c.keyperm 2020-02-14 01:40:54.000000000 +0100 -+++ openssh-8.2p1/authfile.c 2020-02-17 11:55:12.841729758 +0100 -Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/backport-openssh-6.6p1-keyperm.patch -Conflict:NA -@@ -31,6 +31,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -101,7 +102,19 @@ sshkey_perm_ok(int fd, const char *filen - #ifdef HAVE_CYGWIN - if (check_ntsec(filename)) - #endif -+ - if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { -+ if (st.st_mode & 040) { -+ struct group *gr; -+ -+ if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid)) { -+ /* The only additional bit is read -+ * for ssh_keys group, which is fine */ -+ if ((st.st_mode & 077) == 040 ) { -+ return 0; -+ } -+ } -+ } - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); diff --git a/backport-upstream-Make-sure-sftp_get_limits-only-returns-0-if.patch b/backport-upstream-Make-sure-sftp_get_limits-only-returns-0-if.patch deleted file mode 100644 index 75a704e7c7b419ff6f7bb81300e51b1a2d841149..0000000000000000000000000000000000000000 --- a/backport-upstream-Make-sure-sftp_get_limits-only-returns-0-if.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 676377ce67807a24e08a54cd60ec832946cc6cae Mon Sep 17 00:00:00 2001 -From: "tobhe@openbsd.org" -Date: Mon, 13 Nov 2023 09:18:19 +0000 -Subject: [PATCH] upstream: Make sure sftp_get_limits() only returns 0 if - 'limits' - -was initialized. This fixes a potential uninitialized use of 'limits' in -sftp_init() if sftp_get_limits() returned early because of an unexpected -message type. - -ok djm@ - -OpenBSD-Commit-ID: 1c177d7c3becc1d71bc8763eecf61873a1d3884c - -Reference:https://github.com/openssh/openssh-portable/commit/676377ce67807a24e08a54cd60ec832946cc6cae -Conflict:2de990142(Rename do_limits to sftp_get_limits) ---- - sftp-client.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/sftp-client.c b/sftp-client.c -index 2598029f7..5cc8bb539 100644 ---- a/sftp-client.c -+++ b/sftp-client.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sftp-client.c,v 1.169 2023/03/08 04:43:12 guenther Exp $ */ -+/* $OpenBSD: sftp-client.c,v 1.175 2023/11/13 09:18:19 tobhe Exp $ */ - /* - * Copyright (c) 2001-2004 Damien Miller - * -@@ -656,7 +656,7 @@ do_limits(struct sftp_conn *conn, struct sftp_limits *limits) - /* Disable the limits extension */ - conn->exts &= ~SFTP_EXT_LIMITS; - sshbuf_free(msg); -- return 0; -+ return -1; - } - - memset(limits, 0, sizeof(*limits)); --- -2.33.0 - diff --git a/backport-upstream-fix-memory-leak-in-mux-proxy-mode-when-requ.patch b/backport-upstream-fix-memory-leak-in-mux-proxy-mode-when-requ.patch deleted file mode 100644 index 83a9f99363b2df8b5699c434365ac456ac874e26..0000000000000000000000000000000000000000 --- a/backport-upstream-fix-memory-leak-in-mux-proxy-mode-when-requ.patch +++ /dev/null @@ -1,41 +0,0 @@ -From c47e1c9c7911f38b2fc2fb01b1f6ae3a3121a838 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Wed, 6 Mar 2024 02:59:59 +0000 -Subject: [PATCH] upstream: fix memory leak in mux proxy mode when requesting - forwarding. - -found by RASU JSC, reported by Maks Mishin in GHPR#467 - -OpenBSD-Commit-ID: 97d96a166b1ad4b8d229864a553e3e56d3116860 - -Reference:https://github.com/openssh/openssh-portable/commit/c47e1c9c7911f38b2fc2fb01b1f6ae3a3121a838 -Conflict:NA ---- - channels.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/channels.c b/channels.c -index 6862556be..ece8d30d6 100644 ---- a/channels.c -+++ b/channels.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: channels.c,v 1.430 2023/03/10 03:01:51 dtucker Exp $ */ -+/* $OpenBSD: channels.c,v 1.437 2024/03/06 02:59:59 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -3245,9 +3245,8 @@ channel_proxy_downstream(struct ssh *ssh, Channel *downstream) - goto out; - } - /* Record that connection to this host/port is permitted. */ -- permission_set_add(ssh, FORWARD_USER, FORWARD_LOCAL, "", -1, -- listen_host, NULL, (int)listen_port, downstream); -- listen_host = NULL; -+ permission_set_add(ssh, FORWARD_USER, FORWARD_LOCAL, "", -+ -1, listen_host, NULL, (int)listen_port, downstream); - break; - case SSH2_MSG_CHANNEL_CLOSE: - if (have < 4) --- -2.33.0 - diff --git a/backport-upstream-make-parsing-user-host-consistently-look-for-the-last-in.patch b/backport-upstream-make-parsing-user-host-consistently-look-for-the-last-in.patch index 0955217f434146316713cefa5fbd6c3e6c285d80..7c28a8778b89fdeee2320940049b24b015ad59c3 100644 --- a/backport-upstream-make-parsing-user-host-consistently-look-for-the-last-in.patch +++ b/backport-upstream-make-parsing-user-host-consistently-look-for-the-last-in.patch @@ -1,23 +1,37 @@ From a8ad7a2952111c6ce32949a775df94286550af6b Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 6 Sep 2024 02:30:44 +0000 -Subject: [PATCH] upstream: make parsing user@host consistently look for the - last '@' in the string rather than the first. This makes it possible to - use usernames that contain '@' characters. +Subject: upstream: make parsing user@host consistently look for the last '@' + in +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/commit/a8ad7a2952111c6ce32949a775df94286550af6b +the string rather than the first. This makes it possible to use usernames +that contain '@' characters. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Prompted by Max Zettlmeißl; feedback/ok millert@ + +OpenBSD-Commit-ID: 0b16eec246cda15469ebdcf3b1e2479810e394c5 --- - match.c | 6 +++--- - ssh-add.c | 2 +- - 2 files changed, 4 insertions(+), 4 deletions(-) + match.c | 8 ++++---- + ssh-add.c | 4 ++-- + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/match.c b/match.c -index 3ac854d..b9a8225 100644 +index d6af2561..3ef53693 100644 --- a/match.c +++ b/match.c -@@ -241,17 +241,17 @@ match_user(const char *user, const char *host, const char *ipaddr, +@@ -1,4 +1,4 @@ +-/* $OpenBSD: match.c,v 1.44 2023/04/06 03:19:32 djm Exp $ */ ++/* $OpenBSD: match.c,v 1.45 2024/09/06 02:30:44 djm Exp $ */ + /* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +@@ -241,7 +241,7 @@ match_user(const char *user, const char *host, const char *ipaddr, /* test mode */ if (user == NULL && host == NULL && ipaddr == NULL) { @@ -26,7 +40,9 @@ index 3ac854d..b9a8225 100644 match_host_and_ip(NULL, NULL, p + 1) < 0) return -1; return 0; - } +@@ -250,11 +250,11 @@ match_user(const char *user, const char *host, const char *ipaddr, + if (user == NULL) + return 0; /* shouldn't happen */ - if ((p = strchr(pattern, '@')) == NULL) + if (strrchr(pattern, '@') == NULL) @@ -39,10 +55,16 @@ index 3ac854d..b9a8225 100644 if ((ret = match_pattern(user, pat)) == 1) diff --git a/ssh-add.c b/ssh-add.c -index 8cba0a7..2b081d6 100644 +index e532d5ce..0035cb84 100644 --- a/ssh-add.c +++ b/ssh-add.c -@@ -712,7 +712,7 @@ parse_dest_constraint_hop(const char *s, struct dest_constraint_hop *dch, +@@ -1,4 +1,4 @@ +-/* $OpenBSD: ssh-add.c,v 1.169 2023/12/18 14:46:56 djm Exp $ */ ++/* $OpenBSD: ssh-add.c,v 1.173 2024/09/06 02:30:44 djm Exp $ */ + /* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +@@ -696,7 +696,7 @@ parse_dest_constraint_hop(const char *s, struct dest_constraint_hop *dch, memset(dch, '\0', sizeof(*dch)); os = xstrdup(s); @@ -52,5 +74,4 @@ index 8cba0a7..2b081d6 100644 else { *host++ = '\0'; -- -2.43.0 - +cgit v1.2.3 diff --git a/backport-upstream-set-errno-EAFNOSUPPORT-when-filtering-addre.patch b/backport-upstream-set-errno-EAFNOSUPPORT-when-filtering-addre.patch deleted file mode 100644 index 2ba8172bf4451ab833318710e33de271753f5c4c..0000000000000000000000000000000000000000 --- a/backport-upstream-set-errno-EAFNOSUPPORT-when-filtering-addre.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c52db0114826d73eff6cdbf205e9c1fa4f7ca6c6 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 20 Nov 2023 02:50:00 +0000 -Subject: [PATCH] upstream: set errno=EAFNOSUPPORT when filtering addresses - that don't - -match AddressFamily; yields slightly better error message if no address -matches. bz#3526 - -OpenBSD-Commit-ID: 29cea900ddd8b04a4d1968da5c4a893be2ebd9e6 - -Reference:https://github.com/openssh/openssh-portable/commit/c52db0114826d73eff6cdbf205e9c1fa4f7ca6c6 -Conflict:NA ---- - sshconnect.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/sshconnect.c b/sshconnect.c -index ff3d3501f..bd077c75c 100644 ---- a/sshconnect.c -+++ b/sshconnect.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sshconnect.c,v 1.364 2023/11/15 23:03:38 djm Exp $ */ -+/* $OpenBSD: sshconnect.c,v 1.365 2023/11/20 02:50:00 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -485,7 +485,7 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, - ai->ai_family != options.address_family) { - debug2_f("skipping address [%s]:%s: " - "wrong address family", ntop, strport); -- errno = 0; -+ errno = EAFNOSUPPORT; - continue; - } - --- -2.33.0 - diff --git a/backport-upstream-when-connecting-via-socket-the-default-case.patch b/backport-upstream-when-connecting-via-socket-the-default-case.patch deleted file mode 100644 index d026ccf055aff864e55983e37ec2e56bf7ff7741..0000000000000000000000000000000000000000 --- a/backport-upstream-when-connecting-via-socket-the-default-case.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 26f3f3bbc69196d908cad6558c8c7dc5beb8d74a Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Wed, 15 Nov 2023 23:03:38 +0000 -Subject: [PATCH] upstream: when connecting via socket (the default case), - filter - -addresses by AddressFamily if one was specified. Fixes the case where, if -CanonicalizeHostname is enabled, ssh may ignore AddressFamily. bz5326; ok -dtucker - -OpenBSD-Commit-ID: 6c7d7751f6cd055126b2b268a7b64dcafa447439 - -Reference:https://github.com/openssh/openssh-portable/commit/26f3f3bbc69196d908cad6558c8c7dc5beb8d74a -Conflict:NA ---- - sshconnect.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/sshconnect.c b/sshconnect.c -index e6012f01e..ff3d3501f 100644 ---- a/sshconnect.c -+++ b/sshconnect.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sshconnect.c,v 1.363 2023/03/10 07:17:08 dtucker Exp $ */ -+/* $OpenBSD: sshconnect.c,v 1.364 2023/11/15 23:03:38 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -481,6 +481,14 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, - errno = oerrno; - continue; - } -+ if (options.address_family != AF_UNSPEC && -+ ai->ai_family != options.address_family) { -+ debug2_f("skipping address [%s]:%s: " -+ "wrong address family", ntop, strport); -+ errno = 0; -+ continue; -+ } -+ - debug("Connecting to %.200s [%.100s] port %s.", - host, ntop, strport); - --- -2.33.0 - diff --git a/backport-upstream-when-invoking-KnownHostsCommand-to-determin.patch b/backport-upstream-when-invoking-KnownHostsCommand-to-determin.patch deleted file mode 100644 index e727a7cfbd5ef2c2c1c697e95963ad7a30ad6f09..0000000000000000000000000000000000000000 --- a/backport-upstream-when-invoking-KnownHostsCommand-to-determin.patch +++ /dev/null @@ -1,44 +0,0 @@ -From aa7b21708511a6d4aed3839fc9f6e82e849dd4a1 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Wed, 13 Dec 2023 03:28:19 +0000 -Subject: [PATCH] upstream: when invoking KnownHostsCommand to determine the - order of - -host key algorithms to request, ensure that the hostname passed to the -command is decorated with the port number for ports other than 22. - -This matches the behaviour of KnownHostsCommand when invoked to look -up the actual host key. - -bz3643, ok dtucker@ - -OpenBSD-Commit-ID: 5cfabc0b7c6c7ab473666df314f377b1f15420b1 - -Reference:https://github.com/openssh/openssh-portable/commit/aa7b21708511a6d4aed3839fc9f6e82e849dd4a1 -Conflict:NA ---- - sshconnect2.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/sshconnect2.c b/sshconnect2.c -index 5831a00c6..df6caf817 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.369 2023/12/13 03:28:19 djm Exp $ */ - /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * Copyright (c) 2008 Damien Miller. All rights reserved. -@@ -140,7 +140,7 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port, - } - if (options.known_hosts_command != NULL) { - load_hostkeys_command(hostkeys, options.known_hosts_command, -- "ORDER", cinfo, NULL, host); -+ "ORDER", cinfo, NULL, hostname); - } - /* - * If a plain public key exists that matches the type of the best --- -2.33.0 - diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index fa9d5914de1250f852dd63ceda625ecafeeed748..eab724a0f002e0433607bf968601f821af9b6a83 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -93,19 +93,17 @@ index 8f32464..18a2ca4 100644 #endif diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 22ea8ef..1fc963d 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname) - strlcpy(newctx + len, newname, newlen - len); - if ((cx = index(cx + 1, ':'))) - strlcat(newctx, cx, newlen); -- debug3("%s: setting context from '%s' to '%s'", __func__, -+ debug_f("setting context from '%s' to '%s'", - oldctx, newctx); +--- a/openbsd-compat/port-linux.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/openbsd-compat/port-linux.c (date 1703108053912) +@@ -207,7 +207,7 @@ + xasprintf(&newctx, "%.*s%s%s", (int)(cx - oldctx + 1), oldctx, + newname, cx2 == NULL ? "" : cx2); + +- debug3_f("setting context from '%s' to '%s'", oldctx, newctx); ++ debug_f("setting context from '%s' to '%s'", oldctx, newctx); if (setcon(newctx) < 0) - do_log2(log_level, "%s: setcon %s from %s failed with %s", - __func__, newctx, oldctx, strerror(errno)); + do_log2_f(log_level, "setcon %s from %s failed with %s", + newctx, oldctx, strerror(errno)); diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index cb51f99..8b7cda2 100644 --- a/openbsd-compat/port-linux.h diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 494f4c6a1a0cb956a83cedf2b83c45511546f99a..01a061b9e6174c139c809edaf005b8f298cd4f82 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -17,17 +17,6 @@ diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c return oerrno; } /* make sure the KRB5CCNAME is set for non-standard location */ -diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c ---- openssh-8.5p1/auth-options.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/auth-options.c 2021-03-24 12:03:33.782968159 +0100 -@@ -706,6 +708,7 @@ serialise_array(struct sshbuf *m, char * - return r; - } - /* success */ -+ sshbuf_free(b); - return 0; - } - diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c --- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100 +++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100 @@ -42,32 +31,9 @@ diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (sshbuf_len(buf) != 0 && -diff -up openssh-8.5p1/kexgssc.c.coverity openssh-8.5p1/kexgssc.c ---- openssh-8.5p1/kexgssc.c.coverity 2021-03-24 12:03:33.711967665 +0100 -+++ openssh-8.5p1/kexgssc.c 2021-03-24 12:03:33.783968166 +0100 -@@ -98,8 +98,10 @@ kexgss_client(struct ssh *ssh) - default: - fatal_f("Unexpected KEX type %d", kex->kex_type); - } -- if (r != 0) -+ if (r != 0) { -+ ssh_gssapi_delete_ctx(&ctxt); - return r; -+ } - - token_ptr = GSS_C_NO_BUFFER; - diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c --- openssh-8.5p1/krl.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/krl.c 2021-03-24 12:03:33.783968166 +0100 -@@ -1209,6 +1209,7 @@ ssh_krl_from_blob(struct sshbuf *buf, st - sshkey_free(key); - sshbuf_free(copy); - sshbuf_free(sect); -+ /* coverity[leaked_storage : FALSE] */ - return r; - } - @@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); @@ -164,23 +130,6 @@ diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c return (0); error: -diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.coverity 2016-12-23 16:40:26.892788689 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:40:26.900788691 +0100 -@@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, - if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || - (tmp2 = dup(pmonitor->m_recvfd)) == -1) { - error_f("cannot allocate fds for pty"); -- if (tmp1 > 0) -+ if (tmp1 >= 0) - close(tmp1); -- if (tmp2 > 0) -- close(tmp2); -+ /*DEAD CODE if (tmp2 >= 0) -+ close(tmp2);*/ - return 0; - } - close(tmp1); diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c --- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/openbsd-compat/bindresvport.c 2016-12-23 16:40:26.901788691 +0100 @@ -234,23 +183,6 @@ diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c goto out; } free(arg2); -diff -up openssh-8.7p1/scp.c.coverity openssh-8.7p1/scp.c ---- openssh-8.7p1/scp.c.coverity 2021-08-30 16:23:35.389741329 +0200 -+++ openssh-8.7p1/scp.c 2021-08-30 16:27:04.854555296 +0200 -@@ -186,11 +186,11 @@ killchild(int signo) - { - if (do_cmd_pid > 1) { - kill(do_cmd_pid, signo ? signo : SIGTERM); -- waitpid(do_cmd_pid, NULL, 0); -+ (void) waitpid(do_cmd_pid, NULL, 0); - } - if (do_cmd_pid2 > 1) { - kill(do_cmd_pid2, signo ? signo : SIGTERM); -- waitpid(do_cmd_pid2, NULL, 0); -+ (void) waitpid(do_cmd_pid2, NULL, 0); - } - - if (signo) diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.coverity 2016-12-23 16:40:26.896788690 +0100 +++ openssh-7.4p1/servconf.c 2016-12-23 16:40:26.901788691 +0100 @@ -278,18 +210,6 @@ diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != (int)tun) goto done; -diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c ---- openssh-7.4p1/sftp.c.coverity 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sftp.c 2016-12-23 16:40:26.903788691 +0100 -@@ -224,7 +224,7 @@ killchild(int signo) - pid = sshpid; - if (pid > 1) { - kill(pid, SIGTERM); -- waitpid(pid, NULL, 0); -+ (void) waitpid(pid, NULL, 0); - } - - _exit(1); diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c --- openssh-7.4p1/ssh-agent.c.coverity 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/ssh-agent.c 2016-12-23 16:40:26.903788691 +0100 @@ -301,28 +221,6 @@ diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c return NULL; } /* validate also provider from URI */ -@@ -1220,8 +1220,8 @@ main(int ac, char **av) - sanitise_stdfd(); - - /* drop */ -- setegid(getgid()); -- setgid(getgid()); -+ (void) setegid(getgid()); -+ (void) setgid(getgid()); - - platform_disable_tracing(0); /* strict=no */ - -diff -up openssh-8.5p1/ssh.c.coverity openssh-8.5p1/ssh.c ---- openssh-8.5p1/ssh.c.coverity 2021-03-24 12:03:33.779968138 +0100 -+++ openssh-8.5p1/ssh.c 2021-03-24 12:03:33.786968187 +0100 -@@ -1746,6 +1746,7 @@ control_persist_detach(void) - close(muxserver_sock); - muxserver_sock = -1; - options.control_master = SSHCTL_MASTER_NO; -+ /* coverity[leaked_handle: FALSE]*/ - muxclient(options.control_path); - /* muxclient() doesn't return on success. */ - fatal("Failed to connect to new control master"); diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c --- openssh-7.4p1/sshd.c.coverity 2016-12-23 16:40:26.897788690 +0100 +++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100 diff --git a/openssh-7.2p2-x11.patch b/openssh-7.2p2-x11.patch index 0a19ecb2948796fe98a0dbdbbd516b0ebf69dd8b..b27d7c49ce2fcbcea3e06859c6712fc0cb4e9329 100644 --- a/openssh-7.2p2-x11.patch +++ b/openssh-7.2p2-x11.patch @@ -1,21 +1,23 @@ -diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c ---- openssh-7.2p2/channels.c.x11 2016-03-09 19:04:48.000000000 +0100 -+++ openssh-7.2p2/channels.c 2016-06-03 10:42:04.775164520 +0200 -@@ -3990,21 +3990,24 @@ x11_create_display_inet(int x11_display_ +diff --git a/channels.c b/channels.c +--- a/channels.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/channels.c (date 1703026069921) +@@ -5075,11 +5075,13 @@ } - + static int -connect_local_xsocket_path(const char *pathname) +connect_local_xsocket_path(const char *pathname, int len) { int sock; struct sockaddr_un addr; - -+ if (len <= 0) -+ return -1; + ++ if (len <= 0) ++ return -1; sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock == -1) + if (sock == -1) { error("socket: %.100s", strerror(errno)); +@@ -5087,11 +5089,12 @@ + } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); @@ -29,8 +31,8 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c - error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); return -1; } - -@@ -4012,8 +4015,18 @@ static int + +@@ -5099,8 +5102,18 @@ connect_local_xsocket(u_int dnr) { char buf[1024]; diff --git a/backport-openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch similarity index 50% rename from backport-openssh-7.7p1-fips.patch rename to openssh-7.7p1-fips.patch index fd8de20c6432cec10e75bc215370f870c57bc738..774c5da41f569d8502daf801d288bb8cbe21c862 100644 --- a/backport-openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,537 +1,678 @@ -From 94f3898f43a7ef0c53dd50c60ce6d6f884de28e1 Mon Sep 17 00:00:00 2001 -Date: Tue, 20 Aug 2024 20:17:01 +0800 -Subject: [PATCH] backport-openssh-7.7p1-fips - -Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/backport-openssh-7.7p1-fips.patch -Conflict:NA ---- - cipher-aes.c | 3 +- - dh.c | 41 +++++++++++++++++++++++++++ - dh.h | 1 + - kex.c | 6 +++- - kexgexc.c | 5 ++++ - myproposal.h | 33 ++++++++++++++++++++++ - readconf.c | 16 +++++++---- - sandbox-seccomp-filter.c | 3 ++ - servconf.c | 16 +++++++---- - ssh-keygen.c | 17 ++++++++++- - ssh-rsa.c | 3 ++ - ssh.c | 5 ++++ - sshconnect2.c | 61 ++++++++++++++++++++++------------------ - sshd.c | 19 ++++++++++--- - sshkey.c | 1 + - 15 files changed, 186 insertions(+), 44 deletions(-) - -diff --git a/cipher-aes.c b/cipher-aes.c -index 8b10172..1a07697 100644 ---- a/cipher-aes.c -+++ b/cipher-aes.c -@@ -154,7 +154,8 @@ evp_rijndael(void) - rijndal_cbc.do_cipher = ssh_rijndael_cbc; - #ifndef SSH_OLD_EVP - rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | -- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; -+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV | -+ EVP_CIPH_FLAG_FIPS; - #endif - return (&rijndal_cbc); - } -diff --git a/dh.c b/dh.c -index ce2eb47..166cb02 100644 ---- a/dh.c -+++ b/dh.c -@@ -36,6 +36,7 @@ - - #include - #include -+#include - - #include "dh.h" - #include "pathnames.h" -@@ -164,6 +165,12 @@ choose_dh(int min, int wantbits, int max) - int best, bestcount, which, linenum; - struct dhgroup dhg; - -+ if (FIPS_mode()) { -+ logit("Using arbitrary primes is not allowed in FIPS mode." -+ " Falling back to known groups."); -+ return (dh_new_group_fallback(max)); -+ } -+ - if ((f = fopen(get_moduli_filename(), "r")) == NULL) { - logit("WARNING: could not open %s (%s), using fixed modulus", - get_moduli_filename(), strerror(errno)); -@@ -502,4 +509,38 @@ dh_estimate(int bits) - return 8192; - } - -+/* -+ * Compares the received DH parameters with known-good groups, -+ * which might be either from group14, group16 or group18. -+ */ -+int -+dh_is_known_group(const DH *dh) -+{ -+ const BIGNUM *p, *g; -+ const BIGNUM *known_p, *known_g; -+ DH *known = NULL; -+ int bits = 0, rv = 0; -+ -+ DH_get0_pqg(dh, &p, NULL, &g); -+ bits = BN_num_bits(p); -+ -+ if (bits <= 3072) { -+ known = dh_new_group14(); -+ } else if (bits <= 6144) { -+ known = dh_new_group16(); -+ } else { -+ known = dh_new_group18(); -+ } -+ -+ DH_get0_pqg(known, &known_p, NULL, &known_g); -+ -+ if (BN_cmp(g, known_g) == 0 && -+ BN_cmp(p, known_p) == 0) { -+ rv = 1; -+ } -+ -+ DH_free(known); -+ return rv; -+} -+ - #endif /* WITH_OPENSSL */ -diff --git a/dh.h b/dh.h -index c6326a3..e51e292 100644 ---- a/dh.h -+++ b/dh.h -@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); - - int dh_gen_key(DH *, int); - int dh_pub_is_valid(const DH *, const BIGNUM *); -+int dh_is_known_group(const DH *); - - u_int dh_estimate(int); - void dh_set_moduli_file(const char *); -diff --git a/kex.c b/kex.c -index 36ae36c..1636f25 100644 ---- a/kex.c -+++ b/kex.c -@@ -40,6 +40,7 @@ - #ifdef WITH_OPENSSL - #include - #include -+#include - # ifdef HAVE_EVP_KDF_CTX_NEW_ID - # include - # endif -@@ -205,7 +206,10 @@ kex_names_valid(const char *names) - for ((p = strsep(&cp, ",")); p && *p != '\0'; - (p = strsep(&cp, ","))) { - if (kex_alg_by_name(p) == NULL) { -- error("Unsupported KEX algorithm \"%.100s\"", p); -+ if (FIPS_mode()) -+ error("\"%.100s\" is not allowed in FIPS mode", p); -+ else -+ error("Unsupported KEX algorithm \"%.100s\"", p); - free(s); - return 0; - } -diff --git a/kexgexc.c b/kexgexc.c -index e99e0cf..4c3feae 100644 ---- a/kexgexc.c -+++ b/kexgexc.c -@@ -28,6 +28,7 @@ - - #ifdef WITH_OPENSSL - -+#include - #include - - #include -@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh) - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -+ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) { -+ r = SSH_ERR_INVALID_ARGUMENT; -+ goto out; -+ } - p = g = NULL; /* belong to kex->dh now */ - - /* generate and send 'e', client DH public key */ -diff --git a/myproposal.h b/myproposal.h -index ee6e9f7..ff8dfa8 100644 ---- a/myproposal.h -+++ b/myproposal.h -@@ -56,6 +56,18 @@ - "rsa-sha2-512," \ - "rsa-sha2-256" - -+#define KEX_FIPS_PK_ALG \ -+ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ -+ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \ -+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ -+ "rsa-sha2-512-cert-v01@openssh.com," \ -+ "rsa-sha2-256-cert-v01@openssh.com," \ -+ "ecdsa-sha2-nistp256," \ -+ "ecdsa-sha2-nistp384," \ -+ "ecdsa-sha2-nistp521," \ -+ "rsa-sha2-512," \ -+ "rsa-sha2-256," \ -+ - #define KEX_SERVER_ENCRYPT \ - "chacha20-poly1305@openssh.com," \ - "aes128-ctr,aes192-ctr,aes256-ctr," \ -@@ -77,6 +89,27 @@ - - #define KEX_CLIENT_MAC KEX_SERVER_MAC - -+#define KEX_FIPS_ENCRYPT \ -+ "aes128-ctr,aes192-ctr,aes256-ctr," \ -+ "aes128-cbc,3des-cbc," \ -+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ -+ "aes128-gcm@openssh.com,aes256-gcm@openssh.com" -+#define KEX_DEFAULT_KEX_FIPS \ -+ "ecdh-sha2-nistp256," \ -+ "ecdh-sha2-nistp384," \ -+ "ecdh-sha2-nistp521," \ -+ "diffie-hellman-group-exchange-sha256," \ -+ "diffie-hellman-group16-sha512," \ -+ "diffie-hellman-group18-sha512," \ -+ "diffie-hellman-group14-sha256" -+#define KEX_FIPS_MAC \ -+ "hmac-sha1," \ -+ "hmac-sha2-256," \ -+ "hmac-sha2-512," \ -+ "hmac-sha1-etm@openssh.com," \ -+ "hmac-sha2-256-etm@openssh.com," \ -+ "hmac-sha2-512-etm@openssh.com" -+ - /* Not a KEX value, but here so all the algorithm defaults are together */ - #define SSH_ALLOWED_CA_SIGALGS \ - "ssh-ed25519," \ -diff --git a/readconf.c b/readconf.c -index bd8627c..dd22c3c 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -2711,11 +2712,16 @@ fill_default_options(Options * options) - all_key = sshkey_alg_list(0, 0, 1, ','); - all_sig = sshkey_alg_list(0, 1, 1, ','); - /* remove unsupported algos from default lists */ -- def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher); -- def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac); -- def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex); -- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); -- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); -+ def_cipher = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher); -+ def_mac = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac); -+ def_kex = match_filter_allowlist((FIPS_mode() ? -+ KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex); -+ def_key = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); -+ def_sig = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); - #define ASSEMBLE(what, defaults, all) \ - do { \ - if ((r = kex_assemble_names(&options->what, \ -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 139b6fb..5376800 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -230,6 +230,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_open - SC_DENY(__NR_open, EACCES), - #endif -+#ifdef __NR_socket -+ SC_DENY(__NR_socket, EACCES), -+#endif - #ifdef __NR_openat - SC_DENY(__NR_openat, EACCES), - #endif -diff --git a/servconf.c b/servconf.c -index 0dbf90c..24db0cc 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -26,6 +26,7 @@ - #ifdef HAVE_NET_ROUTE_H - #include - #endif -+#include - - #include - #include -@@ -230,11 +231,16 @@ assemble_algorithms(ServerOptions *o) - all_key = sshkey_alg_list(0, 0, 1, ','); - all_sig = sshkey_alg_list(0, 1, 1, ','); - /* remove unsupported algos from default lists */ -- def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher); -- def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac); -- def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex); -- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); -- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); -+ def_cipher = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher); -+ def_mac = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac); -+ def_kex = match_filter_allowlist((FIPS_mode() ? -+ KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex); -+ def_key = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); -+ def_sig = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); - #define ASSEMBLE(what, defaults, all) \ - do { \ - if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 46f4998..5c48ee0 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -23,6 +23,7 @@ - #include - #include "openbsd-compat/openssl-compat.h" - #endif -+#include - - #ifdef HAVE_STDINT_H - # include -@@ -207,6 +208,12 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) - #endif - } - #ifdef WITH_OPENSSL -+ if (FIPS_mode()) { -+ if (type == KEY_DSA) -+ fatal("DSA keys are not allowed in FIPS mode"); -+ if (type == KEY_ED25519) -+ fatal("ED25519 keys are not allowed in FIPS mode"); -+ } - switch (type) { - case KEY_DSA: - if (*bitsp != 1024) -@@ -1113,9 +1120,17 @@ do_gen_all_hostkeys(struct passwd *pw) - first = 1; - printf("%s: generating new host keys: ", __progname); - } -+ type = sshkey_type_from_name(key_types[i].key_type); -+ -+ /* Skip the keys that are not supported in FIPS mode */ -+ if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) { -+ logit("Skipping %s key in FIPS mode", -+ key_types[i].key_type_display); -+ goto next; -+ } -+ - printf("%s ", key_types[i].key_type_display); - fflush(stdout); -- type = sshkey_type_from_name(key_types[i].key_type); - if ((fd = mkstemp(prv_tmp)) == -1) { - error("Could not save your private key in %s: %s", - prv_tmp, strerror(errno)); -diff --git a/ssh-rsa.c b/ssh-rsa.c -index 88a98fd..17662be 100644 ---- a/ssh-rsa.c -+++ b/ssh-rsa.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -162,6 +163,8 @@ ssh_rsa_generate(struct sshkey *k, int bits) - goto out; - - if (EVP_PKEY_keygen(ctx, &res) <= 0) { -+ if (FIPS_mode()) -+ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -diff --git a/ssh.c b/ssh.c -index 4caa6e1..d144a25 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -77,6 +77,7 @@ - #include - #include - #endif -+#include - #include "openbsd-compat/openssl-compat.h" - #include "openbsd-compat/sys-queue.h" - -@@ -1564,6 +1565,10 @@ main(int ac, char **av) - exit(0); - } - -+ if (FIPS_mode()) { -+ debug("FIPS mode initialized"); -+ } -+ - /* Expand SecurityKeyProvider if it refers to an environment variable */ - if (options.sk_provider != NULL && *options.sk_provider == '$' && - strlen(options.sk_provider) > 1) { -diff --git a/sshconnect2.c b/sshconnect2.c -index 1e217e4..1d72a91 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -45,6 +45,8 @@ - #include - #endif - -+#include -+ - #include "openbsd-compat/sys-queue.h" - - #include "xmalloc.h" -@@ -276,36 +278,41 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - - #if defined(GSSAPI) && defined(WITH_OPENSSL) - if (options.gss_keyex) { -- /* Add the GSSAPI mechanisms currently supported on this -- * client to the key exchange algorithm proposal */ -- orig = myproposal[PROPOSAL_KEX_ALGS]; -- -- if (options.gss_server_identity) { -- gss_host = xstrdup(options.gss_server_identity); -- } else if (options.gss_trust_dns) { -- gss_host = remote_hostname(ssh); -- /* Fall back to specified host if we are using proxy command -- * and can not use DNS on that socket */ -- if (strcmp(gss_host, "UNKNOWN") == 0) { -- free(gss_host); -+ if (FIPS_mode()) { -+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); -+ options.gss_keyex = 0; -+ } else { -+ /* Add the GSSAPI mechanisms currently supported on this -+ * client to the key exchange algorithm proposal */ -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ -+ if (options.gss_server_identity) { -+ gss_host = xstrdup(options.gss_server_identity); -+ } else if (options.gss_trust_dns) { -+ gss_host = remote_hostname(ssh); -+ /* Fall back to specified host if we are using proxy command -+ * and can not use DNS on that socket */ -+ if (strcmp(gss_host, "UNKNOWN") == 0) { -+ free(gss_host); -+ gss_host = xstrdup(host); -+ } -+ } else { - gss_host = xstrdup(host); - } -- } else { -- gss_host = xstrdup(host); -- } - -- gss = ssh_gssapi_client_mechanisms(gss_host, -- options.gss_client_identity, options.gss_kex_algorithms); -- if (gss) { -- debug("Offering GSSAPI proposal: %s", gss); -- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -- "%s,%s", gss, orig); -- -- /* If we've got GSSAPI algorithms, then we also support the -- * 'null' hostkey, as a last resort */ -- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; -- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], -- "%s,null", orig); -+ gss = ssh_gssapi_client_mechanisms(gss_host, -+ options.gss_client_identity, options.gss_kex_algorithms); -+ if (gss) { -+ debug("Offering GSSAPI proposal: %s", gss); -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -+ "%s,%s", gss, orig); -+ -+ /* If we've got GSSAPI algorithms, then we also support the -+ * 'null' hostkey, as a last resort */ -+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], -+ "%s,null", orig); -+ } - } - } - #endif -diff --git a/sshd.c b/sshd.c -index 595e44a..f49e2e5 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -69,6 +69,7 @@ - #endif - #include - #include -+#include - #include - #include - #include -@@ -80,6 +81,7 @@ - #include - #include - #include -+#include - #include "openbsd-compat/openssl-compat.h" - #endif - -@@ -1665,6 +1667,7 @@ main(int ac, char **av) - sigemptyset(&sigmask); - sigprocmask(SIG_SETMASK, &sigmask, NULL); - -+ OpenSSL_add_all_algorithms(); - /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ - saved_argc = ac; - rexec_argc = ac; -@@ -2160,6 +2163,10 @@ main(int ac, char **av) - /* Reinitialize the log (because of the fork above). */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); - -+ if (FIPS_mode()) { -+ debug("FIPS mode initialized"); -+ } -+ - /* - * Chdir to the root directory so that the current disk can be - * unmounted if desired. -@@ -2535,10 +2542,14 @@ do_ssh2_kex(struct ssh *ssh) - if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) - orig = NULL; - -- if (options.gss_keyex) -- gss = ssh_gssapi_server_mechanisms(); -- else -- gss = NULL; -+ if (options.gss_keyex) { -+ if (FIPS_mode()) { -+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); -+ options.gss_keyex = 0; -+ } else { -+ gss = ssh_gssapi_server_mechanisms(); -+ } -+ } - - if (gss && orig) - xasprintf(&newstr, "%s,%s", gss, orig); -diff --git a/sshkey.c b/sshkey.c -index 1aee244..be2c399 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - #endif --- -2.33.0 - +diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c +--- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/dh.c 2021-05-06 12:12:10.107634472 +0200 +@@ -36,6 +36,7 @@ + + #include + #include ++#include + + #include "dh.h" + #include "pathnames.h" +@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max + int best, bestcount, which, linenum; + struct dhgroup dhg; + ++ if (FIPS_mode()) { ++ verbose("Using arbitrary primes is not allowed in FIPS mode." ++ " Falling back to known groups."); ++ return (dh_new_group_fallback(max)); ++ } ++ + if ((f = fopen(get_moduli_filename(), "r")) == NULL) { + logit("WARNING: could not open %s (%s), using fixed modulus", + get_moduli_filename(), strerror(errno)); +@@ -502,4 +508,38 @@ dh_estimate(int bits) + return 8192; + } + ++/* ++ * Compares the received DH parameters with known-good groups, ++ * which might be either from group14, group16 or group18. ++ */ ++int ++dh_is_known_group(const DH *dh) ++{ ++ const BIGNUM *p, *g; ++ const BIGNUM *known_p, *known_g; ++ DH *known = NULL; ++ int bits = 0, rv = 0; ++ ++ DH_get0_pqg(dh, &p, NULL, &g); ++ bits = BN_num_bits(p); ++ ++ if (bits <= 3072) { ++ known = dh_new_group14(); ++ } else if (bits <= 6144) { ++ known = dh_new_group16(); ++ } else { ++ known = dh_new_group18(); ++ } ++ ++ DH_get0_pqg(known, &known_p, NULL, &known_g); ++ ++ if (BN_cmp(g, known_g) == 0 && ++ BN_cmp(p, known_p) == 0) { ++ rv = 1; ++ } ++ ++ DH_free(known); ++ return rv; ++} ++ + #endif /* WITH_OPENSSL */ +diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h +--- openssh-8.6p1/dh.h.fips 2021-05-06 12:08:36.498926877 +0200 ++++ openssh-8.6p1/dh.h 2021-05-06 12:11:28.393298005 +0200 +@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); + + int dh_gen_key(DH *, int); + int dh_pub_is_valid(const DH *, const BIGNUM *); ++int dh_is_known_group(const DH *); + + u_int dh_estimate(int); + void dh_set_moduli_file(const char *); +diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c +--- openssh-8.6p1/kex.c.fips 2021-05-06 12:08:36.489926807 +0200 ++++ openssh-8.6p1/kex.c 2021-05-06 12:08:36.498926877 +0200 +@@ -39,6 +39,7 @@ + + #ifdef WITH_OPENSSL + #include ++#include + #include + # ifdef HAVE_EVP_KDF_CTX_NEW_ID + # include +@@ -203,7 +203,10 @@ kex_names_valid(const char *names) + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + if (kex_alg_by_name(p) == NULL) { +- error("Unsupported KEX algorithm \"%.100s\"", p); ++ if (FIPS_mode()) ++ error("\"%.100s\" is not allowed in FIPS mode", p); ++ else ++ error("Unsupported KEX algorithm \"%.100s\"", p); + free(s); + return 0; + } +diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c +--- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/kexgexc.c 2021-05-06 12:08:36.498926877 +0200 +@@ -28,6 +28,7 @@ + + #ifdef WITH_OPENSSL + ++#include + #include + + #include +@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32 + r = SSH_ERR_ALLOC_FAIL; + goto out; + } ++ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) { ++ r = SSH_ERR_INVALID_ARGUMENT; ++ goto out; ++ } + p = g = NULL; /* belong to kex->dh now */ + + /* generate and send 'e', client DH public key */ +diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h +--- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200 +@@ -57,6 +57,18 @@ + "rsa-sha2-512," \ + "rsa-sha2-256" + ++#define KEX_FIPS_PK_ALG \ ++ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ ++ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \ ++ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ ++ "rsa-sha2-512-cert-v01@openssh.com," \ ++ "rsa-sha2-256-cert-v01@openssh.com," \ ++ "ecdsa-sha2-nistp256," \ ++ "ecdsa-sha2-nistp384," \ ++ "ecdsa-sha2-nistp521," \ ++ "rsa-sha2-512," \ ++ "rsa-sha2-256" ++ + #define KEX_SERVER_ENCRYPT \ + "chacha20-poly1305@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ +@@ -78,6 +92,27 @@ + + #define KEX_CLIENT_MAC KEX_SERVER_MAC + ++#define KEX_FIPS_ENCRYPT \ ++ "aes128-ctr,aes192-ctr,aes256-ctr," \ ++ "aes128-cbc,3des-cbc," \ ++ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ ++ "aes128-gcm@openssh.com,aes256-gcm@openssh.com" ++#define KEX_DEFAULT_KEX_FIPS \ ++ "ecdh-sha2-nistp256," \ ++ "ecdh-sha2-nistp384," \ ++ "ecdh-sha2-nistp521," \ ++ "diffie-hellman-group-exchange-sha256," \ ++ "diffie-hellman-group16-sha512," \ ++ "diffie-hellman-group18-sha512," \ ++ "diffie-hellman-group14-sha256" ++#define KEX_FIPS_MAC \ ++ "hmac-sha1," \ ++ "hmac-sha2-256," \ ++ "hmac-sha2-512," \ ++ "hmac-sha1-etm@openssh.com," \ ++ "hmac-sha2-256-etm@openssh.com," \ ++ "hmac-sha2-512-etm@openssh.com" ++ + /* Not a KEX value, but here so all the algorithm defaults are together */ + #define SSH_ALLOWED_CA_SIGALGS \ + "ssh-ed25519," \ +diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c +--- openssh-8.6p1/readconf.c.fips 2021-05-06 12:08:36.428926336 +0200 ++++ openssh-8.6p1/readconf.c 2021-05-06 12:08:36.499926885 +0200 +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #ifdef USE_SYSTEM_GLOB + # include + #else +@@ -2538,11 +2538,16 @@ fill_default_options(Options * options) + all_key = sshkey_alg_list(0, 0, 1, ','); + all_sig = sshkey_alg_list(0, 1, 1, ','); + /* remove unsupported algos from default lists */ +- def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher); +- def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac); +- def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex); +- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); +- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); ++ def_cipher = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher); ++ def_mac = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac); ++ def_kex = match_filter_allowlist((FIPS_mode() ? ++ KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex); ++ def_key = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); ++ def_sig = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); + #define ASSEMBLE(what, defaults, all) \ + do { \ + if ((r = kex_assemble_names(&options->what, \ +diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c +--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-05-06 12:08:36.463926606 +0200 ++++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-06 12:08:36.499926885 +0200 +@@ -160,6 +160,9 @@ static const struct sock_filter preauth_ + #ifdef __NR_open + SC_DENY(__NR_open, EACCES), + #endif ++#ifdef __NR_socket ++ SC_DENY(__NR_socket, EACCES), ++#endif + #ifdef __NR_openat + SC_DENY(__NR_openat, EACCES), + #endif +diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.fips 2021-05-06 12:08:36.455926545 +0200 ++++ openssh-8.6p1/servconf.c 2021-05-06 12:08:36.500926893 +0200 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #ifdef HAVE_UTIL_H + #include + #endif +@@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o) + all_key = sshkey_alg_list(0, 0, 1, ','); + all_sig = sshkey_alg_list(0, 1, 1, ','); + /* remove unsupported algos from default lists */ +- def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher); +- def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac); +- def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex); +- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); +- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); ++ def_cipher = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher); ++ def_mac = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac); ++ def_kex = match_filter_allowlist((FIPS_mode() ? ++ KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex); ++ def_key = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); ++ def_sig = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); + #define ASSEMBLE(what, defaults, all) \ + do { \ + if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ +diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c +--- openssh-8.6p1/ssh.c.fips 2021-05-06 12:08:36.467926637 +0200 ++++ openssh-8.6p1/ssh.c 2021-05-06 12:08:36.500926893 +0200 +@@ -77,6 +77,7 @@ + #include + #include + #endif ++#include + #include "openbsd-compat/openssl-compat.h" + #include "openbsd-compat/sys-queue.h" + +@@ -1516,6 +1517,10 @@ main(int ac, char **av) + exit(0); + } + ++ if (FIPS_mode()) { ++ debug("FIPS mode initialized"); ++ } ++ + /* Expand SecurityKeyProvider if it refers to an environment variable */ + if (options.sk_provider != NULL && *options.sk_provider == '$' && + strlen(options.sk_provider) > 1) { +diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c +--- openssh-8.6p1/sshconnect2.c.fips 2021-05-06 12:08:36.485926777 +0200 ++++ openssh-8.6p1/sshconnect2.c 2021-05-06 12:08:36.501926900 +0200 +@@ -45,6 +45,8 @@ + #include + #endif + ++#include ++ + #include "openbsd-compat/sys-queue.h" + + #include "xmalloc.h" +@@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st + + #if defined(GSSAPI) && defined(WITH_OPENSSL) + if (options.gss_keyex) { +- /* Add the GSSAPI mechanisms currently supported on this +- * client to the key exchange algorithm proposal */ +- orig = myproposal[PROPOSAL_KEX_ALGS]; +- +- if (options.gss_server_identity) { +- gss_host = xstrdup(options.gss_server_identity); +- } else if (options.gss_trust_dns) { +- gss_host = remote_hostname(ssh); +- /* Fall back to specified host if we are using proxy command +- * and can not use DNS on that socket */ +- if (strcmp(gss_host, "UNKNOWN") == 0) { +- free(gss_host); ++ if (FIPS_mode()) { ++ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); ++ options.gss_keyex = 0; ++ } else { ++ /* Add the GSSAPI mechanisms currently supported on this ++ * client to the key exchange algorithm proposal */ ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ ++ if (options.gss_server_identity) { ++ gss_host = xstrdup(options.gss_server_identity); ++ } else if (options.gss_trust_dns) { ++ gss_host = remote_hostname(ssh); ++ /* Fall back to specified host if we are using proxy command ++ * and can not use DNS on that socket */ ++ if (strcmp(gss_host, "UNKNOWN") == 0) { ++ free(gss_host); ++ gss_host = xstrdup(host); ++ } ++ } else { + gss_host = xstrdup(host); + } +- } else { +- gss_host = xstrdup(host); +- } + +- gss = ssh_gssapi_client_mechanisms(gss_host, +- options.gss_client_identity, options.gss_kex_algorithms); +- if (gss) { +- debug("Offering GSSAPI proposal: %s", gss); +- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], +- "%s,%s", gss, orig); +- +- /* If we've got GSSAPI algorithms, then we also support the +- * 'null' hostkey, as a last resort */ +- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; +- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], +- "%s,null", orig); ++ gss = ssh_gssapi_client_mechanisms(gss_host, ++ options.gss_client_identity, options.gss_kex_algorithms); ++ if (gss) { ++ debug("Offering GSSAPI proposal: %s", gss); ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ ++ /* If we've got GSSAPI algorithms, then we also support the ++ * 'null' hostkey, as a last resort */ ++ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], ++ "%s,null", orig); ++ } + } + } + #endif +diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.fips 2021-05-06 12:08:36.493926838 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-06 12:13:56.501492639 +0200 +@@ -66,6 +66,7 @@ + #endif + #include + #include ++#include + #include + #include + #include +@@ -77,6 +78,7 @@ + #include + #include + #include ++#include + #include "openbsd-compat/openssl-compat.h" + #endif + +@@ -1931,6 +1931,13 @@ main(int ac, char **av) + &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) + do_log2_r(r, ll, "Unable to load host key \"%s\"", + options.host_key_files[i]); ++ if (FIPS_mode() && key != NULL && (sshkey_type_plain(key->type) == KEY_ED25519_SK ++ || sshkey_type_plain(key->type) == KEY_ED25519)) { ++ logit_f("sshd: Ed25519 keys are not allowed in FIPS mode, skipping %s", options.host_key_files[i]); ++ sshkey_free(key); ++ key = NULL; ++ continue; ++ } + if (sshkey_is_sk(key) && + key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { + debug("host key %s requires user presence, ignoring", +@@ -2110,6 +2113,10 @@ main(int ac, char **av) + /* Reinitialize the log (because of the fork above). */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + ++ if (FIPS_mode()) { ++ debug("FIPS mode initialized"); ++ } ++ + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. +@@ -2494,10 +2501,14 @@ do_ssh2_kex(struct ssh *ssh) + if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) + orig = NULL; + +- if (options.gss_keyex) +- gss = ssh_gssapi_server_mechanisms(); +- else +- gss = NULL; ++ if (options.gss_keyex) { ++ if (FIPS_mode()) { ++ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); ++ options.gss_keyex = 0; ++ } else { ++ gss = ssh_gssapi_server_mechanisms(); ++ } ++ } + + if (gss && orig) + xasprintf(&newstr, "%s,%s", gss, orig); +diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c +--- openssh-8.6p1/sshkey.c.fips 2021-05-06 12:08:36.493926838 +0200 ++++ openssh-8.6p1/sshkey.c 2021-05-06 12:08:36.502926908 +0200 +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #endif + + #include "crypto_api.h" +@@ -57,6 +58,7 @@ + #define SSHKEY_INTERNAL + #include "sshkey.h" + #include "match.h" ++#include "log.h" + #include "ssh-sk.h" + + #ifdef WITH_XMSS +@@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai + impl = keyimpls[i]; + if (impl->name == NULL || impl->type == KEY_NULL) + continue; ++ if (FIPS_mode()) { ++ switch (impl->type) { ++ case KEY_ED25519: ++ case KEY_ED25519_SK: ++ case KEY_ED25519_CERT: ++ case KEY_ED25519_SK_CERT: ++ continue; ++ break; ++ default: ++ break; ++ } ++ } + if (!include_sigonly && impl->sigonly) + continue; + if ((certs_only && !impl->cert) || (plain_only && impl->cert)) +@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c + return SSH_ERR_EC_CURVE_MISMATCH; + } + ++ switch (type) { ++ case KEY_ED25519: ++ case KEY_ED25519_SK: ++ case KEY_ED25519_CERT: ++ case KEY_ED25519_SK_CERT: ++ if (FIPS_mode()) { ++ sshkey_free(k); ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++ break; ++ default: ++ break; ++ } + /* Fill in ret from parsed key */ + sshkey_free_contents(ret); + *ret = *k; +@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key, + *lenp = 0; + if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) + return SSH_ERR_INVALID_ARGUMENT; ++ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++ /* Fallthrough */ + if ((impl = sshkey_impl_from_key(key)) == NULL) + return SSH_ERR_KEY_TYPE_UNKNOWN; + if ((r = sshkey_unshield_private(key)) != 0) +@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key, + *detailsp = NULL; + if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) + return SSH_ERR_INVALID_ARGUMENT; ++ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } + if ((impl = sshkey_impl_from_key(key)) == NULL) + return SSH_ERR_KEY_TYPE_UNKNOWN; + return impl->funcs->verify(key, sig, siglen, data, dlen, +diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c +--- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200 ++++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200 +@@ -20,6 +20,7 @@ + + #ifdef WITH_OPENSSL + #include ++#include + #include + #include "openbsd-compat/openssl-compat.h" + #endif +@@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na + #endif + } + #ifdef WITH_OPENSSL ++ if (FIPS_mode()) { ++ if (type == KEY_DSA) ++ fatal("DSA keys are not allowed in FIPS mode"); ++ if (type == KEY_ED25519 || type == KEY_ED25519_SK) ++ fatal("ED25519 keys are not allowed in FIPS mode"); ++ } + switch (type) { + case KEY_DSA: + if (*bitsp != 1024) +@@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw) + first = 1; + printf("%s: generating new host keys: ", __progname); + } ++ type = sshkey_type_from_name(key_types[i].key_type); ++ ++ /* Skip the keys that are not supported in FIPS mode */ ++ if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) { ++ logit("Skipping %s key in FIPS mode", ++ key_types[i].key_type_display); ++ goto next; ++ } ++ + printf("%s ", key_types[i].key_type_display); + fflush(stdout); +- type = sshkey_type_from_name(key_types[i].key_type); + if ((fd = mkstemp(prv_tmp)) == -1) { + error("Could not save your private key in %s: %s", + prv_tmp, strerror(errno)); +diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c +--- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 ++++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1705,6 +1707,8 @@ ssh_rsa_generate(u_int bits, RSA + goto out; + + if (EVP_PKEY_keygen(ctx, &res) <= 0) { ++ if (FIPS_mode()) ++ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c +--- openssh-8.7p1/kexgen.c.fips3 2022-07-11 16:11:21.973519913 +0200 ++++ openssh-8.7p1/kexgen.c 2022-07-11 16:25:31.172187365 +0200 +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "sshkey.h" + #include "kex.h" +@@ -115,10 +116,20 @@ kex_gen_client(struct ssh *ssh) + break; + #endif + case KEX_C25519_SHA256: +- r = kex_c25519_keypair(kex); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type c25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_c25519_keypair(kex); ++ } + break; + case KEX_KEM_SNTRUP761X25519_SHA512: +- r = kex_kem_sntrup761x25519_keypair(kex); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_kem_sntrup761x25519_keypair(kex); ++ } + break; + default: + r = SSH_ERR_INVALID_ARGUMENT; +@@ -186,11 +197,21 @@ input_kex_gen_reply(int type, u_int32_t + break; + #endif + case KEX_C25519_SHA256: +- r = kex_c25519_dec(kex, server_blob, &shared_secret); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type c25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_c25519_dec(kex, server_blob, &shared_secret); ++ } + break; + case KEX_KEM_SNTRUP761X25519_SHA512: +- r = kex_kem_sntrup761x25519_dec(kex, server_blob, +- &shared_secret); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_kem_sntrup761x25519_dec(kex, server_blob, ++ &shared_secret); ++ } + break; + default: + r = SSH_ERR_INVALID_ARGUMENT; +@@ -285,12 +306,22 @@ input_kex_gen_init(int type, u_int32_t s + break; + #endif + case KEX_C25519_SHA256: +- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, +- &shared_secret); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type c25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, ++ &shared_secret); ++ } + break; + case KEX_KEM_SNTRUP761X25519_SHA512: +- r = kex_kem_sntrup761x25519_enc(kex, client_pubkey, +- &server_pubkey, &shared_secret); ++ if (FIPS_mode()) { ++ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey, ++ &server_pubkey, &shared_secret); ++ } + break; + default: + r = SSH_ERR_INVALID_ARGUMENT; +diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c +--- openssh-8.7p1/ssh-ed25519.c.fips3 2022-07-11 16:53:41.428343304 +0200 ++++ openssh-8.7p1/ssh-ed25519.c 2022-07-11 16:56:09.284663661 +0200 +@@ -24,6 +24,7 @@ + + #include + #include ++#include + + #include "log.h" + #include "sshbuf.h" +@@ -52,6 +53,10 @@ ssh_ed25519_sign(const struct sshkey *ke + key->ed25519_sk == NULL || + datalen >= INT_MAX - crypto_sign_ed25519_BYTES) + return SSH_ERR_INVALID_ARGUMENT; ++ if (FIPS_mode()) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } + smlen = slen = datalen + crypto_sign_ed25519_BYTES; + if ((sig = malloc(slen)) == NULL) + return SSH_ERR_ALLOC_FAIL; +@@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey * + dlen >= INT_MAX - crypto_sign_ed25519_BYTES || + sig == NULL || siglen == 0) + return SSH_ERR_INVALID_ARGUMENT; ++ if (FIPS_mode()) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } + + if ((b = sshbuf_from(sig, siglen)) == NULL) + return SSH_ERR_ALLOC_FAIL; diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 4dc460a530f46109d540e3a586d4b329c6ef420e..347766dcd49c1c88925b71cf9a918a59975c024a 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -23,7 +23,7 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c if ((style = strchr(user, ':')) != NULL) *style++ = 0; -@@ -296,8 +304,15 @@ input_userauth_request(int type, u_int32 +@@ -314,8 +314,15 @@ input_userauth_request(int type, u_int32 use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; @@ -34,12 +34,12 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c + if (use_privsep) { mm_inform_authserv(service, style); +#ifdef WITH_SELINUX -+ mm_inform_authrole(role); ++ mm_inform_authrole(role); +#endif -+ } ++ } userauth_banner(ssh); - if (auth2_setup_methods_lists(authctxt) != 0) - ssh_packet_disconnect(ssh, + if ((r = kex_server_update_ext_info(ssh)) != 0) + fatal_fr(r, "kex_server_update_ext_info failed"); diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c --- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200 +++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200 diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index f3e3f5292de2d42fc6f2dc3b3050906b0382e30b..d64c1fff7c95db502658f17fe56e115ba30615db 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -144,8 +144,8 @@ index 9351e042..d6446c0c 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ - /* $OpenBSD: auth2-gss.c,v 1.33 2021/12/19 22:12:07 djm Exp $ */ - + /* $OpenBSD: auth2-gss.c,v 1.34 2023/03/31 04:22:27 djm Exp $ */ + /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. @@ -160,7 +160,7 @@ index 9351e042..d6446c0c 100644 + * The 'gssapi_keyex' userauth mechanism. + */ +static int -+userauth_gsskeyex(struct ssh *ssh) ++userauth_gsskeyex(struct ssh *ssh, const char *method) +{ + Authctxt *authctxt = ssh->authctxt; + int r, authenticated = 0; @@ -221,19 +221,20 @@ index 9351e042..d6446c0c 100644 else logit("GSSAPI MIC check failed"); -@@ -326,6 +370,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -326,6 +370,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) return 0; } +Authmethod method_gsskeyex = { + "gssapi-keyex", ++ NULL, + userauth_gsskeyex, + &options.gss_authentication +}; + Authmethod method_gssapi = { "gssapi-with-mic", - NULL, + NULL, diff --git a/auth2.c b/auth2.c index 0e776224..1c217268 100644 --- a/auth2.c @@ -400,8 +401,8 @@ index ebd0dbca..1bdac6a4 100644 +#endif + /* Buffer input from the connection. */ - if (conn_in_ready) - client_process_net_input(ssh); + if (conn_in_ready) + client_process_net_input(ssh); diff --git a/configure.ac b/configure.ac index b689db4b..efafb6bd 100644 --- a/configure.ac @@ -1252,7 +1253,7 @@ index ab3a15f0..6ce56e92 100644 + + return ok; } - + /* Privileged */ diff --git a/kex.c b/kex.c index ce85f043..574c7609 100644 @@ -1267,7 +1268,7 @@ index ce85f043..574c7609 100644 +#endif + /* prototype */ - static int kex_choose_conf(struct ssh *); + static int kex_choose_conf(struct ssh *, uint32_t seq); static int kex_input_newkeys(int, u_int32_t, struct ssh *); @@ -115,15 +120,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ @@ -1368,8 +1369,8 @@ index ce85f043..574c7609 100644 +#ifdef GSSAPI + free(kex->gss_host); +#endif /* GSSAPI */ - sshbuf_free(kex->initial_sig); - sshkey_free(kex->initial_hostkey); + sshbuf_free(kex->initial_sig); + sshkey_free(kex->initial_hostkey); free(kex->failed_choice); diff --git a/kex.h b/kex.h index a5ae6ac0..fe714141 100644 @@ -1487,7 +1488,7 @@ new file mode 100644 index 00000000..f6e1405e --- /dev/null +++ b/kexgssc.c -@@ -0,0 +1,600 @@ +@@ -0,0 +1,612 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1588,8 +1589,10 @@ index 00000000..f6e1405e + default: + fatal_f("Unexpected KEX type %d", kex->kex_type); + } -+ if (r != 0) ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&ctxt); + return r; ++ } + + token_ptr = GSS_C_NO_BUFFER; + @@ -1652,11 +1655,16 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ u_char *tmp = NULL; ++ size_t tmp_len = 0; ++ + debug("Received KEXGSS_HOSTKEY"); + if (server_host_key_blob) + fatal("Server host key received more than once"); -+ if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) ++ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) + fatal("Failed to read server host key: %s", ssh_err(r)); ++ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) ++ fatal("sshbuf_from failed"); + } + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); + @@ -1943,11 +1951,16 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ u_char *tmp = NULL; ++ size_t tmp_len = 0; ++ + debug("Received KEXGSS_HOSTKEY"); + if (server_host_key_blob) + fatal("Server host key received more than once"); -+ if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) ++ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); ++ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) ++ fatal("sshbuf_from failed"); + } + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); + @@ -2093,7 +2106,7 @@ new file mode 100644 index 00000000..60bc02de --- /dev/null +++ b/kexgsss.c -@@ -0,0 +1,474 @@ +@@ -0,0 +1,482 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -2160,7 +2173,7 @@ index 00000000..60bc02de + */ + + OM_uint32 ret_flags = 0; -+ gss_buffer_desc gssbuf, recv_tok, msg_tok; ++ gss_buffer_desc gssbuf = {0, NULL}, recv_tok, msg_tok; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + Gssctxt *ctxt = NULL; + struct sshbuf *shared_secret = NULL; @@ -2200,7 +2213,7 @@ index 00000000..60bc02de + type = ssh_packet_read(ssh); + switch(type) { + case SSH2_MSG_KEXGSS_INIT: -+ if (client_pubkey != NULL) ++ if (gssbuf.value != NULL) + fatal("Received KEXGSS_INIT after initialising"); + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, + &recv_tok)) != 0 || @@ -2231,6 +2244,31 @@ index 00000000..60bc02de + goto out; + + /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ ++ /* Calculate the hash early so we can free the ++ * client_pubkey, which has reference to the parent ++ * buffer state->incoming_packet ++ */ ++ hashlen = sizeof(hash); ++ if ((r = kex_gen_hash( ++ kex->hash_alg, ++ kex->client_version, ++ kex->server_version, ++ kex->peer, ++ kex->my, ++ empty, ++ client_pubkey, ++ server_pubkey, ++ shared_secret, ++ hash, &hashlen)) != 0) ++ goto out; ++ ++ gssbuf.value = hash; ++ gssbuf.length = hashlen; ++ ++ sshbuf_free(client_pubkey); ++ client_pubkey = NULL; ++ + break; + case SSH2_MSG_KEXGSS_CONTINUE: + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, @@ -2252,7 +2290,7 @@ index 00000000..60bc02de + if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) + fatal("Zero length token output when incomplete"); + -+ if (client_pubkey == NULL) ++ if (gssbuf.value == NULL) + fatal("No client public key"); + + if (maj_status & GSS_S_CONTINUE_NEEDED) { @@ -2281,23 +2319,6 @@ index 00000000..60bc02de + if (!(ret_flags & GSS_C_INTEG_FLAG)) + fatal("Integrity flag wasn't set"); + -+ hashlen = sizeof(hash); -+ if ((r = kex_gen_hash( -+ kex->hash_alg, -+ kex->client_version, -+ kex->server_version, -+ kex->peer, -+ kex->my, -+ empty, -+ client_pubkey, -+ server_pubkey, -+ shared_secret, -+ hash, &hashlen)) != 0) -+ goto out; -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ + if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) + fatal("Couldn't get MIC"); + @@ -3379,7 +3400,7 @@ index 60de6087..db5c65bc 100644 .It HashKnownHosts .It Host .It HostbasedAcceptedAlgorithms -@@ -579,6 +585,8 @@ flag), +@@ -624,6 +624,8 @@ (supported message integrity codes), .Ar kex (key exchange algorithms), @@ -3387,7 +3408,7 @@ index 60de6087..db5c65bc 100644 +(GSSAPI key exchange algorithms), .Ar key (key types), - .Ar key-cert + .Ar key-ca-sign diff --git a/ssh.c b/ssh.c index 15aee569..110cf9c1 100644 --- a/ssh.c @@ -3423,7 +3444,7 @@ index 5e8ef548..1ff999b6 100644 +# GSSAPIKeyExchange no +# GSSAPITrustDNS no # BatchMode no - # CheckHostIP yes + # CheckHostIP no # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 index 06a32d31..3f490697 100644 @@ -3584,7 +3605,7 @@ index af00fb30..03bc87eb 100644 +# endif +#endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; - ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; + ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; ssh->kex->verify_host_key=&verify_host_key_callback; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -4007,3 +4028,48 @@ index 71a3fddc..37a43a67 100644 KEY_UNSPEC }; +diff --git a/packet.h b/packet.h +--- a/packet.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/packet.h (date 1703172586447) +@@ -124,6 +124,7 @@ + int ssh_packet_send2(struct ssh *); + + int ssh_packet_read(struct ssh *); ++int ssh_packet_read_expect(struct ssh *, u_int type); + int ssh_packet_read_poll(struct ssh *); + int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); + int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); +diff --git a/packet.c b/packet.c +--- a/packet.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/packet.c (date 1703172586447) +@@ -1425,6 +1416,29 @@ + return type; + } + ++/* ++ * Waits until a packet has been received, verifies that its type matches ++ * that given, and gives a fatal error and exits if there is a mismatch. ++ */ ++ ++int ++ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) ++{ ++ int r; ++ u_char type; ++ ++ if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) ++ return r; ++ if (type != expected_type) { ++ if ((r = sshpkt_disconnect(ssh, ++ "Protocol error: expected packet type %d, got %d", ++ expected_type, type)) != 0) ++ return r; ++ return SSH_ERR_PROTOCOL_ERROR; ++ } ++ return 0; ++} ++ + static int + ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) + { + diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 979f9d230742da604f6c23224b47e3a2a7aa558a..1e7940d7294babf8d354b0af762ec802b3864f2c 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,7 +1,7 @@ -diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac ---- openssh-8.7p1/configure.ac.pkcs11-uri 2021-08-30 13:07:43.646699953 +0200 -+++ openssh-8.7p1/configure.ac 2021-08-30 13:07:43.662700088 +0200 -@@ -1985,12 +1985,14 @@ AC_LINK_IFELSE( +diff -up openssh-9.6p1/configure.ac.pkcs11-uri openssh-9.6p1/configure.ac +--- openssh-9.6p1/configure.ac.pkcs11-uri 2024-01-12 14:25:25.228942213 +0100 ++++ openssh-9.6p1/configure.ac 2024-01-12 14:25:25.233942336 +0100 +@@ -2066,12 +2066,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -16,7 +16,7 @@ diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac fi ] ) -@@ -2019,6 +2021,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2095,6 +2097,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -57,7 +57,7 @@ diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5624,6 +5660,7 @@ echo " BSD Auth support +@@ -5708,6 +5744,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -65,10 +65,10 @@ diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac echo " U2F/FIDO support: $enable_sk" echo "" -diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in ---- openssh-8.7p1/Makefile.in.pkcs11-uri 2021-08-30 13:07:43.571699324 +0200 -+++ openssh-8.7p1/Makefile.in 2021-08-30 13:07:43.663700096 +0200 -@@ -103,7 +103,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +diff -up openssh-9.6p1/Makefile.in.pkcs11-uri openssh-9.6p1/Makefile.in +--- openssh-9.6p1/Makefile.in.pkcs11-uri 2024-01-12 14:25:25.204941622 +0100 ++++ openssh-9.6p1/Makefile.in 2024-01-12 14:25:25.233942336 +0100 +@@ -105,7 +105,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ ssh-ed25519-sk.o ssh-rsa.o dh.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ @@ -77,7 +77,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ hmac.o ed25519.o hash.o \ -@@ -302,6 +302,8 @@ clean: regressclean +@@ -299,6 +299,8 @@ clean: regressclean rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8$(EXEEXT) @@ -86,15 +86,15 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -339,6 +341,8 @@ distclean: regressclean +@@ -336,6 +338,8 @@ distclean: regressclean rm -f regress/unittests/sshsig/test_sshsig rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 + rm -f regress/unittests/pkcs11/*.o + rm -f regress/unittests/pkcs11/test_pkcs11 - rm -f regress/misc/sk-dummy/*.o - rm -f regress/misc/sk-dummy/*.lo - rm -f regress/misc/sk-dummy/sk-dummy.so + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so @@ -513,6 +517,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshkey $(MKDIR_P) `pwd`/regress/unittests/sshsig @@ -103,7 +103,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in $(MKDIR_P) `pwd`/regress/misc/sk-dummy [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -677,6 +682,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT +@@ -685,6 +690,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) @@ -120,7 +120,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in # These all need to be compiled -fPIC, so they are treated differently. SK_DUMMY_OBJS=\ regress/misc/sk-dummy/sk-dummy.lo \ -@@ -711,7 +726,8 @@ regress-unit-binaries: regress-prep $(RE +@@ -720,7 +735,8 @@ regress-unit-binaries: regress-prep $(RE regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ regress/unittests/sshkey/test_sshkey$(EXEEXT) \ regress/unittests/sshsig/test_sshsig$(EXEEXT) \ @@ -128,24 +128,12 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in + regress/unittests/utf8/test_utf8$(EXEEXT) \ + regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - tests: file-tests t-exec interop-tests unit + tests: file-tests t-exec interop-tests extra-tests unit echo all tests passed -diff -up openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/agent-pkcs11.sh ---- openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/regress/agent-pkcs11.sh 2021-08-30 13:07:43.663700096 +0200 -@@ -113,7 +113,7 @@ else - done - - trace "remove pkcs11 keys" -- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 -+ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -e failed: exit code $r" -diff -up openssh-8.7p1/regress/Makefile.pkcs11-uri openssh-8.7p1/regress/Makefile ---- openssh-8.7p1/regress/Makefile.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/regress/Makefile 2021-08-30 13:07:43.663700096 +0200 -@@ -122,7 +122,8 @@ CLEANFILES= *.core actual agent-key.* au +diff -up openssh-9.6p1/regress/Makefile.pkcs11-uri openssh-9.6p1/regress/Makefile +--- openssh-9.6p1/regress/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/regress/Makefile 2024-01-12 14:25:25.233942336 +0100 +@@ -134,7 +134,8 @@ CLEANFILES= *.core actual agent-key.* au known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -155,7 +143,7 @@ diff -up openssh-8.7p1/regress/Makefile.pkcs11-uri openssh-8.7p1/regress/Makefil rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ -@@ -252,8 +253,9 @@ unit: +@@ -273,8 +274,9 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -167,9 +155,9 @@ diff -up openssh-8.7p1/regress/Makefile.pkcs11-uri openssh-8.7p1/regress/Makefil -d ${.CURDIR}/unittests/sshkey/testdata ; \ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ -d ${.CURDIR}/unittests/sshsig/testdata ; \ -diff -up openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/pkcs11.sh ---- openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri 2021-08-30 13:07:43.663700096 +0200 -+++ openssh-8.7p1/regress/pkcs11.sh 2021-08-30 13:07:43.663700096 +0200 +diff -up openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri openssh-9.6p1/regress/pkcs11.sh +--- openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 ++++ openssh-9.6p1/regress/pkcs11.sh 2024-01-12 14:25:25.233942336 +0100 @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -520,21 +508,21 @@ diff -up openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/pkcs11 + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -diff -up openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri openssh-8.7p1/regress/unittests/Makefile ---- openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/regress/unittests/Makefile 2021-08-30 13:07:43.663700096 +0200 -@@ -2,6 +2,6 @@ +diff -up openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri openssh-9.6p1/regress/unittests/Makefile +--- openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/regress/unittests/Makefile 2024-01-12 14:25:25.233942336 +0100 +@@ -1,6 +1,6 @@ + # $OpenBSD: Makefile,v 1.13 2023/09/24 08:14:13 claudio Exp $ - REGRESS_FAIL_EARLY?= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion -SUBDIR+=authopt misc sshsig +SUBDIR+=authopt misc sshsig pkcs11 .include -diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1/regress/unittests/pkcs11/tests.c ---- openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-08-30 13:07:43.664700104 +0200 -+++ openssh-8.7p1/regress/unittests/pkcs11/tests.c 2021-08-30 13:07:43.664700104 +0200 -@@ -0,0 +1,337 @@ +diff -up openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-9.6p1/regress/unittests/pkcs11/tests.c +--- openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 ++++ openssh-9.6p1/regress/unittests/pkcs11/tests.c 2024-01-12 14:25:25.233942336 +0100 +@@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -563,7 +551,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +#include "sshbuf.h" +#include "ssh-pkcs11-uri.h" + -+#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL) ++#define EMPTY_URI compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) + +/* prototypes are not public -- specify them here internally for tests */ +struct sshbuf *percent_encode(const char *, size_t, char *); @@ -596,6 +584,10 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + ASSERT_STRING_EQ(a->lib_manuf, b->lib_manuf); + else /* both should be null */ + ASSERT_PTR_EQ(a->lib_manuf, b->lib_manuf); ++ if (b->serial != NULL) ++ ASSERT_STRING_EQ(a->serial, b->serial); ++ else /* both should be null */ ++ ASSERT_PTR_EQ(a->serial, b->serial); +} + +void @@ -630,7 +622,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + +struct pkcs11_uri * +compose_uri(unsigned char *id, size_t id_len, char *token, char *lib_manuf, -+ char *manuf, char *module_path, char *object, char *pin) ++ char *manuf, char *serial, char *module_path, char *object, char *pin) +{ + struct pkcs11_uri *uri = pkcs11_uri_init(); + if (id_len > 0) { @@ -641,6 +633,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + uri->token = token; + uri->lib_manuf = lib_manuf; + uri->manuf = manuf; ++ uri->serial = serial; + uri->object = object; + uri->pin = pin; + return uri; @@ -651,47 +644,49 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +{ + /* path arguments */ + check_parse("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:token=SSH%20Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL, NULL)); + check_parse("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL, NULL)); ++ check_parse("pkcs11:serial=IamSerial", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "IamSerial", NULL, NULL, NULL)); + check_parse("pkcs11:object=SIGN%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "SIGN Key", NULL)); + /* query arguments */ + check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_parse("pkcs11:?pin-value=123456", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "123456")); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, "123456")); + + /* combinations */ + /* ID SHOULD be percent encoded */ + check_parse("pkcs11:token=SSH%20Key;id=0", -+ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("0", 1, "SSH Key", NULL, NULL, NULL, NULL, NULL, NULL)); + check_parse( + "pkcs11:manufacturer=CAC?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, "CAC", ++ compose_uri(NULL, 0, NULL, NULL, "CAC", NULL, + "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_parse( + "pkcs11:object=RSA%20Key?module-path=/usr/lib64/pkcs11/opencryptoki.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, + "/usr/lib64/pkcs11/opencryptoki.so", "RSA Key", NULL)); + check_parse("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so&pin-value=123456", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, "123456")); + + /* empty path component matches everything */ + check_parse("pkcs11:", EMPTY_URI); + + /* empty string is a valid to match against (and different from NULL) */ + check_parse("pkcs11:token=", -+ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "", NULL, NULL, NULL, NULL, NULL, NULL)); + /* Percent character needs to be percent-encoded */ + check_parse("pkcs11:token=%25", -+ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "%", NULL, NULL, NULL, NULL, NULL, NULL)); +} + +static void @@ -703,7 +698,7 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + check_parse_rv("pkcs11:id=%ZZ", EMPTY_URI, -1); + /* Space MUST be percent encoded -- XXX not enforced yet */ + check_parse("pkcs11:token=SSH Keys", -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + /* MUST NOT contain duplicate attributes of the same name */ + check_parse_rv("pkcs11:id=%01;id=%02", EMPTY_URI, -1); + /* MUST NOT contain duplicate attributes of the same name */ @@ -734,29 +729,31 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 +{ + /* path arguments */ + check_gen("pkcs11:id=%01", -+ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x01", 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:id=%00%01", -+ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x00\x01", 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:token=SSH%20Keys", /* space must be percent encoded */ -+ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri(NULL, 0, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + /* library-manufacturer is not implmented now */ + /*check_gen("pkcs11:library-manufacturer=OpenSC", -+ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL));*/ ++ compose_uri(NULL, 0, NULL, "OpenSC", NULL, NULL, NULL, NULL, NULL));*/ + check_gen("pkcs11:manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, NULL, NULL)); ++ check_gen("pkcs11:serial=IamSerial", ++ compose_uri(NULL, 0, NULL, NULL, NULL, "IamSerial", NULL, NULL, NULL)); + check_gen("pkcs11:object=RSA%20Key", -+ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "RSA Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, NULL, "RSA Key", NULL)); + /* query arguments */ + check_gen("pkcs11:?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri(NULL, 0, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri(NULL, 0, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + + /* combinations */ + check_gen("pkcs11:id=%02;token=SSH%20Keys", -+ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL)); ++ compose_uri("\x02", 1, "SSH Keys", NULL, NULL, NULL, NULL, NULL, NULL)); + check_gen("pkcs11:id=%EE%02?module-path=/usr/lib64/p11-kit-proxy.so", -+ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); ++ compose_uri("\xEE\x02", 2, NULL, NULL, NULL, NULL, "/usr/lib64/p11-kit-proxy.so", NULL, NULL)); + check_gen("pkcs11:object=Encryption%20Key;manufacturer=piv_II", -+ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, "Encryption Key", NULL)); ++ compose_uri(NULL, 0, NULL, NULL, "piv_II", NULL, NULL, "Encryption Key", NULL)); + + /* empty path component matches everything */ + check_gen("pkcs11:", EMPTY_URI); @@ -872,10 +869,10 @@ diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1 + test_parse_invalid(); + test_generate_valid(); +} -diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c ---- openssh-8.7p1/ssh-add.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-add.c 2021-08-30 13:07:43.664700104 +0200 -@@ -68,6 +68,7 @@ +diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c +--- openssh-9.6p1/ssh-add.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-add.c 2024-01-12 14:25:25.233942336 +0100 +@@ -69,6 +69,7 @@ #include "ssh-sk.h" #include "sk-api.h" #include "hostfile.h" @@ -883,12 +880,16 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c /* argv0 */ extern char *__progname; -@@ -229,6 +230,34 @@ delete_all(int agent_fd, int qflag) +@@ -240,6 +241,38 @@ delete_all(int agent_fd, int qflag) return ret; } +#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *, int, struct dest_constraint **, size_t, char *); ++static int ++update_card(int agent_fd, int add, const char *id, int qflag, ++ int key_only, int cert_only, ++ struct dest_constraint **dest_constraints, size_t ndest_constraints, ++ struct sshkey **certs, size_t ncerts, char *pin); + +int +update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag, @@ -910,32 +911,35 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c + } + pkcs11_uri_cleanup(uri); + -+ return update_card(agent_fd, adding, pkcs11_uri, qflag, -+ dest_constraints, ndest_constraints, pin); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag, 1, 0, ++ dest_constraints, ndest_constraints, NULL, 0, pin); +} +#endif + static int - add_file(int agent_fd, const char *filename, int key_only, int qflag, - const char *skprovider, struct dest_constraint **dest_constraints, -@@ -445,12 +472,11 @@ add_file(int agent_fd, const char *filen - - static int + add_file(int agent_fd, const char *filename, int key_only, int cert_only, + int qflag, const char *skprovider, +@@ -460,15 +489,14 @@ static int update_card(int agent_fd, int add, const char *id, int qflag, -- struct dest_constraint **dest_constraints, size_t ndest_constraints) -+ struct dest_constraint **dest_constraints, size_t ndest_constraints, char *pin) + int key_only, int cert_only, + struct dest_constraint **dest_constraints, size_t ndest_constraints, +- struct sshkey **certs, size_t ncerts) ++ struct sshkey **certs, size_t ncerts, char *pin) { - char *pin = NULL; int r, ret = -1; + if (key_only) + ncerts = 0; + - if (add) { + if (add && pin == NULL) { if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -630,6 +656,14 @@ static int - const char *skprovider, struct dest_constraint **dest_constraints, - size_t ndest_constraints) +@@ -656,6 +684,14 @@ do_file(int agent_fd, int deleting, int + char *file, int qflag, const char *skprovider, + struct dest_constraint **dest_constraints, size_t ndest_constraints) { +#ifdef ENABLE_PKCS11 + if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && @@ -946,21 +950,21 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c + } +#endif if (deleting) { - if (delete_file(agent_fd, file, key_only, qflag) == -1) - return -1; -@@ -813,7 +846,7 @@ main(int argc, char **argv) - } - if (pkcs11provider != NULL) { + if (delete_file(agent_fd, file, key_only, + cert_only, qflag) == -1) +@@ -999,7 +1035,7 @@ main(int argc, char **argv) if (update_card(agent_fd, !deleting, pkcs11provider, -- qflag, dest_constraints, ndest_constraints) == -1) -+ qflag, dest_constraints, ndest_constraints, NULL) == -1) + qflag, key_only, cert_only, + dest_constraints, ndest_constraints, +- certs, ncerts) == -1) ++ certs, ncerts, NULL) == -1) ret = 1; goto done; } -diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c ---- openssh-8.7p1/ssh-agent.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-agent.c 2021-08-30 13:07:43.664700104 +0200 -@@ -847,10 +847,72 @@ no_identities(SocketEntry *e) +diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c +--- openssh-9.6p1/ssh-agent.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-agent.c 2024-01-12 14:25:25.234942360 +0100 +@@ -1549,10 +1549,72 @@ add_p11_identity(struct sshkey *key, cha } #ifdef ENABLE_PKCS11 @@ -1034,25 +1038,23 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; -@@ -869,33 +931,28 @@ process_add_smartcard_key(SocketEntry *e +@@ -1581,25 +1643,18 @@ process_add_smartcard_key(SocketEntry *e "providers is disabled", provider); goto send; } - if (realpath(provider, canonical_provider) == NULL) { - verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", - provider, strerror(errno)); -- goto send; ++ sane_uri = sanitize_pkcs11_provider(provider); ++ if (sane_uri == NULL) + goto send; - } - if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { - verbose("refusing PKCS#11 add of \"%.100s\": " - "provider not allowed", canonical_provider); -+ -+ sane_uri = sanitize_pkcs11_provider(provider); -+ if (sane_uri == NULL) - goto send; +- goto send; - } - debug_f("add %.100s", canonical_provider); -+ if (lifetime && !death) death = monotime() + lifetime; @@ -1060,31 +1062,38 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c + debug_f("add %.100s", sane_uri); + count = pkcs11_add_provider(sane_uri, pin, &keys, &comments); for (i = 0; i < count; i++) { - k = keys[i]; - if (lookup_identity(k) == NULL) { - id = xcalloc(1, sizeof(Identity)); - id->key = k; - keys[i] = NULL; /* transferred */ -- id->provider = xstrdup(canonical_provider); -+ id->provider = xstrdup(sane_uri); - if (*comments[i] != '\0') { - id->comment = comments[i]; - comments[i] = NULL; /* transferred */ - } else { -- id->comment = xstrdup(canonical_provider); -+ id->comment = xstrdup(sane_uri); - } - id->death = death; - id->confirm = confirm; -@@ -910,6 +967,7 @@ process_add_smartcard_key(SocketEntry *e + if (comments[i] == NULL || comments[i][0] == '\0') { + free(comments[i]); +- comments[i] = xstrdup(canonical_provider); ++ comments[i] = xstrdup(sane_uri); + } + for (j = 0; j < ncerts; j++) { + if (!sshkey_is_cert(certs[j])) +@@ -1609,13 +1664,13 @@ process_add_smartcard_key(SocketEntry *e + if (pkcs11_make_cert(keys[i], certs[j], &k) != 0) + continue; + add_p11_identity(k, xstrdup(comments[i]), +- canonical_provider, death, confirm, ++ sane_uri, death, confirm, + dest_constraints, ndest_constraints); + success = 1; + } + if (!cert_only && lookup_identity(keys[i]) == NULL) { + add_p11_identity(keys[i], comments[i], +- canonical_provider, death, confirm, ++ sane_uri, death, confirm, + dest_constraints, ndest_constraints); + keys[i] = NULL; /* transferred */ + comments[i] = NULL; /* transferred */ +@@ -1628,6 +1683,7 @@ process_add_smartcard_key(SocketEntry *e send: free(pin); free(provider); + free(sane_uri); free(keys); free(comments); - free_dest_constraints(dest_constraints, ndest_constraints); -@@ -918,7 +976,7 @@ send: + free_dest_constraints(dest_constraints, ndest_constraints); +@@ -1640,7 +1696,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1093,7 +1102,7 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c int r, success = 0; Identity *id, *nxt; -@@ -930,30 +988,29 @@ process_remove_smartcard_key(SocketEntry +@@ -1652,30 +1708,29 @@ process_remove_smartcard_key(SocketEntry } free(pin); @@ -1130,10 +1139,10 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff -up openssh-8.7p1/ssh_config.5.pkcs11-uri openssh-8.7p1/ssh_config.5 ---- openssh-8.7p1/ssh_config.5.pkcs11-uri 2021-08-30 13:07:43.578699383 +0200 -+++ openssh-8.7p1/ssh_config.5 2021-08-30 13:07:43.664700104 +0200 -@@ -1111,6 +1111,21 @@ may also be used in conjunction with +diff -up openssh-9.6p1/ssh_config.5.pkcs11-uri openssh-9.6p1/ssh_config.5 +--- openssh-9.6p1/ssh_config.5.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 ++++ openssh-9.6p1/ssh_config.5 2024-01-12 14:25:25.234942360 +0100 +@@ -1216,6 +1216,21 @@ may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. @@ -1155,10 +1164,10 @@ diff -up openssh-8.7p1/ssh_config.5.pkcs11-uri openssh-8.7p1/ssh_config.5 .It Cm IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. -diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c ---- openssh-8.7p1/ssh.c.pkcs11-uri 2021-08-30 13:07:43.578699383 +0200 -+++ openssh-8.7p1/ssh.c 2021-08-30 13:07:43.666700121 +0200 -@@ -826,6 +826,14 @@ main(int ac, char **av) +diff -up openssh-9.6p1/ssh.c.pkcs11-uri openssh-9.6p1/ssh.c +--- openssh-9.6p1/ssh.c.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 ++++ openssh-9.6p1/ssh.c 2024-01-12 14:25:25.234942360 +0100 +@@ -882,6 +882,14 @@ main(int ac, char **av) options.gss_deleg_creds = 1; break; case 'i': @@ -1173,7 +1182,7 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c p = tilde_expand_filename(optarg, getuid()); if (stat(p, &st) == -1) fprintf(stderr, "Warning: Identity file %s " -@@ -1681,6 +1689,7 @@ main(int ac, char **av) +@@ -1784,6 +1792,7 @@ main(int ac, char **av) #ifdef ENABLE_PKCS11 (void)pkcs11_del_provider(options.pkcs11_provider); #endif @@ -1181,7 +1190,7 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c skip_connect: exit_status = ssh_session2(ssh, cinfo); -@@ -2197,6 +2206,45 @@ ssh_session2(struct ssh *ssh, const stru +@@ -2307,6 +2316,45 @@ ssh_session2(struct ssh *ssh, const stru options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -1227,7 +1236,7 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2211,11 +2259,6 @@ load_public_identity_files(const struct +@@ -2321,11 +2369,6 @@ load_public_identity_files(const struct char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; @@ -1239,7 +1248,7 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2228,33 +2271,46 @@ load_public_identity_files(const struct +@@ -2338,33 +2381,46 @@ load_public_identity_files(const struct sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -1305,10 +1314,10 @@ diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c filename = default_client_percent_dollar_expand(cp, cinfo); free(cp); check_load(sshkey_load_public(filename, &public, NULL), -diff -up openssh-8.7p1/ssh-keygen.c.pkcs11-uri openssh-8.7p1/ssh-keygen.c ---- openssh-8.7p1/ssh-keygen.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-keygen.c 2021-08-30 13:07:43.666700121 +0200 -@@ -860,8 +860,11 @@ do_download(struct passwd *pw) +diff -up openssh-9.6p1/ssh-keygen.c.pkcs11-uri openssh-9.6p1/ssh-keygen.c +--- openssh-9.6p1/ssh-keygen.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-keygen.c 2024-01-12 14:25:25.234942360 +0100 +@@ -862,8 +862,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1322,19 +1331,19 @@ diff -up openssh-8.7p1/ssh-keygen.c.pkcs11-uri openssh-8.7p1/ssh-keygen.c } free(comments[i]); sshkey_free(keys[i]); -diff -up openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-client.c ---- openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-pkcs11-client.c 2021-08-30 13:07:43.666700121 +0200 -@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pi - u_int nkeys, i; +diff -up openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-client.c +--- openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11-client.c 2024-01-12 14:25:25.234942360 +0100 +@@ -592,6 +592,8 @@ pkcs11_add_provider(char *name, char *pi struct sshbuf *msg; + struct helper *helper; + debug_f("called, name = %s", name); + - if (fd < 0 && pkcs11_start_helper() < 0) - return (-1); - -@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pi + if ((helper = helper_by_provider(name)) == NULL && + (helper = pkcs11_start_helper(name)) == NULL) + return -1; +@@ -612,6 +614,7 @@ pkcs11_add_provider(char *name, char *pi *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); @@ -1342,9 +1351,9 @@ diff -up openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-c for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c ---- openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-pkcs11.c 2021-08-30 13:12:27.709084157 +0200 +diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c +--- openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11.c 2024-01-12 14:28:09.170975480 +0100 @@ -55,8 +55,8 @@ struct pkcs11_slotinfo { int logged_in; }; @@ -1528,10 +1537,10 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c struct pkcs11_provider *p; + int rv = -1; + char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug3_f("called with provider %s", provider_uri); - if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3_f("called with provider %s", provider_uri); -+ + if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { TAILQ_REMOVE(&pkcs11_providers, p, next); pkcs11_provider_finalize(p); @@ -1545,7 +1554,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c } static RSA_METHOD *rsa_method; -@@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; +@@ -195,6 +286,56 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ @@ -1587,6 +1596,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + uri.module_path = k11->provider->module->module_path; + uri.lib_manuf = k11->provider->module->info.manufacturerID; + uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ uri.serial = k11->provider->module->slotinfo[k11->slotidx].token.serialNumber; + + p = pkcs11_uri_get(&uri); + /* do not cleanup -- we do not allocate here, only reference */ @@ -1601,7 +1611,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c /* release a wrapped object */ static void pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +348,7 @@ pkcs11_k11_free(void *parent, void *ptr, +@@ -208,6 +349,7 @@ pkcs11_k11_free(void *parent, void *ptr, if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); @@ -1609,7 +1619,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c free(k11); } -@@ -222,8 +363,8 @@ pkcs11_find(struct pkcs11_provider *p, C +@@ -222,8 +364,8 @@ pkcs11_find(struct pkcs11_provider *p, C CK_RV rv; int ret = -1; @@ -1620,9 +1630,12 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -262,12 +403,12 @@ pkcs11_login_slot(struct pkcs11_provider +@@ -260,14 +402,14 @@ pkcs11_login_slot(struct pkcs11_provider + if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) + verbose("Deferring PIN entry to reader keypad."); else { - snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", +- snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", ++ snprintf(prompt, sizeof(prompt), "Enter PIN for '%.32s': ", si->token.label); - if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { + if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { @@ -1635,7 +1648,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c (pin != NULL) ? strlen(pin) : 0); if (pin != NULL) freezero(pin, strlen(pin)); -@@ -297,13 +438,14 @@ pkcs11_login_slot(struct pkcs11_provider +@@ -297,13 +439,14 @@ pkcs11_login_slot(struct pkcs11_provider static int pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) { @@ -1652,7 +1665,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c } -@@ -319,13 +461,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs +@@ -319,13 +462,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs *val = 0; @@ -1670,7 +1683,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c attr.type = type; attr.pValue = &flag; -@@ -356,13 +499,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C +@@ -356,13 +500,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C int always_auth = 0; int did_login = 0; @@ -1688,7 +1701,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -439,8 +583,8 @@ pkcs11_rsa_private_encrypt(int flen, con +@@ -439,8 +584,8 @@ pkcs11_rsa_private_encrypt(int flen, con return (-1); } @@ -1699,7 +1712,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c tlen = RSA_size(rsa); /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -484,7 +628,7 @@ pkcs11_rsa_start_wrapper(void) +@@ -484,7 +629,7 @@ pkcs11_rsa_start_wrapper(void) /* redirect private key operations for rsa key to pkcs11 token */ static int pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1708,7 +1721,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c { struct pkcs11_key *k11; -@@ -502,6 +646,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * +@@ -502,6 +647,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -1721,7 +1734,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c RSA_set_method(rsa, rsa_method); RSA_set_ex_data(rsa, rsa_idx, k11); return (0); -@@ -532,8 +682,8 @@ ecdsa_do_sign(const unsigned char *dgst, +@@ -532,8 +683,8 @@ ecdsa_do_sign(const unsigned char *dgst, return (NULL); } @@ -1732,7 +1745,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c siglen = ECDSA_size(ec); sig = xmalloc(siglen); -@@ -598,7 +748,7 @@ pkcs11_ecdsa_start_wrapper(void) +@@ -598,7 +749,7 @@ pkcs11_ecdsa_start_wrapper(void) static int pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1741,10 +1754,10 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c { struct pkcs11_key *k11; -@@ -614,6 +764,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider +@@ -615,6 +766,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - } + } + if (label_attrib->ulValueLen > 0 ) { + k11->label = xmalloc(label_attrib->ulValueLen+1); + memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); @@ -1754,7 +1767,17 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c EC_KEY_set_method(ec, ec_key_method); EC_KEY_set_ex_data(ec, ec_key_idx, k11); -@@ -650,8 +806,8 @@ pkcs11_open_session(struct pkcs11_provid +@@ -622,7 +779,8 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider + } + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + +-/* remove trailing spaces */ ++/* remove trailing spaces. Note, that this does NOT guarantee the buffer ++ * will be null terminated if there are no trailing spaces! */ + static char * + rmspace(u_char *buf, size_t len) + { +@@ -654,8 +812,8 @@ pkcs11_open_session(struct pkcs11_provid CK_SESSION_HANDLE session; int login_required, ret; @@ -1765,7 +1788,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c login_required = si->token.flags & CKF_LOGIN_REQUIRED; -@@ -661,9 +817,9 @@ pkcs11_open_session(struct pkcs11_provid +@@ -665,9 +823,9 @@ pkcs11_open_session(struct pkcs11_provid error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -1777,7 +1800,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c return (-1); } if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -699,7 +855,8 @@ static struct sshkey * +@@ -703,7 +861,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1787,7 +1810,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -713,14 +870,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -717,14 +876,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -1808,7 +1831,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -731,19 +889,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -735,19 +895,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -1832,7 +1855,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -755,8 +913,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -759,8 +919,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1843,7 +1866,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (group == NULL) { ossl_error("d2i_ECPKParameters failed"); goto fail; -@@ -767,13 +925,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -771,13 +931,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1860,7 +1883,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (octet == NULL) { ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; -@@ -790,7 +948,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -794,7 +954,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1869,7 +1892,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -806,7 +964,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ +@@ -810,7 +970,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ ec = NULL; /* now owned by key */ fail: @@ -1878,7 +1901,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c free(key_attr[i].pValue); if (ec) EC_KEY_free(ec); -@@ -823,7 +981,8 @@ static struct sshkey * +@@ -827,7 +987,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1888,7 +1911,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -834,14 +993,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -838,14 +999,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -1909,7 +1932,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -852,19 +1012,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -856,19 +1018,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -1933,7 +1956,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -876,8 +1036,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -880,8 +1042,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr goto fail; } @@ -1944,7 +1967,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rsa_n == NULL || rsa_e == NULL) { error("BN_bin2bn failed"); goto fail; -@@ -886,7 +1046,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -890,7 +1052,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ @@ -1953,7 +1976,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -901,7 +1061,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr +@@ -905,7 +1067,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr rsa = NULL; /* now owned by key */ fail: @@ -1962,7 +1985,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c free(key_attr[i].pValue); RSA_free(rsa); -@@ -912,7 +1072,8 @@ static int +@@ -916,7 +1078,8 @@ static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) { @@ -1972,7 +1995,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -936,14 +1097,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -940,14 +1103,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -1993,7 +2016,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return -1; -@@ -955,18 +1117,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -959,18 +1123,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2016,7 +2039,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto out; -@@ -980,8 +1143,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -984,8 +1149,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p subject = xstrdup("invalid subject"); X509_NAME_free(x509_name); @@ -2027,7 +2050,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c error("d2i_x509 failed"); goto out; } -@@ -1001,7 +1164,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1005,7 +1170,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2036,7 +2059,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1031,7 +1194,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1035,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2045,7 +2068,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1051,7 +1214,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p +@@ -1055,7 +1220,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } out: @@ -2054,7 +2077,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1102,11 +1265,12 @@ note_key(struct pkcs11_provider *p, CK_U +@@ -1106,11 +1271,12 @@ note_key(struct pkcs11_provider *p, CK_U */ static int pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2069,7 +2092,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1123,10 +1287,23 @@ pkcs11_fetch_certs(struct pkcs11_provide +@@ -1127,10 +1293,23 @@ pkcs11_fetch_certs(struct pkcs11_provide key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2087,16 +2110,16 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - rv = f->C_FindObjectsInit(session, key_attr, 1); ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1207,11 +1384,12 @@ fail: +@@ -1211,11 +1390,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2111,7 +2134,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1227,10 +1405,23 @@ pkcs11_fetch_keys(struct pkcs11_provider +@@ -1231,10 +1411,23 @@ pkcs11_fetch_keys(struct pkcs11_provider key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2129,16 +2152,16 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } - -- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ + session = p->module->slotinfo[slotidx].session; + f = p->module->function_list; -+ + +- rv = f->C_FindObjectsInit(session, key_attr, 1); + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1499,16 +1690,10 @@ pkcs11_ecdsa_generate_private_key(struct +@@ -1503,16 +1696,10 @@ pkcs11_ecdsa_generate_private_key(struct } #endif /* WITH_PKCS11_KEYGEN */ @@ -2157,7 +2180,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1517,162 +1702,296 @@ pkcs11_register_provider(char *provider_ +@@ -1521,162 +1708,309 @@ pkcs11_register_provider(char *provider_ CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2165,28 +2188,35 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + struct pkcs11_module *m = NULL; - if (providerp == NULL) +- goto fail; +- *providerp = NULL; +- +- if (keyp != NULL) +- *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; + /* if no provider specified, fallback to p11-kit */ + if (uri->module_path == NULL) { +#ifdef PKCS11_DEFAULT_PROVIDER + provider_module = strdup(PKCS11_DEFAULT_PROVIDER); +#else + error_f("No module path provided"); - goto fail; -- *providerp = NULL; ++ goto fail; +#endif + } else { + provider_module = strdup(uri->module_path); + } - -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; + p = xcalloc(1, sizeof(*p)); + p->name = pkcs11_uri_get(uri); - if (pkcs11_provider_lookup(provider_id) != NULL) { - debug_f("provider already registered: %s", provider_id); ++ if (lib_contains_symbol(provider_module, "C_GetFunctionList") != 0) { ++ error("provider %s is not a PKCS11 library", provider_module); + goto fail; + } +- if (lib_contains_symbol(provider_id, "C_GetFunctionList") != 0) { +- error("provider %s is not a PKCS11 library", provider_id); - goto fail; + if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL + && m->valid) { @@ -2218,7 +2248,6 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c - p = xcalloc(1, sizeof(*p)); - p->name = xstrdup(provider_id); - p->handle = handle; -+ + p->module->handle = handle; /* setup the pkcs11 callbacks */ if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { @@ -2241,28 +2270,28 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c error("C_GetInfo for provider %s failed: %lu", - provider_id, rv); + provider_module, rv); -+ goto fail; -+ } -+ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); -+ if (uri->lib_manuf != NULL && -+ strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug_f("Skipping provider %s not matching library_manufacturer", -+ m->info.manufacturerID); goto fail; } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); - debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" - " libraryDescription <%s> libraryVersion %d.%d", +- debug("provider %s: manufacturerID <%.*s> cryptokiVersion %d.%d" +- " libraryDescription <%.*s> libraryVersion %d.%d", - provider_id, -- p->info.manufacturerID, +- RMSPACE(p->info.manufacturerID), - p->info.cryptokiVersion.major, - p->info.cryptokiVersion.minor, -- p->info.libraryDescription, +- RMSPACE(p->info.libraryDescription), - p->info.libraryVersion.major, - p->info.libraryVersion.minor); - if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strncmp(uri->lib_manuf, m->info.manufacturerID, 32)) { ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); ++ goto fail; ++ } ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); ++ debug("provider %s: manufacturerID <%.32s> cryptokiVersion %d.%d" ++ " libraryDescription <%.32s> libraryVersion %d.%d", + provider_module, + m->info.manufacturerID, + m->info.cryptokiVersion.major, @@ -2293,12 +2322,12 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c goto fail; } - p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); p->valid = 1; - nkeys = 0; - for (i = 0; i < p->nslots; i++) { - token = &p->slotinfo[i].token; - if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); + m->valid = 1; + for (i = 0; i < m->nslots; i++) { + token = &m->slotinfo[i].token; @@ -2315,20 +2344,25 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + token->flags = 0; continue; } - rmspace(token->label, sizeof(token->label)); - rmspace(token->manufacturerID, sizeof(token->manufacturerID)); - rmspace(token->model, sizeof(token->model)); - rmspace(token->serialNumber, sizeof(token->serialNumber)); + debug("provider %s slot %lu: label <%.*s> " + "manufacturerID <%.*s> model <%.*s> serial <%.*s> " + "flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_module, (unsigned long)i, + RMSPACE(token->label), RMSPACE(token->manufacturerID), + RMSPACE(token->model), RMSPACE(token->serialNumber), + token->flags); + } + m->module_path = provider_module; + provider_module = NULL; + -+ /* insert unconditionally -- remove if there will be no keys later */ ++ /* now owned by caller */ ++ *providerp = p; ++ + TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); + p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; + ++ return 0; +fail: + if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize for provider %s failed: %lu", @@ -2344,7 +2378,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + } + if (handle) + dlclose(handle); -+ return ret; ++ return (ret); +} + +/* @@ -2387,29 +2421,35 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + continue; + } + if (uri->token != NULL && -+ strcmp(token->label, uri->token) != 0) { -+ debug2_f("ignoring token not matching label (%s) " ++ strncmp(token->label, uri->token, 32) != 0) { ++ debug2_f("ignoring token not matching label (%.32s) " + "specified by PKCS#11 URI in slot %lu", + token->label, (unsigned long)i); + continue; + } + if (uri->manuf != NULL && -+ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ strncmp(token->manufacturerID, uri->manuf, 32) != 0) { + debug2_f("ignoring token not matching requrested " -+ "manufacturerID (%s) specified by PKCS#11 URI in " ++ "manufacturerID (%.32s) specified by PKCS#11 URI in " + "slot %lu", token->manufacturerID, (unsigned long)i); + continue; + } - debug("provider %s slot %lu: label <%s> manufacturerID <%s> " - "model <%s> serial <%s> flags 0x%lx", -- provider_id, (unsigned long)i, ++ if (uri->serial != NULL && ++ strncmp(token->serialNumber, uri->serial, 16) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "serialNumber (%s) specified by PKCS#11 URI in " ++ "slot %lu", token->serialNumber, (unsigned long)i); ++ continue; ++ } ++ debug("provider %s slot %lu: label <%.32s> manufacturerID <%.32s> " ++ "model <%.16s> serial <%.16s> flags 0x%lx", + provider_uri, (unsigned long)i, - token->label, token->manufacturerID, token->model, - token->serialNumber, token->flags); ++ token->label, token->manufacturerID, token->model, ++ token->serialNumber, token->flags); /* - * open session, login with pin and retrieve public - * keys (if keyp is provided) -+ * open session if not yet openend, login with pin and ++ * open session if not yet opened, login with pin and + * retrieve public keys (if keyp is provided) */ - if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || @@ -2441,7 +2481,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + } + if (nkeys == 0 && uri->object != NULL) { -+ debug3_f("No keys found. Retrying without label (%s) ", ++ debug3_f("No keys found. Retrying without label (%.32s) ", + uri->object); + /* Try once more without the label filter */ + char *label = uri->object; @@ -2470,8 +2510,8 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c - free(p->slotlist); - free(p->slotinfo); - free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); } - if (handle) - dlclose(handle); @@ -2529,7 +2569,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -1683,7 +2002,37 @@ pkcs11_add_provider(char *provider_id, c +@@ -1685,7 +2019,37 @@ pkcs11_add_provider(char *provider_id, c pkcs11_provider_unref(p); } if (nkeys == 0) @@ -2568,9 +2608,9 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c return (nkeys); } -diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h ---- openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/ssh-pkcs11.h 2021-08-30 13:07:43.666700121 +0200 +diff -up openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11.h +--- openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11.h 2024-01-12 14:25:25.235942385 +0100 @@ -22,10 +22,14 @@ #define SSH_PKCS11_ERR_PIN_REQUIRED 4 #define SSH_PKCS11_ERR_PIN_LOCKED 5 @@ -2586,10 +2626,10 @@ diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, -diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.c ---- openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 -+++ openssh-8.7p1/ssh-pkcs11-uri.c 2021-08-30 13:07:43.667700130 +0200 -@@ -0,0 +1,419 @@ +diff -up openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.c +--- openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 ++++ openssh-9.6p1/ssh-pkcs11-uri.c 2024-01-12 14:25:25.235942385 +0100 +@@ -0,0 +1,437 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -2632,13 +2672,14 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. +#define PKCS11_URI_OBJECT "object" +#define PKCS11_URI_LIB_MANUF "library-manufacturer" +#define PKCS11_URI_MANUF "manufacturer" ++#define PKCS11_URI_SERIAL "serial" +#define PKCS11_URI_MODULE_PATH "module-path" +#define PKCS11_URI_PIN_VALUE "pin-value" + +/* Keyword tokens. */ +typedef enum { -+ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, -+ pPinValue, pBadOption ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pSerial, ++ pModulePath, pPinValue, pBadOption +} pkcs11uriOpCodes; + +/* Textual representation of the tokens. */ @@ -2651,6 +2692,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + { PKCS11_URI_OBJECT, pObject }, + { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, + { PKCS11_URI_MANUF, pManufacturer }, ++ { PKCS11_URI_SERIAL, pSerial }, + { PKCS11_URI_MODULE_PATH, pModulePath }, + { PKCS11_URI_PIN_VALUE, pPinValue }, + { NULL, pBadOption } @@ -2809,6 +2851,16 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + goto err; + } + ++ /* Write serial */ ++ if (uri->serial) { ++ struct sshbuf *serial = percent_encode(uri->serial, ++ strlen(uri->serial), PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_SERIAL, serial); ++ if (path == NULL) ++ goto err; ++ } ++ + /* Write module_path */ + if (uri->module_path) { + struct sshbuf *module = percent_encode(uri->module_path, @@ -2851,6 +2903,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + free(pkcs11->object); + free(pkcs11->lib_manuf); + free(pkcs11->manuf); ++ free(pkcs11->serial); + if (pkcs11->pin) + freezero(pkcs11->pin, strlen(pkcs11->pin)); + free(pkcs11); @@ -2946,6 +2999,11 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + charptr = &pkcs11->manuf; + goto parse_string; + ++ case pSerial: ++ /* CK_TOKEN_INFO -> serialNumber */ ++ charptr = &pkcs11->serial; ++ goto parse_string; ++ + case pLibraryManufacturer: + /* CK_INFO -> manufacturerID */ + charptr = &pkcs11->lib_manuf; @@ -3009,10 +3067,10 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. +} + +#endif /* ENABLE_PKCS11 */ -diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.h ---- openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 -+++ openssh-8.7p1/ssh-pkcs11-uri.h 2021-08-30 13:07:43.667700130 +0200 -@@ -0,0 +1,42 @@ +diff -up openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.h +--- openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 ++++ openssh-9.6p1/ssh-pkcs11-uri.h 2024-01-12 14:25:25.235942385 +0100 +@@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -3044,6 +3102,7 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. + char *object; + char *lib_manuf; + char *manuf; ++ char *serial; + /* query */ + char *module_path; + char *pin; /* Only parsed, but not printed */ diff --git a/openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch index 2ed59a3e099b7db9599382b6875622862541db0c..479b55d526bc2e3410fc9a6e9c54b3e2afdc9e92 100644 --- a/openssh-8.7p1-minrsabits.patch +++ b/openssh-8.7p1-minrsabits.patch @@ -1,23 +1,21 @@ diff --git a/readconf.c b/readconf.c -index 7f26c680..42be690b 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -320,6 +320,7 @@ static struct { +--- a/readconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/readconf.c (date 1703169891147) +@@ -326,6 +326,7 @@ { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, - { "requiredrsasize", oRequiredRSASize }, + { "requiredrsasize", oRequiredRSASize }, + { "rsaminsize", oRequiredRSASize }, /* alias */ { "enableescapecommandline", oEnableEscapeCommandline }, - - { NULL, oBadOption } + { "obscurekeystroketiming", oObscureKeystrokeTiming }, + { "channeltimeout", oChannelTimeout }, diff --git a/servconf.c b/servconf.c -index 29df0463..423772b1 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -676,6 +680,7 @@ static struct { +--- a/servconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/servconf.c (date 1703169891148) +@@ -691,6 +691,7 @@ { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, - { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, + { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, + { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */ { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, diff --git a/openssh-8.7p1-recursive-scp.patch b/openssh-8.7p1-recursive-scp.patch index f0d9b0fed4898e8536615edeffe6a122aace88fc..17c340e088db27d5ccddb8288170840789522c49 100644 --- a/openssh-8.7p1-recursive-scp.patch +++ b/openssh-8.7p1-recursive-scp.patch @@ -1,28 +1,28 @@ -diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c ---- openssh-8.7p1/scp.c.scp-sftpdirs 2022-02-07 12:31:07.407740407 +0100 -+++ openssh-8.7p1/scp.c 2022-02-07 12:31:07.409740424 +0100 -@@ -1324,7 +1324,7 @@ source_sftp(int argc, char *src, char *t - +diff --git a/scp.c b/scp.c +--- a/scp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/scp.c (date 1703111453316) +@@ -1372,7 +1372,7 @@ + if (src_is_dir && iamrecursive) { - if (upload_dir(conn, src, abs_dst, pflag, + if (sftp_upload_dir(conn, src, abs_dst, pflag, - SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { + SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) { - error("failed to upload directory %s to %s", src, targ); - errs = 1; - } -diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c ---- openssh-8.7p1/sftp-client.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp-client.c 2022-02-07 12:47:59.117516131 +0100 -@@ -971,7 +971,7 @@ do_fsetstat(struct sftp_conn *conn, cons - + error("failed to upload directory %s to %s", src, targ); + errs = 1; + } +diff --git a/sftp-client.c b/sftp-client.c +--- a/sftp-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp-client.c (date 1703169614263) +@@ -1003,7 +1003,7 @@ + /* Implements both the realpath and expand-path operations */ static char * --do_realpath_expand(struct sftp_conn *conn, const char *path, int expand) -+do_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir) +-sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) ++sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir) { struct sshbuf *msg; u_int expected_id, count, id; -@@ -1033,11 +1033,43 @@ do_realpath_expand(struct sftp_conn *con +@@ -1049,11 +1049,43 @@ if ((r = sshbuf_get_u32(msg, &status)) != 0 || (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0) fatal_fr(r, "parse status"); @@ -33,7 +33,7 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c - return NULL; + if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) { + memset(&a, '\0', sizeof(a)); -+ if ((r = do_mkdir(conn, path, &a, 0)) != 0) { ++ if ((r = sftp_mkdir(conn, path, &a, 0)) != 0) { + sshbuf_free(msg); + return NULL; + } @@ -71,111 +71,112 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); -@@ -1039,9 +1067,9 @@ do_realpath_expand(struct sftp_conn *con +@@ -1078,9 +1110,9 @@ } - + char * --do_realpath(struct sftp_conn *conn, const char *path) -+do_realpath(struct sftp_conn *conn, const char *path, int create_dir) +-sftp_realpath(struct sftp_conn *conn, const char *path) ++sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir) { -- return do_realpath_expand(conn, path, 0); -+ return do_realpath_expand(conn, path, 0, create_dir); +- return sftp_realpath_expand(conn, path, 0); ++ return sftp_realpath_expand(conn, path, 0, create_dir); } - + int -@@ -1055,9 +1083,9 @@ do_expand_path(struct sftp_conn *conn, c +@@ -1094,9 +1126,9 @@ { - if (!can_expand_path(conn)) { + if (!sftp_can_expand_path(conn)) { debug3_f("no server support, fallback to realpath"); -- return do_realpath_expand(conn, path, 0); -+ return do_realpath_expand(conn, path, 0, 0); +- return sftp_realpath_expand(conn, path, 0); ++ return sftp_realpath_expand(conn, path, 0, 0); } -- return do_realpath_expand(conn, path, 1); -+ return do_realpath_expand(conn, path, 1, 0); +- return sftp_realpath_expand(conn, path, 1); ++ return sftp_realpath_expand(conn, path, 1, 0); } - + int -@@ -1807,7 +1835,7 @@ download_dir(struct sftp_conn *conn, con +@@ -2016,7 +2048,7 @@ char *src_canon; int ret; - -- if ((src_canon = do_realpath(conn, src)) == NULL) { -+ if ((src_canon = do_realpath(conn, src, 0)) == NULL) { - error("download \"%s\": path canonicalization failed", src); - return -1; - } -@@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co + +- if ((src_canon = sftp_realpath(conn, src)) == NULL) { ++ if ((src_canon = sftp_realpath(conn, src, 0)) == NULL) { + error("download \"%s\": path canonicalization failed", src); + return -1; + } +@@ -2365,12 +2397,12 @@ int - upload_dir(struct sftp_conn *conn, const char *src, const char *dst, + sftp_upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int preserve_flag, int print_flag, int resume, int fsync_flag, - int follow_link_flag, int inplace_flag) + int follow_link_flag, int inplace_flag, int create_dir) { char *dst_canon; int ret; - -- if ((dst_canon = do_realpath(conn, dst)) == NULL) { -+ if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) { - error("upload \"%s\": path canonicalization failed", dst); - return -1; - } -@@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st + +- if ((dst_canon = sftp_realpath(conn, dst)) == NULL) { ++ if ((dst_canon = sftp_realpath(conn, dst, create_dir)) == NULL) { + error("upload \"%s\": path canonicalization failed", dst); + return -1; + } +@@ -2825,7 +2857,7 @@ char *from_path_canon; int ret; - -- if ((from_path_canon = do_realpath(from, from_path)) == NULL) { -+ if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) { - error("crossload \"%s\": path canonicalization failed", - from_path); - return -1; -diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h ---- openssh-8.7p1/sftp-client.h.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp-client.h 2022-02-07 12:31:07.410740433 +0100 -@@ -111,7 +111,7 @@ int do_fsetstat(struct sftp_conn *, cons - int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); - + +- if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) { ++ if ((from_path_canon = sftp_realpath(from, from_path, 0)) == NULL) { + error("crossload \"%s\": path canonicalization failed", + from_path); + return -1; +diff --git a/sftp-client.h b/sftp-client.h +--- a/sftp-client.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp-client.h (date 1703111691284) +@@ -111,7 +111,7 @@ + int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); + /* Canonicalise 'path' - caller must free result */ --char *do_realpath(struct sftp_conn *, const char *); -+char *do_realpath(struct sftp_conn *, const char *, int); - +-char *sftp_realpath(struct sftp_conn *, const char *); ++char *sftp_realpath(struct sftp_conn *, const char *, int); + /* Canonicalisation with tilde expansion (requires server extension) */ - char *do_expand_path(struct sftp_conn *, const char *); -@@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const + char *sftp_expand_path(struct sftp_conn *, const char *); +@@ -163,7 +163,7 @@ * times if 'pflag' is set */ - int upload_dir(struct sftp_conn *, const char *, const char *, + int sftp_upload_dir(struct sftp_conn *, const char *, const char *, - int, int, int, int, int, int); + int, int, int, int, int, int, int); - + /* * Download a 'from_path' from the 'from' connection and upload it to -diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c ---- openssh-8.7p1/sftp.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp.c 2022-02-07 12:31:07.411740442 +0100 -@@ -760,7 +760,7 @@ process_put(struct sftp_conn *conn, cons - if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { - if (upload_dir(conn, g.gl_pathv[i], abs_dst, + +diff --git a/sftp.c b/sftp.c +--- a/sftp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp.c (date 1703168795365) +@@ -807,7 +807,7 @@ + (rflag || global_rflag)) { + if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst, pflag || global_pflag, 1, resume, - fflag || global_fflag, 0, 0) == -1) + fflag || global_fflag, 0, 0, 0) == -1) err = -1; } else { - if (do_upload(conn, g.gl_pathv[i], abs_dst, -@@ -1577,7 +1577,7 @@ parse_dispatch_command(struct sftp_conn + if (sftp_upload(conn, g.gl_pathv[i], abs_dst, +@@ -1642,7 +1642,7 @@ if (path1 == NULL || *path1 == '\0') path1 = xstrdup(startdir); - path1 = make_absolute(path1, *pwd); -- if ((tmp = do_realpath(conn, path1)) == NULL) { -+ if ((tmp = do_realpath(conn, path1, 0)) == NULL) { + path1 = sftp_make_absolute(path1, *pwd); +- if ((tmp = sftp_realpath(conn, path1)) == NULL) { ++ if ((tmp = sftp_realpath(conn, path1, 0)) == NULL) { err = 1; break; } -@@ -2160,7 +2160,7 @@ interactive_loop(struct sftp_conn *conn, +@@ -2247,7 +2247,7 @@ } #endif /* USE_LIBEDIT */ - -- remote_path = do_realpath(conn, "."); -+ remote_path = do_realpath(conn, ".", 0); - if (remote_path == NULL) + +- if ((remote_path = sftp_realpath(conn, ".")) == NULL) ++ if ((remote_path = sftp_realpath(conn, ".", 0)) == NULL) fatal("Need cwd"); startdir = xstrdup(remote_path); + diff --git a/openssh-9.0p1-audit-log.patch b/openssh-9.0p1-audit-log.patch new file mode 100644 index 0000000000000000000000000000000000000000..04a16b985a7a358da087ea76a0e1e0aef2bed8de --- /dev/null +++ b/openssh-9.0p1-audit-log.patch @@ -0,0 +1,119 @@ +diff -up openssh-9.0p1/audit-bsm.c.patch openssh-9.0p1/audit-bsm.c +--- openssh-9.0p1/audit-bsm.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit-bsm.c 2022-10-24 14:51:43.685766639 +0200 +@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li + } + + int +-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv) + { + /* not implemented */ + } +diff -up openssh-9.0p1/audit.c.patch openssh-9.0p1/audit.c +--- openssh-9.0p1/audit.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit.c 2022-10-24 15:20:38.854548226 +0200 +@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev) + void + audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) + { +- char *fp; ++ char *key_fp = NULL; ++ char *issuer_fp = NULL; ++ struct sshkey_cert *cert = NULL; + +- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); +- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) ++ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) { ++ cert = key->cert; ++ issuer_fp = sshkey_fingerprint(cert->signature_key, ++ options.fingerprint_hash, SSH_FP_DEFAULT); ++ } ++ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0) + *rv = -SSH_ERR_INTERNAL_ERROR; +- free(fp); ++ if (key_fp) ++ free(key_fp); ++ if (issuer_fp) ++ free(issuer_fp); + } + + void +diff -up openssh-9.0p1/audit.h.patch openssh-9.0p1/audit.h +--- openssh-9.0p1/audit.h.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit.h 2022-10-24 14:58:20.887565518 +0200 +@@ -64,7 +64,7 @@ void audit_session_close(struct logininf + int audit_run_command(struct ssh *, const char *); + void audit_end_command(struct ssh *, int, const char *); + ssh_audit_event_t audit_classify_auth(const char *); +-int audit_keyusage(struct ssh *, int, char *, int); ++int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int); + void audit_key(struct ssh *, int, int *, const struct sshkey *); + void audit_unsupported(struct ssh *, int); + void audit_kex(struct ssh *, int, char *, char *, char *, char *); +diff -up openssh-9.0p1/audit-linux.c.patch openssh-9.0p1/audit-linux.c +--- openssh-9.0p1/audit-linux.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit-linux.c 2022-10-24 15:21:58.165303951 +0200 +@@ -137,10 +137,12 @@ fatal_report: + } + + int +-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, const char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv) + { + char buf[AUDIT_LOG_SIZE]; + int audit_fd, rc, saved_errno; ++ const char *rip; ++ u_int i; + + audit_fd = audit_open(); + if (audit_fd < 0) { +@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host + else + return 0; /* Must prevent login */ + } ++ rip = ssh_remote_ipaddr(ssh); + snprintf(buf, sizeof(buf), "%s_auth grantors=auth-key", host_user ? "pubkey" : "hostbased"); + rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, +- buf, audit_username(), -1, NULL, ssh_remote_ipaddr(ssh), NULL, rv); ++ buf, audit_username(), -1, NULL, rip, NULL, rv); + if ((rc < 0) && ((rc != -1) || (getuid() == 0))) + goto out; +- snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", fp); ++ snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", key_fp); + rc = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, buf, NULL, +- ssh_remote_ipaddr(ssh), NULL, rv); ++ rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ ++ if (cert) { ++ char *pbuf; ++ ++ pbuf = audit_encode_nv_string("key_id", cert->key_id, 0); ++ if (pbuf == NULL) ++ goto out; ++ snprintf(buf, sizeof(buf), "cert %s cert_serial=%llu cert_issuer_alg=\"%s\" cert_issuer_fp=\"%s\"", ++ pbuf, (unsigned long long)cert->serial, sshkey_type(cert->signature_key), issuer_fp); ++ free(pbuf); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ ++ for (i = 0; cert->principals != NULL && i < cert->nprincipals; i++) { ++ pbuf = audit_encode_nv_string("cert_principal", cert->principals[i], 0); ++ if (pbuf == NULL) ++ goto out; ++ snprintf(buf, sizeof(buf), "principal %s", pbuf); ++ free(pbuf); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ } ++ } + out: + saved_errno = errno; + audit_close(audit_fd); diff --git a/openssh-9.3p1-merged-openssl-evp.patch b/openssh-9.3p1-merged-openssl-evp.patch index d8c2ca359fa4592e5f2ab362099dd6170d3a564b..6a30485aee3d7a6463a22fef6ed844a2889dd8c5 100644 --- a/openssh-9.3p1-merged-openssl-evp.patch +++ b/openssh-9.3p1-merged-openssl-evp.patch @@ -252,6 +252,16 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include +@@ -44,6 +44,9 @@ + #include "digest.h" + #define SSHKEY_INTERNAL + #include "sshkey.h" ++#ifdef ENABLE_PKCS11 ++#include "ssh-pkcs11.h" ++#endif + + #include "openbsd-compat/openssl-compat.h" + @@ -126,19 +128,29 @@ static int ssh_ecdsa_generate(struct sshkey *k, int bits) @@ -521,14 +531,6 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #endif #include "crypto_api.h" -@@ -57,6 +59,7 @@ - #define SSHKEY_INTERNAL - #include "sshkey.h" - #include "match.h" -+#include "log.h" - #include "ssh-sk.h" - - #ifdef WITH_XMSS @@ -575,6 +577,86 @@ } @@ -657,15 +659,15 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x # ifdef OPENSSL_HAS_ECC # include # include -@@ -268,6 +271,10 @@ +@@ -266,6 +266,10 @@ const char *sshkey_ssh_name_plain(const struct sshkey *); - int sshkey_names_valid2(const char *, int); + int sshkey_names_valid2(const char *, int, int); char *sshkey_alg_list(int, int, int, char); +int sshkey_calculate_signature(EVP_PKEY*, int, u_char **, + int *, const u_char *, size_t); +int sshkey_verify_signature(EVP_PKEY *, int, const u_char *, + size_t, u_char *, int); - + int sshkey_from_blob(const u_char *, size_t, struct sshkey **); int sshkey_fromb(struct sshbuf *, struct sshkey **); @@ -324,6 +331,13 @@ @@ -693,11 +695,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #if !defined(WITH_OPENSSL) # undef RSA # undef DSA -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11.c openssh-9.3p1-patched/ssh-pkcs11.c ---- openssh-9.3p1/ssh-pkcs11.c 2023-06-06 15:53:36.592443989 +0200 -+++ openssh-9.3p1-patched/ssh-pkcs11.c 2023-06-06 15:52:25.626551768 +0200 -@@ -777,8 +777,24 @@ - +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +--- a/ssh-pkcs11.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11.c (date 1703110934679) +@@ -620,8 +620,24 @@ + return (0); } + @@ -709,7 +711,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return 0; +} #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - + +int +is_rsa_pkcs11(RSA *rsa) +{ @@ -718,16 +720,16 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return 0; +} + - /* remove trailing spaces */ - static void - rmspace(u_char *buf, size_t len) -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11-client.c openssh-9.3p1-patched/ssh-pkcs11-client.c ---- openssh-9.3p1/ssh-pkcs11-client.c 2023-06-06 15:53:36.591443976 +0200 -+++ openssh-9.3p1-patched/ssh-pkcs11-client.c 2023-06-06 15:52:25.626551768 +0200 -@@ -225,8 +225,36 @@ - static RSA_METHOD *helper_rsa; - #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - static EC_KEY_METHOD *helper_ecdsa; + /* remove trailing spaces. Note, that this does NOT guarantee the buffer + * will be null terminated if there are no trailing spaces! */ + static char * +diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c +--- a/ssh-pkcs11-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11-client.c (date 1703110830967) +@@ -402,8 +402,36 @@ + if (helper->nrsa == 0 && helper->nec == 0) + helper_terminate(helper); + } + +int +is_ecdsa_pkcs11(EC_KEY *ecdsa) @@ -742,8 +744,8 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return 1; + return 0; +} - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - + #endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ + +int +is_rsa_pkcs11(RSA *rsa) +{ @@ -760,14 +762,15 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + /* redirect private key crypto operations to the ssh-pkcs11-helper */ static void - wrap_key(struct sshkey *k) -diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11.h openssh-9.3p1-patched/ssh-pkcs11.h ---- openssh-9.3p1/ssh-pkcs11.h 2023-06-06 15:53:36.592443989 +0200 -+++ openssh-9.3p1-patched/ssh-pkcs11.h 2023-06-06 15:52:25.626551768 +0200 -@@ -39,6 +39,11 @@ - u_int32_t *); - #endif - + wrap_key(struct helper *helper, struct sshkey *k) +diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h +--- a/ssh-pkcs11.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11.h (date 1703111023334) +@@ -38,6 +38,12 @@ + /* Only available in ssh-pkcs11-client.c so far */ + int pkcs11_make_cert(const struct sshkey *, + const struct sshkey *, struct sshkey **); ++ +#ifdef HAVE_EC_KEY_METHOD_NEW +int is_ecdsa_pkcs11(EC_KEY *ecdsa); +#endif @@ -788,7 +791,13 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #include #include -@@ -36,7 +38,7 @@ +@@ -36,10 +36,13 @@ + #include "sshkey.h" + #include "digest.h" + #include "log.h" ++#ifdef ENABLE_PKCS11 ++#include "ssh-pkcs11.h" ++#endif #include "openbsd-compat/openssl-compat.h" diff --git a/openssh-9.3p2.tar.gz b/openssh-9.3p2.tar.gz deleted file mode 100644 index a670bd8ef9841e04c51b55d924630261ee007880..0000000000000000000000000000000000000000 Binary files a/openssh-9.3p2.tar.gz and /dev/null differ diff --git a/openssh-9.3p2.tar.gz.asc b/openssh-9.3p2.tar.gz.asc deleted file mode 100644 index 4c69906cd5d1f6092d81e0b9c5d1fb0cf31698cc..0000000000000000000000000000000000000000 --- a/openssh-9.3p2.tar.gz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmS3g5wACgkQKj9BTnNg -YLrMYw//evjl0mlSnycb85tWASdBWQh28xQCouuqYhDhY+8kt6YpEx34r4zuXvL3 -pEN/F1ancNXwvlRPct/tF3OEQVpKHZqiRyfWuHHURSBLaGf9V1b+gQgfM4lEQNtH -8PqRj+ur8E2GMGxvxuDKPcfduCTFrjbPJ/0OCgquuEteSM6dgcClT7q5SKKpTVSa -jV0PaXeYgnaa+u+4GsH01oUteyJNmhvEa4T+fC1RDrct1DiieUQNkaw3pwMqYXA5 -8PldGatn/npNM5ZFW4uxTjbib2yJXNIEhUIzo2A00XWRG3jIArtRJwJ6ZSBahUE4 -PyasPMhJVIxIaKy5OL4s4FAd1goe2hBlPzmDhUJOhpFniLIZ9dS5AGaX4i2TjsZl -iaIwtE2VLIn3peKZPvm7SCBqyBoiPKC0BfHmVOYs8c1W5Q30jE+kCcTDrJhHl32/ -kN5khCHIg6bUc3JzFZM7Ib0tshNP5AY0pyduSEF7SPOB5Zz2E+EwkDmkrnw9FoMh -LCvSERDkBdxWD7okUdb0ARr564lShRjd2UTFZqv3Py4nVfvnP19RgCfakNg0CZ3w -VoLytn8OQ/joAx4GMWox6g5ieYqeQ2kLzXYfXObTlDIjxirFeiBYPh6Ln5oGl81/ -jx/172HqCzRDgUogtZ/BTwiLDEzTHG7YS5RDIUYkqEGkkjjj6gg= -=yVD2 ------END PGP SIGNATURE----- diff --git a/openssh-9.6p1.tar.gz b/openssh-9.6p1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a0fb71616503940886d3a49c01e3bc1d5e3a8497 Binary files /dev/null and b/openssh-9.6p1.tar.gz differ diff --git a/openssh-9.6p1.tar.gz.asc b/openssh-9.6p1.tar.gz.asc new file mode 100644 index 0000000000000000000000000000000000000000..e99892f8b86193e8b14bd703728c2a707bc0ec6d --- /dev/null +++ b/openssh-9.6p1.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmWAXvAACgkQKj9BTnNg +YLrypA/6A1O8e80XnzVWIFhXkbv/biGL10Q5ZMvjQvND6mbkphNWZ4G4QOEh0nBG +rseD3Fce7me9pfeLYVhaNXO9R3OYAXxjbWfQwI7FpBU4QUCnbH53PG32B6ESq7pl +0vlDqdqI7aBAyMpp+8WFD+EvHWUVA77JtfU4MFw7myKJacrVrDUygDaZkJKOhqKf +N1Nurz4YppdQ5zIK1ElL0jlRJXm08flLFRg8fD5/5rwabpUbZIY9b5qZzGKgnR7I +sxUBlDkfLnvKIlKzUXbRvOHazvFAHYH1ltJZGlJUc/+H/ZaPigWf4IR+E1FB9c2O +zxaZhlbwGKyD+p7l08F9n8T21taxpBCW1Uxkx7MLTz8k9huPNpdX5l8VM4Gotmn8 +I4V3Fevyx+M3XJYeKtkspa51h0GqF3gNFPLxW7ERGaIuqwoxuHxIEKwYE+JPmQag +UDma5LDrSrasa8Rw8g5urGE48PeDQ5muPy8Bi9eIGZU5JLqX6TNgz7QDDs/dQsHB +iny4wQOLmdIA78IGttiCo0rqikEvFtFDFR4mCUTC8K0nQKzWwGewO3gRTcHttzyU +xMalxw+wt9cUJ8gb1E9p7OeMUuXdaHMmem8/PcFCar/vKx1mdV/On6evnp3P8yQA +la8WnbcP0+zJg0GGwGszpFlOMjWCDB0kUTBCT+MR+IWbj/pVZVA= +=G9YA +-----END PGP SIGNATURE----- diff --git a/openssh.spec b/openssh.spec index f8d9b0549429e9e5e57701f124e49f46c9004ee9..cc53a64b551ca1370407161e319224618548fdf4 100644 --- a/openssh.spec +++ b/openssh.spec @@ -6,10 +6,10 @@ %{?no_gtk2:%global gtk2 0} %global sshd_uid 74 -%global openssh_release 6 +%global openssh_release 1 Name: openssh -Version: 9.3p2 +Version: 9.6p1 Release: %{openssh_release} URL: http://www.openssh.com/portable.html License: BSD @@ -32,88 +32,83 @@ Source13: sshd-keygen.target Source14: ssh-agent.service Source15: ssh-agent.socket Source16: ssh-keygen-bash-completion.sh +Source17: ssh-host-keys-migration.sh +Source18: ssh-host-keys-migration.service Patch0: openssh-6.7p1-coverity.patch Patch1: openssh-7.6p1-audit.patch Patch2: openssh-7.1p2-audit-race-condition.patch -Patch3: pam_ssh_agent_auth-0.9.3-build.patch -Patch4: pam_ssh_agent_auth-0.10.3-seteuid.patch -Patch5: pam_ssh_agent_auth-0.9.2-visibility.patch -Patch6: pam_ssh_agent_auth-0.9.3-agent_structure.patch -Patch7: pam_ssh_agent_auth-0.10.2-compat.patch -Patch8: pam_ssh_agent_auth-0.10.2-dereference.patch -Patch9: pam_ssh_agent_auth-0.10.4-rsasha2.patch -Patch10: pam_ssh_agent-configure-c99.patch -Patch11: openssh-7.8p1-role-mls.patch -Patch12: openssh-6.6p1-privsep-selinux.patch +Patch3: openssh-9.0p1-audit-log.patch +Patch4: pam_ssh_agent_auth-0.9.3-build.patch +Patch5: pam_ssh_agent_auth-0.10.3-seteuid.patch +Patch6: pam_ssh_agent_auth-0.9.2-visibility.patch +Patch7: pam_ssh_agent_auth-0.9.3-agent_structure.patch +Patch8: pam_ssh_agent_auth-0.10.2-compat.patch +Patch9: pam_ssh_agent_auth-0.10.2-dereference.patch +Patch10: pam_ssh_agent_auth-0.10.4-rsasha2.patch +Patch11: pam_ssh_agent-configure-c99.patch +Patch12: openssh-7.8p1-role-mls.patch +Patch13: openssh-6.6p1-privsep-selinux.patch Patch14: openssh-6.6p1-keycat.patch Patch15: openssh-6.6p1-allow-ip-opts.patch -Patch17: openssh-5.9p1-ipv6man.patch -Patch18: openssh-5.8p2-sigpipe.patch -Patch19: openssh-7.2p2-x11.patch -Patch21: openssh-5.1p1-askpass-progress.patch -Patch22: openssh-4.3p2-askpass-grab-info.patch -Patch23: openssh-7.7p1.patch -Patch24: openssh-7.8p1-UsePAM-warning.patch -Patch28: openssh-8.0p1-gssapi-keyex.patch -Patch29: openssh-6.6p1-force_krb.patch -Patch30: openssh-6.6p1-GSSAPIEnablek5users.patch -Patch31: openssh-7.7p1-gssapi-new-unique.patch -Patch32: openssh-7.2p2-k5login_directory.patch -Patch33: openssh-6.6p1-kuserok.patch -Patch34: openssh-6.4p1-fromto-remote.patch -Patch35: openssh-6.6.1p1-selinux-contexts.patch -Patch36: openssh-6.6.1p1-log-in-chroot.patch -Patch37: openssh-6.6.1p1-scp-non-existing-directory.patch -Patch38: openssh-6.8p1-sshdT-output.patch -Patch39: openssh-6.7p1-sftp-force-permission.patch -Patch40: openssh-7.2p2-s390-closefrom.patch -Patch41: openssh-7.3p1-x11-max-displays.patch -Patch42: openssh-7.4p1-systemd.patch -Patch43: openssh-7.6p1-cleanup-selinux.patch -Patch44: openssh-7.5p1-sandbox.patch -Patch45: openssh-8.0p1-pkcs11-uri.patch -Patch46: openssh-7.8p1-scp-ipv6.patch -Patch48: openssh-8.0p1-crypto-policies.patch -Patch49: openssh-9.3p1-merged-openssl-evp.patch -Patch50: openssh-8.0p1-openssl-kdf.patch -Patch51: openssh-8.2p1-visibility.patch -Patch52: openssh-8.2p1-x11-without-ipv6.patch -Patch53: openssh-8.0p1-keygen-strip-doseol.patch -Patch54: openssh-8.0p1-preserve-pam-errors.patch -Patch55: openssh-8.7p1-scp-kill-switch.patch -Patch56: openssh-8.7p1-recursive-scp.patch -Patch57: openssh-8.7p1-minrsabits.patch -Patch58: openssh-8.7p1-ibmca.patch -Patch60: openssh-8.7p1-ssh-manpage.patch -Patch61: openssh-8.7p1-negotiate-supported-algs.patch -Patch66: bugfix-sftp-when-parse_user_host_path-empty-path-should-be-allowed.patch -Patch67: bugfix-openssh-add-option-check-username-splash.patch -Patch68: feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch -Patch69: bugfix-openssh-fix-sftpserver.patch -Patch70: set-sshd-config.patch -Patch71: feature-add-SMx-support.patch -Patch72: add-loongarch.patch -Patch73: openssh-Add-sw64-architecture.patch -Patch74: add-strict-scp-check-for-CVE-2020-15778.patch -Patch75: skip-scp-test-if-there-is-no-scp-on-remote-path-as-s.patch -Patch77: set-ssh-config.patch -Patch78: backport-CVE-2023-48795-upstream-implement-strict-key-exchange-in-ssh-and-ss.patch -Patch79: backport-CVE-2023-51385-upstream-ban-user-hostnames-with-most-shell-metachar.patch -Patch80: backport-fix-CVE-2024-6387.patch -Patch81: backport-CVE-2023-51384-upstream-apply-destination-constraints-to-all-p11-ke.patch -Patch82: backport-upstream-Make-sure-sftp_get_limits-only-returns-0-if.patch -Patch83: backport-upstream-when-connecting-via-socket-the-default-case.patch -Patch84: backport-upstream-set-errno-EAFNOSUPPORT-when-filtering-addre.patch -Patch85: backport-upstream-when-invoking-KnownHostsCommand-to-determin.patch -Patch86: backport-upstream-ensure-key_fd-is-filled-when-DSA-is-disable.patch -Patch87: backport-upstream-fix-memory-leak-in-mux-proxy-mode-when-requ.patch -Patch88: backport-openssh-7.7p1-fips.patch -Patch89: backport-CVE-2021-36368-added-option-to-disable-trivial-auth.patch -Patch90: backport-upstream-Fix-proxy-multiplexing-O-proxy-bug.patch -Patch91: backport-openssh-6.6p1-keyperm.patch -Patch92: backport-upstream-make-parsing-user-host-consistently-look-for-the-last-in.patch -Patch93: backport-upstream-Do-not-apply-authorized_keys-options-when-signature.patch -Patch94: backport-upstream-some-extra-paranoia.patch +Patch16: openssh-5.9p1-ipv6man.patch +Patch17: openssh-5.8p2-sigpipe.patch +Patch18: openssh-7.2p2-x11.patch +Patch19: openssh-7.7p1-fips.patch +Patch20: openssh-5.1p1-askpass-progress.patch +Patch21: openssh-4.3p2-askpass-grab-info.patch +Patch22: openssh-7.7p1.patch +Patch23: openssh-7.8p1-UsePAM-warning.patch +Patch24: openssh-8.0p1-gssapi-keyex.patch +Patch25: openssh-6.6p1-force_krb.patch +Patch26: openssh-6.6p1-GSSAPIEnablek5users.patch +Patch27: openssh-7.7p1-gssapi-new-unique.patch +Patch28: openssh-7.2p2-k5login_directory.patch +Patch29: openssh-6.6p1-kuserok.patch +Patch30: openssh-6.4p1-fromto-remote.patch +Patch31: openssh-6.6.1p1-selinux-contexts.patch +Patch32: openssh-6.6.1p1-log-in-chroot.patch +Patch33: openssh-6.6.1p1-scp-non-existing-directory.patch +Patch34: openssh-6.8p1-sshdT-output.patch +Patch35: openssh-6.7p1-sftp-force-permission.patch +Patch36: openssh-7.2p2-s390-closefrom.patch +Patch37: openssh-7.3p1-x11-max-displays.patch +Patch38: openssh-7.4p1-systemd.patch +Patch39: openssh-7.6p1-cleanup-selinux.patch +Patch40: openssh-7.5p1-sandbox.patch +Patch41: openssh-8.0p1-pkcs11-uri.patch +Patch42: openssh-7.8p1-scp-ipv6.patch +Patch43: openssh-8.0p1-crypto-policies.patch +Patch44: openssh-9.3p1-merged-openssl-evp.patch +Patch45: openssh-8.0p1-openssl-kdf.patch +Patch46: openssh-8.2p1-visibility.patch +Patch47: openssh-8.2p1-x11-without-ipv6.patch +Patch48: openssh-8.0p1-keygen-strip-doseol.patch +Patch49: openssh-8.0p1-preserve-pam-errors.patch +Patch50: openssh-8.7p1-scp-kill-switch.patch +Patch51: openssh-8.7p1-recursive-scp.patch +Patch52: openssh-8.7p1-minrsabits.patch +Patch53: openssh-8.7p1-ibmca.patch +Patch54: openssh-8.7p1-ssh-manpage.patch +Patch55: openssh-8.7p1-negotiate-supported-algs.patch + +Patch56: bugfix-sftp-when-parse_user_host_path-empty-path-should-be-allowed.patch +Patch57: bugfix-openssh-add-option-check-username-splash.patch +Patch58: feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch +Patch59: bugfix-openssh-fix-sftpserver.patch +Patch60: set-sshd-config.patch +Patch61: feature-add-SMx-support.patch +Patch62: add-loongarch.patch +Patch63: openssh-Add-sw64-architecture.patch +Patch64: add-strict-scp-check-for-CVE-2020-15778.patch +Patch65: skip-scp-test-if-there-is-no-scp-on-remote-path-as-s.patch +Patch66: set-ssh-config.patch +Patch67: backport-fix-CVE-2024-6387.patch + +Patch68: backport-upstream-ensure-key_fd-is-filled-when-DSA-is-disable.patch +Patch69: backport-upstream-Fix-proxy-multiplexing-O-proxy-bug.patch +Patch70: backport-upstream-make-parsing-user-host-consistently-look-for-the-last-in.patch +Patch71: backport-upstream-Do-not-apply-authorized_keys-options-when-signature.patch +Patch72: backport-upstream-some-extra-paranoia.patch Requires: /sbin/nologin Requires: libselinux >= 2.3-5 audit-libs >= 1.0.8 @@ -190,93 +185,84 @@ instance. The module is most useful for su and sudo service stacks. %setup -q -a 3 pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 -%patch3 -p2 -b .psaa-build -%patch4 -p2 -b .psaa-seteuid -%patch5 -p2 -b .psaa-visibility -%patch7 -p2 -b .psaa-compat -%patch6 -p2 -b .psaa-agent -%patch8 -p2 -b .psaa-deref -%patch9 -p2 -b .rsasha2 -%patch10 -p1 -b .psaa-configure-c99 +%patch -P 4 -p2 -b .psaa-build +%patch -P 5 -p2 -b .psaa-seteuid +%patch -P 6 -p2 -b .psaa-visibility +%patch -P 8 -p2 -b .psaa-compat +%patch -P 7 -p2 -b .psaa-agent +%patch -P 9 -p2 -b .psaa-deref +%patch -P 10 -p2 -b .rsasha2 +%patch -P 11 -p1 -b .psaa-configure-c99 # Remove duplicate headers and library files rm -f $(cat %{SOURCE4}) popd -%patch11 -p1 -b .role-mls -%patch12 -p1 -b .privsep-selinux -%patch14 -p1 -b .keycat -%patch15 -p1 -b .ip-opts -%patch17 -p1 -b .ipv6man -%patch18 -p1 -b .sigpipe -%patch19 -p1 -b .x11 -%patch21 -p1 -b .progress -%patch22 -p1 -b .grab-info -%patch23 -p1 -%patch24 -p1 -b .log-usepam-no -%patch28 -p1 -b .gsskex -%patch29 -p1 -b .force_krb -%patch31 -p1 -b .ccache_name -%patch32 -p1 -b .k5login -%patch33 -p1 -b .kuserok -%patch34 -p1 -b .fromto-remote -%patch35 -p1 -b .contexts -%patch36 -p1 -b .log-in-chroot -%patch37 -p1 -b .scp -%patch30 -p1 -b .GSSAPIEnablek5users -%patch38 -p1 -b .sshdt -%patch39 -p1 -b .sftp-force-mode -%patch40 -p1 -b .s390-dev -%patch41 -p1 -b .x11max -%patch42 -p1 -b .systemd -%patch43 -p1 -b .refactor -%patch44 -p1 -b .sandbox -%patch45 -p1 -b .pkcs11-uri -%patch46 -p1 -b .scp-ipv6 -%patch48 -p1 -b .crypto-policies -%patch49 -p1 -b .openssl-evp -%patch50 -p1 -b .openssl-kdf -%patch51 -p1 -b .visibility -%patch52 -p1 -b .x11-ipv6 -%patch53 -p1 -b .keygen-strip-doseol -%patch54 -p1 -b .preserve-pam-errors -%patch55 -p1 -b .kill-scp -%patch56 -p1 -b .scp-sftpdirs -%patch57 -p1 -b .minrsabits -%patch58 -p1 -b .ibmca -%patch60 -p1 -b .ssh-manpage -%patch61 -p1 -b .negotiate-supported-algs -%patch1 -p1 -b .audit -%patch2 -p1 -b .audit-race -%patch0 -p1 -b .coverity - -%patch66 -p1 -%patch67 -p1 -%patch68 -p1 -%patch69 -p1 -%patch70 -p1 -%patch71 -p1 -%patch72 -p1 -%patch73 -p1 -%patch74 -p1 -%patch75 -p1 -%patch77 -p1 -%patch78 -p1 -%patch79 -p1 -%patch80 -p1 -%patch81 -p1 -%patch82 -p1 -%patch83 -p1 -%patch84 -p1 -%patch85 -p1 -%patch86 -p1 -%patch87 -p1 -%patch88 -p1 -%patch89 -p1 -%patch90 -p1 -%patch91 -p1 -%patch92 -p1 -%patch93 -p1 -%patch94 -p1 +%patch -P 12 -p1 -b .role-mls +%patch -P 13 -p1 -b .privsep-selinux +%patch -P 14 -p1 -b .keycat +%patch -P 15 -p1 -b .ip-opts +%patch -P 16 -p1 -b .ipv6man +%patch -P 17 -p1 -b .sigpipe +%patch -P 18 -p1 -b .x11 +%patch -P 20 -p1 -b .progress +%patch -P 21 -p1 -b .grab-info +%patch -P 22 -p1 +%patch -P 23 -p1 -b .log-usepam-no +%patch -P 24 -p1 -b .gsskex +%patch -P 25 -p1 -b .force_krb +%patch -P 27 -p1 -b .ccache_name +%patch -P 28 -p1 -b .k5login +%patch -P 29 -p1 -b .kuserok +%patch -P 30 -p1 -b .fromto-remote +%patch -P 31 -p1 -b .contexts +%patch -P 32 -p1 -b .log-in-chroot +%patch -P 33 -p1 -b .scp +%patch -P 26 -p1 -b .GSSAPIEnablek5users +%patch -P 34 -p1 -b .sshdt +%patch -P 35 -p1 -b .sftp-force-mode +%patch -P 36 -p1 -b .s390-dev +%patch -P 37 -p1 -b .x11max +%patch -P 38 -p1 -b .systemd +%patch -P 39 -p1 -b .refactor +%patch -P 40 -p1 -b .sandbox +%patch -P 41 -p1 -b .pkcs11-uri +%patch -P 42 -p1 -b .scp-ipv6 +%patch -P 43 -p1 -b .crypto-policies +%patch -P 44 -p1 -b .openssl-evp +%patch -P 45 -p1 -b .openssl-kdf +%patch -P 46 -p1 -b .visibility +%patch -P 47 -p1 -b .x11-ipv6 +%patch -P 48 -p1 -b .keygen-strip-doseol +%patch -P 49 -p1 -b .preserve-pam-errors +%patch -P 50 -p1 -b .kill-scp +%patch -P 51 -p1 -b .scp-sftpdirs +%patch -P 52 -p1 -b .minrsabits +%patch -P 53 -p1 -b .ibmca +%patch -P 1 -p1 -b .audit +%patch -P 2 -p1 -b .audit-race +%patch -P 3 -p1 -b .audit-log +%patch -P 19 -p1 -b .fips +%patch -P 54 -p1 -b .ssh-manpage +%patch -P 55 -p1 -b .negotiate-supported-algs +%patch -P 0 -p1 -b .coverity + +%patch -P 56 -p1 +%patch -P 57 -p1 +%patch -P 58 -p1 +%patch -P 59 -p1 +%patch -P 60 -p1 +%patch -P 61 -p1 +%patch -P 62 -p1 +%patch -P 63 -p1 +%patch -P 64 -p1 +%patch -P 65 -p1 +%patch -P 66 -p1 +%patch -P 67 -p1 +%patch -P 68 -p1 +%patch -P 69 -p1 +%patch -P 70 -p1 +%patch -P 71 -p1 +%patch -P 72 -p1 autoreconf pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 @@ -390,6 +376,10 @@ install contrib/ssh-copy-id.1 $RPM_BUILD_ROOT%{_mandir}/man1/ install -m644 -D %{SOURCE12} $RPM_BUILD_ROOT%{_tmpfilesdir}/%{name}.conf install contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass install -m644 %{SOURCE16} $RPM_BUILD_ROOT/etc/bash_completion.d/ssh-keygen-bash-completion.sh +install -m744 %{SOURCE17} $RPM_BUILD_ROOT/%{_libexecdir}/openssh/ssh-host-keys-migration.sh +install -m644 %{SOURCE18} $RPM_BUILD_ROOT/%{_unitdir}/ssh-host-keys-migration.service +install -d $RPM_BUILD_ROOT/%{_localstatedir}/lib +touch $RPM_BUILD_ROOT/%{_localstatedir}/lib/.ssh-host-keys-migration ln -s gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass install -m 755 -d $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ @@ -412,6 +402,14 @@ getent passwd sshd >/dev/null || \ -s /sbin/nologin -r -d /var/empty/sshd sshd 2> /dev/null || : %post server +if [ $1 -gt 1 ]; then + # In the case of an upgrade (never true on OSTree systems) run the migration + # script for Fedora 38 to remove group ownership for host keys. + %{_libexecdir}/openssh/ssh-host-keys-migration.sh + # Prevent the systemd unit that performs the same service (useful for + # OSTree systems) from running. + touch /var/lib/.ssh-host-keys-migration +fi %systemd_post sshd.service sshd.socket %preun server @@ -466,6 +464,9 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/sshd-keygen@.service %attr(0644,root,root) %{_unitdir}/sshd-keygen.target %attr(0644,root,root) %{_tmpfilesdir}/openssh.conf +%attr(0644,root,root) %{_unitdir}/ssh-host-keys-migration.service +%attr(0744,root,root) %{_libexecdir}/openssh/ssh-host-keys-migration.sh +%ghost %attr(0644,root,root) %{_localstatedir}/lib/.ssh-host-keys-migration %files keycat %attr(0755,root,root) %{_libexecdir}/openssh/ssh-keycat @@ -493,6 +494,12 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_mandir}/man8/sftp-server.8* %changelog +* Mon Dec 09 2024 yanglu - 9.6p1-1 +- Type:requirement +- CVE:NA +- SUG:NA +- DESC:update openssh version to 9.6p1 + * Tue Oct 29 2024 bitianyuan - 9.3p2-6 - Type:bugfix - ID:NA diff --git a/ssh-host-keys-migration.service b/ssh-host-keys-migration.service new file mode 100644 index 0000000000000000000000000000000000000000..d49b63e7fddc9eceff0f69ee45f54bc314db7416 --- /dev/null +++ b/ssh-host-keys-migration.service @@ -0,0 +1,14 @@ +[Unit] +Description=Update OpenSSH host key permissions +Before=sshd.service +After=ssh-keygen.target +ConditionPathExists=!/var/lib/.ssh-host-keys-migration + +[Service] +Type=oneshot +ExecStart=-/usr/libexec/openssh/ssh-host-keys-migration.sh +ExecStart=touch /var/lib/.ssh-host-keys-migration +RemainAfterExit=yes + +[Install] +WantedBy=sshd.service diff --git a/ssh-host-keys-migration.sh b/ssh-host-keys-migration.sh new file mode 100644 index 0000000000000000000000000000000000000000..d376eda8f759179055e6aa015aa7d6a9d68bdfb7 --- /dev/null +++ b/ssh-host-keys-migration.sh @@ -0,0 +1,34 @@ +#!/usr/bin/bash +set -eu -o pipefail +# +# Example output looks like: +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +# Permissions 0640 for '/etc/ssh/ssh_host_rsa_key' are too open. +# It is required that your private key files are NOT accessible by others. +# This private key will be ignored. +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +# Permissions 0640 for '/etc/ssh/ssh_host_ecdsa_key' are too open. +# It is required that your private key files are NOT accessible by others. +# This private key will be ignored. +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +# Permissions 0640 for '/etc/ssh/ssh_host_ed25519_key' are too open. +# It is required that your private key files are NOT accessible by others. +# This private key will be ignored. +# sshd: no hostkeys available -- exiting. +# +output="$(sshd -T 2>&1 || true)" # expected to fail +while read line; do + if [[ $line =~ ^Permissions\ [0-9]+\ for\ \'(.*)\'\ are\ too\ open. ]]; then + keyfile=${BASH_REMATCH[1]} + echo $line + echo -e "\t-> changing permissions on $keyfile" + chmod --verbose g-r $keyfile + chown --verbose root:root $keyfile + fi +done <<< "$output" diff --git a/sshd-keygen b/sshd-keygen index efd876c99aa7c6a854f603889d32617b4f550a49..170ada07a9d0f48a49dd00405fb8509ef1b5678b 100644 --- a/sshd-keygen +++ b/sshd-keygen @@ -30,9 +30,8 @@ if ! $KEYGEN -q -t $KEYTYPE -f $KEY -C '' -N '' >&/dev/null; then fi # sanitize permissions -/usr/bin/chgrp ssh_keys $KEY -/usr/bin/chmod 400 $KEY -/usr/bin/chmod 400 $KEY.pub +/usr/bin/chmod 600 $KEY +/usr/bin/chmod 644 $KEY.pub if [[ -x /usr/sbin/restorecon ]]; then /usr/sbin/restorecon $KEY{,.pub} fi diff --git a/sshd.service b/sshd.service index e8afb869854ca11c713832b710733d19f7fc65ff..d138c67fc3fbee462af4d8e3a124c34423be37fb 100644 --- a/sshd.service +++ b/sshd.service @@ -3,6 +3,7 @@ Description=OpenSSH server daemon Documentation=man:sshd(8) man:sshd_config(5) After=network.target sshd-keygen.target Wants=sshd-keygen.target +Wants=ssh-host-keys-migration.service [Service] Type=notify diff --git a/sshd@.service b/sshd@.service index 196c555ae54f339b718c3f65858b1caa4adf6365..5cd740bb80172ba037c7985f10f72b4721124385 100644 --- a/sshd@.service +++ b/sshd@.service @@ -3,6 +3,7 @@ Description=OpenSSH per-connection server daemon Documentation=man:sshd(8) man:sshd_config(5) Wants=sshd-keygen.target After=sshd-keygen.target +Wants=ssh-host-keys-migration.service [Service] EnvironmentFile=-/etc/sysconfig/sshd