diff --git a/backport-Don-t-leak-the-strings-allocated-by-order_h.patch b/backport-Don-t-leak-the-strings-allocated-by-order_h.patch deleted file mode 100644 index 9b14806245d0d3f31920b10a952a2d24a8308be0..0000000000000000000000000000000000000000 --- a/backport-Don-t-leak-the-strings-allocated-by-order_h.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 6c31ba10e97b6953c4f325f526f3e846dfea647a Mon Sep 17 00:00:00 2001 -From: "dtucker@openbsd.org" -Date: Fri, 1 Jul 2022 03:39:44 +0000 -Subject: upstream: Don't leak the strings allocated by order_hostkeyalgs() - -and list_hostkey_types() that are passed to compat_pkalg_proposal(). Part of -github PR#324 from ZoltanFridrich, ok djm@ - -This is a roll-forward of the previous rollback now that the required -changes in compat.c have been done. - -OpenBSD-Commit-ID: c7cd93730b3b9f53cdad3ae32462922834ef73eb - -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/patch/?id=6c31ba10e97b6953c4f325f526f3e846dfea647a - ---- - sshconnect2.c | 16 ++++++++++------ - sshd.c | 17 +++++++++++------ - 2 files changed, 21 insertions(+), 12 deletions(-) - -diff --git a/sshconnect2.c b/sshconnect2.c -index 150d419..eb0df92 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sshconnect2.c,v 1.351 2021/07/23 05:24:02 djm Exp $ */ -+/* $OpenBSD: sshconnect2.c,v 1.359 2022/07/01 03:39:44 dtucker Exp $ */ - /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * Copyright (c) 2008 Damien Miller. All rights reserved. -@@ -218,6 +218,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - { - char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; - char *s, *all_key; -+ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; - int r, use_known_hosts_order = 0; - - #if defined(GSSAPI) && defined(WITH_OPENSSL) -@@ -248,10 +249,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - - if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) - fatal_f("kex_names_cat"); -- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, s); -+ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, s); - myproposal[PROPOSAL_ENC_ALGS_CTOS] = -- compat_cipher_proposal(ssh, options.ciphers); -- myproposal[PROPOSAL_ENC_ALGS_STOC] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc = - compat_cipher_proposal(ssh, options.ciphers); - myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = -@@ -260,12 +260,12 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; - if (use_known_hosts_order) { - /* Query known_hosts and prefer algorithms that appear there */ -- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = - compat_pkalg_proposal(ssh, - order_hostkeyalgs(host, hostaddr, port, cinfo)); - } else { - /* Use specified HostkeyAlgorithms exactly */ -- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = - compat_pkalg_proposal(ssh, options.hostkeyalgorithms); - } - -@@ -380,6 +380,10 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - (r = ssh_packet_write_wait(ssh)) != 0) - fatal_fr(r, "send packet"); - #endif -+ /* Free only parts of proposal that were dynamically allocated here. */ -+ free(prop_kex); -+ free(prop_enc); -+ free(prop_hostkey); - } - - /* -diff --git a/sshd.c b/sshd.c -index 98a9754..6c77f07 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sshd.c,v 1.578 2021/07/19 02:21:50 dtucker Exp $ */ -+/* $OpenBSD: sshd.c,v 1.589 2022/07/01 03:39:44 dtucker Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -2522,12 +2522,14 @@ do_ssh2_kex(struct ssh *ssh) - { - char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; - struct kex *kex; -+ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; - int r; - -- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, -+ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, - options.kex_algorithms); -- myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh, -- options.ciphers); -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc = -+ compat_cipher_proposal(ssh, options.ciphers); - myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(ssh, - options.ciphers); - myproposal[PROPOSAL_MAC_ALGS_CTOS] = -@@ -2542,8 +2544,8 @@ do_ssh2_kex(struct ssh *ssh) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); - /* coverity[leaked_storage : FALSE]*/ -- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( -- ssh, list_hostkey_types()); -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = -+ compat_pkalg_proposal(ssh, list_hostkey_types()); - - #if defined(GSSAPI) && defined(WITH_OPENSSL) - { -@@ -2639,6 +2641,9 @@ do_ssh2_kex(struct ssh *ssh) - (r = ssh_packet_write_wait(ssh)) != 0) - fatal_fr(r, "send test"); - #endif -+ free(prop_kex); -+ free(prop_enc); -+ free(prop_hostkey); - debug("KEX done"); - } - --- -2.33.0 - diff --git a/backport-Return-ERANGE-from-getcwd-if-buffer-size-is-1.patch b/backport-Return-ERANGE-from-getcwd-if-buffer-size-is-1.patch deleted file mode 100644 index 17387d2156d817d74789fceca7d634d11badaad6..0000000000000000000000000000000000000000 --- a/backport-Return-ERANGE-from-getcwd-if-buffer-size-is-1.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 527cb43fa1b4e55df661feabbac51b8e608b6519 Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Thu, 14 Jul 2022 11:22:08 +1000 -Subject: Return ERANGE from getcwd() if buffer size is 1. - -If getcwd() is supplied a buffer size of exactly 1 and a path of "/", it -could result in a nul byte being written out of array bounds. POSIX says -it should return ERANGE if the path will not fit in the available buffer -(with terminating nul). 1 byte cannot fit any possible path with its nul, -so immediately return ERANGE in that case. - -OpenSSH never uses getcwd() with this buffer size, and all current -(and even quite old) platforms that we are currently known to work -on have a native getcwd() so this code is not used on those anyway. -Reported by Qualys, ok djm@ - -Reference:https://anongit.mindrot.org/openssh.git/patch/?id=527cb43fa1b4e55df661feabbac51b8e608b6519 -Conflict:NA ---- - openbsd-compat/getcwd.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/openbsd-compat/getcwd.c b/openbsd-compat/getcwd.c -index e4f7f5a..a403a01 100644 ---- a/openbsd-compat/getcwd.c -+++ b/openbsd-compat/getcwd.c -@@ -71,9 +71,12 @@ getcwd(char *pt, size_t size) - */ - if (pt) { - ptsize = 0; -- if (!size) { -+ if (size == 0) { - errno = EINVAL; - return (NULL); -+ } else if (size == 1) { -+ errno = ERANGE; -+ return (NULL); - } - ept = pt + size; - } else { --- -2.33.0 - diff --git a/backport-Skip-scp3-test-if-there-s-no-scp-on-remote-path.patch b/backport-Skip-scp3-test-if-there-s-no-scp-on-remote-path.patch deleted file mode 100644 index 60f4b9d47db0487ec19267d3015378eef6cd186d..0000000000000000000000000000000000000000 --- a/backport-Skip-scp3-test-if-there-s-no-scp-on-remote-path.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ea7ecc2c3ae39fdf5c6ad97b7bc0b47a98847f43 Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Sat, 23 Jul 2022 14:36:38 +1000 -Subject: [PATCH] Skip scp3 test if there's no scp on remote path. - -scp -3 ends up using the scp that's in the remote path and will fail if -one is not available. Based on a patch from rapier at psc.edu. - -Reference:https://github.com/openssh/openssh-portable/commit/ea7ecc2c3ae39fdf5c6ad97b7bc0b47a98847f43 -Conflict:NA ---- - regress/scp3.sh | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/regress/scp3.sh b/regress/scp3.sh -index f71b1567..47db47cd 100644 ---- a/regress/scp3.sh -+++ b/regress/scp3.sh -@@ -9,6 +9,12 @@ COPY2=${OBJ}/copy2 - DIR=${COPY}.dd - DIR2=${COPY}.dd2 - -+$SSH -F $OBJ/ssh_proxy somehost \ -+ 'IFS=":"; for i in $PATH;do [ -x "$i/scp" ] && exit 0; done; exit 1' -+if [ $? -eq 1 ]; then -+ skip "No scp on remote path." -+fi -+ - SRC=`dirname ${SCRIPT}` - cp ${SRC}/scp-ssh-wrapper.sh ${OBJ}/scp-ssh-wrapper.scp - chmod 755 ${OBJ}/scp-ssh-wrapper.scp --- -2.23.0 - diff --git a/backport-fix-possible-NULL-deref-when-built-without-FIDO.patch b/backport-fix-possible-NULL-deref-when-built-without-FIDO.patch deleted file mode 100644 index 842149866babca7b870d6e1e7451d7d950c36bdc..0000000000000000000000000000000000000000 --- a/backport-fix-possible-NULL-deref-when-built-without-FIDO.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7d25b37fb2a5ff4dadabcbdac6087a97479434f5 Mon Sep 17 00:00:00 2001 -From: Damien Miller -Date: Fri, 24 Jun 2022 13:46:39 +1000 -Subject: [PATCH] fix possible NULL deref when built without FIDO - -Analysis/fix from kircher in bz3443; ok dtucker@ - -Reference:https://github.com/openssh/openssh-portable/commit/7d25b37fb2a5ff -Conflict:NA ---- - ssh-sk.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/ssh-sk.c b/ssh-sk.c -index a1ff5cc4..ba514607 100644 ---- a/ssh-sk.c -+++ b/ssh-sk.c -@@ -127,10 +127,11 @@ sshsk_open(const char *path) - ret->sk_enroll = ssh_sk_enroll; - ret->sk_sign = ssh_sk_sign; - ret->sk_load_resident_keys = ssh_sk_load_resident_keys; -+ return ret; - #else - error("internal security key support not enabled"); -+ goto fail; - #endif -- return ret; - } - if ((ret->dlhandle = dlopen(path, RTLD_NOW)) == NULL) { - error("Provider \"%s\" dlopen failed: %s", path, dlerror()); --- -2.23.0 - diff --git a/backport-upstream-Always-return-allocated-strings-from-the-ke.patch b/backport-upstream-Always-return-allocated-strings-from-the-ke.patch deleted file mode 100644 index b7febc9f8459877b5730a286a4a43d0bd2d48c81..0000000000000000000000000000000000000000 --- a/backport-upstream-Always-return-allocated-strings-from-the-ke.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 486c4dc3b83b4b67d663fb0fa62bc24138ec3946 Mon Sep 17 00:00:00 2001 -From: "dtucker@openbsd.org" -Date: Fri, 1 Jul 2022 03:35:45 +0000 -Subject: upstream: Always return allocated strings from the kex filtering so - -that we can free them later. Fix one leak in compat_kex_proposal. Based on -github PR#324 from ZoltanFridrich with some simplications by me. ok djm@ - -OpenBSD-Commit-ID: 9171616da3307612d0ede086fd511142f91246e4 - -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/patch/?id=486c4dc3b83b4b67d663fb0fa62bc24138ec3946 ---- - compat.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/compat.c b/compat.c -index 9120bd2..1d50349 100644 ---- a/compat.c -+++ b/compat.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: compat.c,v 1.119 2021/09/10 05:46:09 djm Exp $ */ -+/* $OpenBSD: compat.c,v 1.120 2022/07/01 03:35:45 dtucker Exp $ */ - /* - * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. - * -@@ -156,11 +156,12 @@ compat_banner(struct ssh *ssh, const char *version) - debug_f("no match: %s", version); - } - -+/* Always returns pointer to allocated memory, caller must free. */ - char * - compat_cipher_proposal(struct ssh *ssh, char *cipher_prop) - { - if (!(ssh->compat & SSH_BUG_BIGENDIANAES)) -- return cipher_prop; -+ return xstrdup(cipher_prop); - debug2_f("original cipher proposal: %s", cipher_prop); - if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL) - fatal("match_filter_denylist failed"); -@@ -170,11 +171,12 @@ compat_cipher_proposal(struct ssh *ssh, char *cipher_prop) - return cipher_prop; - } - -+/* Always returns pointer to allocated memory, caller must free. */ - char * - compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) - { - if (!(ssh->compat & SSH_BUG_RSASIGMD5)) -- return pkalg_prop; -+ return xstrdup(pkalg_prop); - debug2_f("original public key proposal: %s", pkalg_prop); - if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL) - fatal("match_filter_denylist failed"); -@@ -184,11 +186,15 @@ compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) - return pkalg_prop; - } - -+/* Always returns pointer to allocated memory, caller must free. */ - char * - compat_kex_proposal(struct ssh *ssh, char *p) - { -+ char *cp = NULL; -+ -+ - if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) -- return p; -+ return xstrdup(p); - debug2_f("original KEX proposal: %s", p); - if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) - /* coverity[overwrite_var : FALSE] */ -@@ -196,11 +202,13 @@ compat_kex_proposal(struct ssh *ssh, char *p) - "curve25519-sha256@libssh.org")) == NULL) - fatal("match_filter_denylist failed"); - if ((ssh->compat & SSH_OLD_DHGEX) != 0) { -+ cp = p; - /* coverity[overwrite_var : FALSE] */ - if ((p = match_filter_denylist(p, - "diffie-hellman-group-exchange-sha256," - "diffie-hellman-group-exchange-sha1")) == NULL) - fatal("match_filter_denylist failed"); -+ free(cp); - } - debug2_f("compat KEX proposal: %s", p); - if (*p == '\0') --- -2.33.0 - diff --git a/backport-upstream-Donot-attempt-to-fprintf-a-null-identity-co.patch b/backport-upstream-Donot-attempt-to-fprintf-a-null-identity-co.patch deleted file mode 100644 index 66f2f908f01ab4dcdd8a10a27bee6143e06c6a56..0000000000000000000000000000000000000000 --- a/backport-upstream-Donot-attempt-to-fprintf-a-null-identity-co.patch +++ /dev/null @@ -1,37 +0,0 @@ -From f29d6cf98c25bf044079032d22c1a57c63ab9d8e Mon Sep 17 00:00:00 2001 -From: "dtucker@openbsd.org" -Date: Sat, 18 Jun 2022 02:17:16 +0000 -Subject: upstream: Don't attempt to fprintf a null identity comment. From - -Martin Vahlensieck via tech@. - -OpenBSD-Commit-ID: 4c54d20a8e8e4e9912c38a7b4ef5bfc5ca2e05c2 - -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/patch/?id=f29d6cf98c25bf044079032d22c1a57c63ab9d8e ---- - ssh-add.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ssh-add.c b/ssh-add.c -index 29c0b17..d60bafc 100644 ---- a/ssh-add.c -+++ b/ssh-add.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: ssh-add.c,v 1.160 2021/04/03 06:18:41 djm Exp $ */ -+/* $OpenBSD: ssh-add.c,v 1.166 2022/06/18 02:17:16 dtucker Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -125,7 +125,7 @@ delete_one(int agent_fd, const struct sshkey *key, const char *comment, - } - if (!qflag) { - fprintf(stderr, "Identity removed: %s %s (%s)\n", path, -- sshkey_type(key), comment); -+ sshkey_type(key), comment ? comment : "no comment"); - } - return 0; - } --- -2.33.0 - diff --git a/backport-upstream-Make-sure-not-to-fclose-the-same-fd-twice-i.patch b/backport-upstream-Make-sure-not-to-fclose-the-same-fd-twice-i.patch deleted file mode 100644 index 1b7739f7336ac4cb42a3794c2127ce4896f9377a..0000000000000000000000000000000000000000 --- a/backport-upstream-Make-sure-not-to-fclose-the-same-fd-twice-i.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 17904f05802988d0bb9ed3c8d1d37411e8f459c3 Mon Sep 17 00:00:00 2001 -From: "tobhe@openbsd.org" -Date: Tue, 21 Jun 2022 14:52:13 +0000 -Subject: upstream: Make sure not to fclose() the same fd twice in case of an - -error. - -ok dtucker@ - -OpenBSD-Commit-ID: e384c4e05d5521e7866b3d53ca59acd2a86eef99 - -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/patch/?id=17904f05802988d0bb9ed3c8d1d37411e8f459c3 - ---- - authfile.c | 19 ++++++++++++------- - 1 file changed, 12 insertions(+), 7 deletions(-) - -diff --git a/authfile.c b/authfile.c -index 8990137..dce1e84 100644 ---- a/authfile.c -+++ b/authfile.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: authfile.c,v 1.141 2020/06/18 23:33:38 djm Exp $ */ -+/* $OpenBSD: authfile.c,v 1.143 2022/06/21 14:52:13 tobhe Exp $ */ - /* - * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. - * -@@ -515,20 +515,25 @@ sshkey_save_public(const struct sshkey *key, const char *path, - return SSH_ERR_SYSTEM_ERROR; - if ((f = fdopen(fd, "w")) == NULL) { - r = SSH_ERR_SYSTEM_ERROR; -+ close(fd); - goto fail; - } - if ((r = sshkey_write(key, f)) != 0) - goto fail; - fprintf(f, " %s\n", comment); -- if (ferror(f) || fclose(f) != 0) { -+ if (ferror(f)) { - r = SSH_ERR_SYSTEM_ERROR; -+ goto fail; -+ } -+ if (fclose(f) != 0) { -+ r = SSH_ERR_SYSTEM_ERROR; -+ f = NULL; - fail: -- oerrno = errno; -- if (f != NULL) -+ if (f != NULL) { -+ oerrno = errno; - fclose(f); -- else -- close(fd); -- errno = oerrno; -+ errno = oerrno; -+ } - return r; - } - return 0; --- -2.33.0 - diff --git a/backport-upstream-a-little-extra-debugging.patch b/backport-upstream-a-little-extra-debugging.patch deleted file mode 100644 index 32701d42a64230c1df5042c83af0d48d50b67a77..0000000000000000000000000000000000000000 --- a/backport-upstream-a-little-extra-debugging.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 940dc10729cb5a95b7ee82c10184e2b9621c8a1d Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Wed, 14 Sep 2022 00:13:13 +0000 -Subject: [PATCH] upstream: a little extra debugging - -OpenBSD-Commit-ID: edf1601c1d0905f6da4c713f4d9cecc7d1c0295a - -Reference:https://github.com/openssh/openssh-portable/commit/940dc10729cb5a95b7ee82c10184e2b9621c8a1d -Conflict:NA ---- - ssh-agent.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/ssh-agent.c b/ssh-agent.c -index ddda4d77..0aef07eb 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: ssh-agent.c,v 1.278 2021/04/03 06:18:41 djm Exp $ */ -+/* $OpenBSD: ssh-agent.c,v 1.291 2022/09/14 00:13:13 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -845,6 +845,7 @@ process_sign_request2(SocketEntry *e) - /* Success */ - ok = 0; - send: -+ debug_f("good signature"); - notify_complete(notifier, "User presence confirmed"); - - if (ok == 0) { --- -2.23.0 - diff --git a/backport-upstream-avoid-integer-overflow-of-auth-attempts-har.patch b/backport-upstream-avoid-integer-overflow-of-auth-attempts-har.patch deleted file mode 100644 index 66ecfdae854dcd2308dde5a174006810aea1b668..0000000000000000000000000000000000000000 --- a/backport-upstream-avoid-integer-overflow-of-auth-attempts-har.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 32ebaa0dbca5d0bb86e384e72bebc153f48413e4 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Wed, 23 Feb 2022 11:18:13 +0000 -Subject: [PATCH] upstream: avoid integer overflow of auth attempts -(harmless,caught by monitor) - -OpenBSD-Commit-ID: 488ad570b003b21e0cd9e7a00349cfc1003b4d86 - -Reference:https://github.com/openssh/openssh-portable/commit/32ebaa0dbca5d0 -Conflict:NA ---- - auth2.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/auth2.c b/auth2.c -index 7290d54..0de58e6 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: auth2.c,v 1.161 2021/04/03 06:18:40 djm Exp $ */ -+/* $OpenBSD: auth2.c,v 1.164 2022/02/23 11:18:13 djm Exp $ */ - /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * -@@ -290,6 +290,8 @@ if (options.check_user_splash) - if ((style = strchr(user, ':')) != NULL) - *style++ = 0; - -+ if (authctxt->attempt >= 1024) -+ auth_maxtries_exceeded(ssh); - if (authctxt->attempt++ == 0) { - /* setup auth context */ - authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); -@@ -298,6 +300,7 @@ if (options.check_user_splash) - authctxt->valid = 1; - debug2_f("setting up authctxt for %s", user); - } else { -+ authctxt->valid = 0; - /* Invalid user, fake password information */ - authctxt->pw = fakepw(); - } --- -2.23.0 - diff --git a/backport-upstream-better-debugging-for-connect_next.patch b/backport-upstream-better-debugging-for-connect_next.patch deleted file mode 100644 index 7d4509b711b8f718a8a6ea8ae0821e0184cd75ed..0000000000000000000000000000000000000000 --- a/backport-upstream-better-debugging-for-connect_next.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 231a346c0c67cc7ca098360f9a554fa7d4f1eddb Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 19 Sep 2022 08:49:50 +0000 -Subject: [PATCH] upstream: better debugging for connect_next() - -OpenBSD-Commit-ID: d16a307a0711499c971807f324484ed3a6036640 - -Reference:https://github.com/openssh/openssh-portable/commit/231a346c0c67cc7ca098360f9a554fa7d4f1eddb -Conflict:NA ---- - channels.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/channels.c b/channels.c -index 3ac51bac..6a78de9d 100644 ---- a/channels.c -+++ b/channels.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: channels.c,v 1.408 2021/09/14 11:04:21 mbuhl Exp $ */ -+/* $OpenBSD: channels.c,v 1.420 2022/09/19 08:49:50 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -4403,13 +4403,15 @@ connect_next(struct channel_connect *cctx) - if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen, - ntop, sizeof(ntop), strport, sizeof(strport), - NI_NUMERICHOST|NI_NUMERICSERV) != 0) { -- error("connect_next: getnameinfo failed"); -+ error_f("getnameinfo failed"); - continue; - } - break; - default: - continue; - } -+ debug_f("start for host %.100s ([%.100s]:%s)", -+ cctx->host, ntop, strport); - if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, - cctx->ai->ai_protocol)) == -1) { - if (cctx->ai->ai_next == NULL) -@@ -4422,9 +4424,8 @@ connect_next(struct channel_connect *cctx) - fatal_f("set_nonblock(%d)", sock); - if (connect(sock, cctx->ai->ai_addr, - cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) { -- debug("connect_next: host %.100s ([%.100s]:%s): " -- "%.100s", cctx->host, ntop, strport, -- strerror(errno)); -+ debug_f("host %.100s ([%.100s]:%s): %.100s", -+ cctx->host, ntop, strport, strerror(errno)); - saved_errno = errno; - close(sock); - errno = saved_errno; -@@ -4432,8 +4433,8 @@ connect_next(struct channel_connect *cctx) - } - if (cctx->ai->ai_family != AF_UNIX) - set_nodelay(sock); -- debug("connect_next: host %.100s ([%.100s]:%s) " -- "in progress, fd=%d", cctx->host, ntop, strport, sock); -+ debug_f("connect host %.100s ([%.100s]:%s) in progress, fd=%d", -+ cctx->host, ntop, strport, sock); - cctx->ai = cctx->ai->ai_next; - return sock; - } --- -2.23.0 - diff --git a/backport-upstream-double-free-in-error-path-from-Eusgor-via-G.patch b/backport-upstream-double-free-in-error-path-from-Eusgor-via-G.patch deleted file mode 100644 index b0e27bbbcad6e9b6fa6948253cf71f44f94c0377..0000000000000000000000000000000000000000 --- a/backport-upstream-double-free-in-error-path-from-Eusgor-via-G.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 5062ad48814b06162511c4f5924a33d97b6b2566 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 19 Aug 2022 03:06:30 +0000 -Subject: upstream: double free() in error path; from Eusgor via GHPR333 - -OpenBSD-Commit-ID: 39f35e16ba878c8d02b4d01d8826d9b321be26d4 - -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/patch/?id=5062ad48814b06162511c4f5924a33d97b6b2566 - ---- - sshsig.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/sshsig.c b/sshsig.c -index 0e8abf1..58c7df4 100644 ---- a/sshsig.c -+++ b/sshsig.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sshsig.c,v 1.21 2021/07/23 04:00:59 djm Exp $ */ -+/* $OpenBSD: sshsig.c,v 1.30 2022/08/19 03:06:30 djm Exp $ */ - /* - * Copyright (c) 2019 Google LLC - * -@@ -491,7 +491,7 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) - { - char *hex, rbuf[8192], hash[SSH_DIGEST_MAX_LENGTH]; - ssize_t n, total = 0; -- struct ssh_digest_ctx *ctx; -+ struct ssh_digest_ctx *ctx = NULL; - int alg, oerrno, r = SSH_ERR_INTERNAL_ERROR; - struct sshbuf *b = NULL; - -@@ -514,7 +514,6 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) - continue; - oerrno = errno; - error_f("read: %s", strerror(errno)); -- ssh_digest_free(ctx); - ctx = NULL; - errno = oerrno; - r = SSH_ERR_SYSTEM_ERROR; -@@ -550,9 +549,11 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) - /* success */ - r = 0; - out: -+ oerrno = errno; - sshbuf_free(b); - ssh_digest_free(ctx); - explicit_bzero(hash, sizeof(hash)); -+ errno = oerrno; - return r; - } - --- -2.33.0 - diff --git a/backport-upstream-if-sshpkt-functions-fail-then-password-is-n.patch b/backport-upstream-if-sshpkt-functions-fail-then-password-is-n.patch deleted file mode 100644 index 618601c0250b67b50f5018f9dcb829734392f91f..0000000000000000000000000000000000000000 --- a/backport-upstream-if-sshpkt-functions-fail-then-password-is-n.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 2c334fd36f80cb91cc42e4b978b10aa35e0df236 Mon Sep 17 00:00:00 2001 -From: "dtucker@openbsd.org" -Date: Fri, 27 May 2022 04:29:40 +0000 -Subject: upstream: f sshpkt functions fail, then password is not cleared - -with freezero. Unconditionally call freezero to guarantee that password is -removed from RAM. - -From tobias@ and c3h2_ctf via github PR#286, ok djm@ - -OpenBSD-Commit-ID: 6b093619c9515328e25b0f8093779c52402c89cd - -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/commit?id=2c334fd36f80cb91cc42e4b978b10aa35e0df236 - ---- - auth2-passwd.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/auth2-passwd.c b/auth2-passwd.c -index be4b860..1d80481 100644 ---- a/auth2-passwd.c -+++ b/auth2-passwd.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: auth2-passwd.c,v 1.19 2020/10/18 11:32:01 djm Exp $ */ -+/* $OpenBSD: auth2-passwd.c,v 1.21 2022/05/27 04:29:40 dtucker Exp $ */ - /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * -@@ -51,16 +51,18 @@ extern ServerOptions options; - static int - userauth_passwd(struct ssh *ssh) - { -- char *password; -+ char *password = NULL; - int authenticated = 0, r; - u_char change; -- size_t len; -+ size_t len = 0; - - if ((r = sshpkt_get_u8(ssh, &change)) != 0 || - (r = sshpkt_get_cstring(ssh, &password, &len)) != 0 || - (change && (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) || -- (r = sshpkt_get_end(ssh)) != 0) -+ (r = sshpkt_get_end(ssh)) != 0) { -+ freezero(password, len); - fatal_fr(r, "parse packet"); -+ } - - if (change) - logit("password change not supported"); --- -2.33.0 - diff --git a/backport-upstream-ignore-SIGPIPE-earlier-in-main-specifically.patch b/backport-upstream-ignore-SIGPIPE-earlier-in-main-specifically.patch deleted file mode 100644 index 1a540c67eab8ae19bb69309ebff2401f3d3c0fb4..0000000000000000000000000000000000000000 --- a/backport-upstream-ignore-SIGPIPE-earlier-in-main-specifically.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 96faa0de6c673a2ce84736eba37fc9fb723d9e5c Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 1 Jul 2022 00:36:30 +0000 -Subject: upstream: ignore SIGPIPE earlier in main(), specifically before - -muxclient() which performs operations that could cause one; Reported by Noam -Lewis via bz3454, ok dtucker@ - -OpenBSD-Commit-ID: 63d8e13276869eebac6d7a05d5a96307f9026e47 - -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/patch/?id=96faa0de6c673a2ce84736eba37fc9fb723d9e5c ---- - ssh.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/ssh.c b/ssh.c -index f55ff73..e987cd5 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: ssh.c,v 1.569 2021/09/20 04:02:13 dtucker Exp $ */ -+/* $OpenBSD: ssh.c,v 1.575 2022/07/01 00:36:30 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -1135,6 +1135,8 @@ main(int ac, char **av) - } - } - -+ ssh_signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ -+ - /* - * Initialize "log" output. Since we are the client all output - * goes to stderr unless otherwise specified by -y or -E. -@@ -1660,7 +1662,6 @@ main(int ac, char **av) - options.num_system_hostfiles); - tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles); - -- ssh_signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ - ssh_signal(SIGCHLD, main_sigchld_handler); - - /* Log into the remote system. Never returns if the login fails. */ --- -2.33.0 - diff --git a/backport-upstream-ssh-keygen-Y-check-novalidate-requires-name.patch b/backport-upstream-ssh-keygen-Y-check-novalidate-requires-name.patch deleted file mode 100644 index aa9f80c168661ffc7be1b8732fd9a23853ab315a..0000000000000000000000000000000000000000 --- a/backport-upstream-ssh-keygen-Y-check-novalidate-requires-name.patch +++ /dev/null @@ -1,41 +0,0 @@ -From a0b5816f8f1f645acdf74f7bc11b34455ec30bac Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 18 Mar 2022 02:31:25 +0000 -Subject: [PATCH] upstream: ssh-keygen -Y check-novalidate requires namespace - or SEGV - -will ensue. Patch from Mateusz Adamowski via GHPR#307 - -OpenBSD-Commit-ID: 99e8ec38f9feb38bce6de240335be34aedeba5fd -Reference:https://github.com/openssh/openssh-portable/commit/a0b5816f8f1f645acdf74f7bc11b34455ec30bac -Conflict:NA ---- - ssh-keygen.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 7fc616c..bd6ea16 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: ssh-keygen.c,v 1.437 2021/09/08 03:23:44 djm Exp $ */ -+/* $OpenBSD: ssh-keygen.c,v 1.449 2022/03/18 02:31:25 djm Exp $ */ - /* - * Author: Tatu Ylonen - * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland -@@ -3489,6 +3489,12 @@ main(int argc, char **argv) - return sig_sign(identity_file, cert_principals, - argc, argv); - } else if (strncmp(sign_op, "check-novalidate", 16) == 0) { -+ if (cert_principals == NULL || -+ *cert_principals == '\0') { -+ error("Too few arguments for check-novalidate: " -+ "missing namespace"); -+ exit(1); -+ } - if (ca_key_path == NULL) { - error("Too few arguments for check-novalidate: " - "missing signature file"); --- -2.23.0 - diff --git a/bugfix-openssh-add-option-check-username-splash.patch b/bugfix-openssh-add-option-check-username-splash.patch index 9293230bc3e61e13637eac6e70697458434ddbf0..3a1b23789498549db877bed669153745e030daa4 100644 --- a/bugfix-openssh-add-option-check-username-splash.patch +++ b/bugfix-openssh-add-option-check-username-splash.patch @@ -6,7 +6,6 @@ Subject: [PATCH] openssh: add option check username splash add a check to inhibit username contains splash add an option 'CheckUserSplash' so that user can turn off this check - --- auth2.c | 4 +++- servconf.c | 8 ++++++++ @@ -15,10 +14,10 @@ this check 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/auth2.c b/auth2.c -index 4adc502..956b9cf 100644 +index 203ba01..284ea19 100644 --- a/auth2.c +++ b/auth2.c -@@ -282,11 +282,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) +@@ -281,11 +281,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) debug("userauth-request for user %s service %s method %s", user, service, method); debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); @@ -34,10 +33,10 @@ index 4adc502..956b9cf 100644 *style++ = 0; diff --git a/servconf.c b/servconf.c -index 7001d56..76147f9 100644 +index d72fb62..6888971 100644 --- a/servconf.c +++ b/servconf.c -@@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options) +@@ -201,6 +201,7 @@ initialize_server_options(ServerOptions *options) options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; @@ -45,7 +44,7 @@ index 7001d56..76147f9 100644 options->fingerprint_hash = -1; options->disable_forwarding = -1; options->expose_userauth_info = -1; -@@ -473,6 +474,8 @@ fill_default_server_options(ServerOptions *options) +@@ -460,6 +461,8 @@ fill_default_server_options(ServerOptions *options) options->ip_qos_bulk = IPTOS_DSCP_CS1; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); @@ -54,15 +53,15 @@ index 7001d56..76147f9 100644 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) options->fwd_opts.streamlocal_bind_mask = 0177; if (options->fwd_opts.streamlocal_bind_unlink == -1) -@@ -574,6 +577,7 @@ typedef enum { - sStreamLocalBindMask, sStreamLocalBindUnlink, +@@ -553,6 +556,7 @@ typedef enum { sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, + sRequiredRSASize, + sCheckUserSplash, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; -@@ -740,6 +744,7 @@ static struct { +@@ -726,6 +730,7 @@ static struct { { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, @@ -70,7 +69,7 @@ index 7001d56..76147f9 100644 { "rdomain", sRDomain, SSHCFG_ALL }, { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, -@@ -1360,6 +1365,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1384,6 +1389,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, case sUsePAM: intptr = &options->use_pam; goto parse_flag; @@ -81,30 +80,27 @@ index 7001d56..76147f9 100644 /* Standard Options */ case sBadOption: diff --git a/servconf.h b/servconf.h -index a3827e5..2c16b5a 100644 +index 77fd779..694addf 100644 --- a/servconf.h +++ b/servconf.h -@@ -226,6 +226,7 @@ typedef struct { +@@ -237,6 +237,7 @@ typedef struct { int fingerprint_hash; int expose_userauth_info; u_int64_t timing_secret; -+ int check_user_splash; /* check whether splash exists in username, if exist, disable login */ ++ int check_user_splash; /* check whether splash exists in username, if exist, disable login */ char *sk_provider; + int required_rsa_size; /* minimum size of RSA keys */ } ServerOptions; - diff --git a/sshd_config b/sshd_config -index ebc28b3..b121450 100644 +index 6d47368..973aecf 100644 --- a/sshd_config +++ b/sshd_config -@@ -125,6 +125,8 @@ Subsystem sftp /usr/libexec/sftp-server - # Example of overriding settings on a per-user basis - #Match User anoncvs - # X11Forwarding no +@@ -128,3 +128,5 @@ Subsystem sftp /usr/libexec/sftp-server # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server +#CheckUserSplash yes + -- -2.23.0 +2.27.0 diff --git a/feature-add-SMx-support.patch b/feature-add-SMx-support.patch index 1eb45b9c69112489f7955ea99caa0e9d4269a1d6..0a9e567431ba9d429a74f4c94113970a34d13fec 100644 --- a/feature-add-SMx-support.patch +++ b/feature-add-SMx-support.patch @@ -18,12 +18,12 @@ FingerprintHash sm3 digest.h | 3 +- kex.c | 1 + kex.h | 3 + - kexecdh.c | 22 ++- + kexecdh.c | 23 +- kexgen.c | 3 + - kexsm2.c | 29 ++++ + kexsm2.c | 406 ++++++++++++++++++++++++++ mac.c | 1 + pathnames.h | 1 + - regress/agent.sh | 8 + + regress/agent.sh | 9 + regress/keytype.sh | 2 + regress/knownhosts-command.sh | 1 + regress/misc/fuzz-harness/sig_fuzz.cc | 4 + @@ -31,18 +31,18 @@ FingerprintHash sm3 ssh-ecdsa.c | 6 +- ssh-keygen.c | 12 +- ssh-keyscan.c | 12 +- - ssh-sm2.c | 232 ++++++++++++++++++++++++++ + ssh-sm2.c | 230 +++++++++++++++ ssh_api.c | 2 + sshconnect2.c | 1 + sshd.c | 7 + - sshkey.c | 62 ++++++- + sshkey.c | 62 +++- sshkey.h | 9 + - 27 files changed, 417 insertions(+), 16 deletions(-) + 27 files changed, 794 insertions(+), 16 deletions(-) create mode 100644 kexsm2.c create mode 100644 ssh-sm2.c diff --git a/Makefile.in b/Makefile.in -index 07bf440..fb8b006 100644 +index 07bf440..1393190 100644 --- a/Makefile.in +++ b/Makefile.in @@ -100,14 +100,14 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ @@ -50,7 +50,7 @@ index 07bf440..fb8b006 100644 readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ atomicio.o dispatch.o mac.o misc.o utf8.o \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ -+ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o ssh-sm2.o \ ++ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-sm2.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 \ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ @@ -76,7 +76,7 @@ index 9f092f7..163b4b5 100644 case KEY_ECDSA_SK_CERT: #endif diff --git a/authfile.c b/authfile.c -index d7827ed..8990137 100644 +index 666730b..dce1e84 100644 --- a/authfile.c +++ b/authfile.c @@ -343,6 +343,7 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase, @@ -88,31 +88,31 @@ index d7827ed..8990137 100644 case KEY_ED25519: case KEY_XMSS: diff --git a/cipher.c b/cipher.c -index b54b994..16bfdcb 100644 +index b54b994..039e414 100644 --- a/cipher.c +++ b/cipher.c @@ -88,6 +88,7 @@ static const struct sshcipher ciphers[] = { #endif { "chacha20-poly1305@openssh.com", 8, 64, 0, 16, CFLAG_CHACHAPOLY, NULL }, -+ { "sm4-ctr", 16, 16, 0, 0, 0, EVP_sm4_ctr }, ++ { "sm4-ctr", 16, 16, 0, 0, 0, EVP_sm4_ctr }, { "none", 8, 0, 0, 0, CFLAG_NONE, NULL }, { NULL, 0, 0, 0, 0, 0, NULL } diff --git a/digest-openssl.c b/digest-openssl.c -index 94730e9..a93924b 100644 +index 94730e9..fa92360 100644 --- a/digest-openssl.c +++ b/digest-openssl.c @@ -61,6 +61,7 @@ const struct ssh_digest digests[] = { { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, -+ { SSH_DIGEST_SM3, "SM3", 32, EVP_sm3 }, ++ { SSH_DIGEST_SM3, "SM3", 32, EVP_sm3 }, { -1, NULL, 0, NULL }, }; diff --git a/digest.h b/digest.h -index c7ceeb3..e42affe 100644 +index c7ceeb3..520722c 100644 --- a/digest.h +++ b/digest.h @@ -27,7 +27,8 @@ @@ -120,7 +120,7 @@ index c7ceeb3..e42affe 100644 #define SSH_DIGEST_SHA384 3 #define SSH_DIGEST_SHA512 4 -#define SSH_DIGEST_MAX 5 -+#define SSH_DIGEST_SM3 5 ++#define SSH_DIGEST_SM3 5 +#define SSH_DIGEST_MAX 6 struct sshbuf; @@ -159,7 +159,7 @@ index d26ba26..8b95227 100644 void dump_digest(const char *, const u_char *, int); #endif diff --git a/kexecdh.c b/kexecdh.c -index efb2e55..a780517 100644 +index efb2e55..69ec13b 100644 --- a/kexecdh.c +++ b/kexecdh.c @@ -44,7 +44,7 @@ @@ -176,7 +176,7 @@ index efb2e55..a780517 100644 goto out; if ((r = kex_ecdh_dec_key_group(kex, client_blob, server_key, group, - shared_secretp)) != 0) -+ shared_secretp, 0)) != 0) ++ shared_secretp, 1)) != 0) goto out; *server_blobp = server_blob; server_blob = NULL; @@ -189,7 +189,7 @@ index efb2e55..a780517 100644 { struct sshbuf *buf = NULL; BIGNUM *shared_secret = NULL; -@@ -176,10 +176,18 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, +@@ -176,11 +176,20 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -209,14 +209,16 @@ index efb2e55..a780517 100644 + goto out; + } } ++ #ifdef DEBUG_KEXECDH dump_digest("shared secret", kbuf, klen); -@@ -203,7 +211,7 @@ kex_ecdh_dec(struct kex *kex, const struct sshbuf *server_blob, + #endif +@@ -203,7 +212,7 @@ kex_ecdh_dec(struct kex *kex, const struct sshbuf *server_blob, int r; r = kex_ecdh_dec_key_group(kex, server_blob, kex->ec_client_key, - kex->ec_group, shared_secretp); -+ kex->ec_group, shared_secretp, 1); ++ kex->ec_group, shared_secretp, 0); EC_KEY_free(kex->ec_client_key); kex->ec_client_key = NULL; return r; @@ -250,17 +252,394 @@ index 31f90f5..f3eff47 100644 break; diff --git a/kexsm2.c b/kexsm2.c new file mode 100644 -index 0000000..f9b8bb9 +index 0000000..f507557 --- /dev/null +++ b/kexsm2.c -@@ -0,0 +1,29 @@ +@@ -0,0 +1,406 @@ +#include +#include +#include ++#include +#include +#include -+#include -+#include ++ ++int sm2_compute_z_digest(uint8_t *out, ++ const EVP_MD *digest, ++ const uint8_t *id, ++ const size_t id_len, ++ const EC_KEY *key) ++{ ++ int rc = 0; ++ const EC_GROUP *group = EC_KEY_get0_group(key); ++ BN_CTX *ctx = NULL; ++ EVP_MD_CTX *hash = NULL; ++ BIGNUM *p = NULL; ++ BIGNUM *a = NULL; ++ BIGNUM *b = NULL; ++ BIGNUM *xG = NULL; ++ BIGNUM *yG = NULL; ++ BIGNUM *xA = NULL; ++ BIGNUM *yA = NULL; ++ int p_bytes = 0; ++ uint8_t *buf = NULL; ++ uint16_t entl = 0; ++ uint8_t e_byte = 0; ++ ++ hash = EVP_MD_CTX_new(); ++ ctx = BN_CTX_new(); ++ if (hash == NULL || ctx == NULL) { ++ goto done; ++ } ++ ++ p = BN_CTX_get(ctx); ++ a = BN_CTX_get(ctx); ++ b = BN_CTX_get(ctx); ++ xG = BN_CTX_get(ctx); ++ yG = BN_CTX_get(ctx); ++ xA = BN_CTX_get(ctx); ++ yA = BN_CTX_get(ctx); ++ ++ if (yA == NULL) { ++ goto done; ++ } ++ ++ if (!EVP_DigestInit(hash, digest)) { ++ goto done; ++ } ++ ++ /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */ ++ ++ if (id_len >= (UINT16_MAX / 8)) { ++ /* too large */ ++ goto done; ++ } ++ ++ entl = (uint16_t)(8 * id_len); ++ ++ e_byte = entl >> 8; ++ if (!EVP_DigestUpdate(hash, &e_byte, 1)) { ++ goto done; ++ } ++ e_byte = entl & 0xFF; ++ if (!EVP_DigestUpdate(hash, &e_byte, 1)) { ++ goto done; ++ } ++ ++ if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) { ++ goto done; ++ } ++ ++ if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { ++ goto done; ++ } ++ ++ p_bytes = BN_num_bytes(p); ++ buf = OPENSSL_zalloc(p_bytes); ++ if (buf == NULL) { ++ goto done; ++ } ++ ++ if (BN_bn2binpad(a, buf, p_bytes) < 0 ++ || !EVP_DigestUpdate(hash, buf, p_bytes) ++ || BN_bn2binpad(b, buf, p_bytes) < 0 ++ || !EVP_DigestUpdate(hash, buf, p_bytes) ++ || !EC_POINT_get_affine_coordinates(group, ++ EC_GROUP_get0_generator(group), ++ xG, yG, ctx) ++ || BN_bn2binpad(xG, buf, p_bytes) < 0 ++ || !EVP_DigestUpdate(hash, buf, p_bytes) ++ || BN_bn2binpad(yG, buf, p_bytes) < 0 ++ || !EVP_DigestUpdate(hash, buf, p_bytes) ++ || !EC_POINT_get_affine_coordinates(group, ++ EC_KEY_get0_public_key(key), ++ xA, yA, ctx) ++ || BN_bn2binpad(xA, buf, p_bytes) < 0 ++ || !EVP_DigestUpdate(hash, buf, p_bytes) ++ || BN_bn2binpad(yA, buf, p_bytes) < 0 ++ || !EVP_DigestUpdate(hash, buf, p_bytes) ++ || !EVP_DigestFinal(hash, out, NULL)) { ++ goto done; ++ } ++ ++ rc = 1; ++ ++ done: ++ OPENSSL_free(buf); ++ BN_CTX_free(ctx); ++ EVP_MD_CTX_free(hash); ++ return rc; ++} ++ ++ ++/* GM/T003_2012 Defined Key Derive Function */ ++int kdf_gmt003_2012(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *SharedInfo, size_t SharedInfolen, const EVP_MD *md) ++{ ++ EVP_MD_CTX *mctx = NULL; ++ unsigned int counter; ++ unsigned char ctr[4]; ++ size_t mdlen; ++ int retval = 0; ++ unsigned char dgst[EVP_MAX_MD_SIZE]; ++ ++ if (!out || !outlen) return retval; ++ if (md == NULL) { ++ md = EVP_sm3(); ++ } ++ mdlen = EVP_MD_size(md); ++ mctx = EVP_MD_CTX_new(); ++ if (mctx == NULL) { ++ goto err; ++ } ++ ++ for (counter = 1;; counter++) { ++ if (!EVP_DigestInit(mctx, md)) { ++ goto err; ++ } ++ ctr[0] = (unsigned char)((counter >> 24) & 0xFF); ++ ctr[1] = (unsigned char)((counter >> 16) & 0xFF); ++ ctr[2] = (unsigned char)((counter >> 8) & 0xFF); ++ ctr[3] = (unsigned char)(counter & 0xFF); ++ ++ if (!EVP_DigestUpdate(mctx, Z, Zlen)) { ++ goto err; ++ } ++ if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr))) { ++ goto err; ++ } ++ if (!EVP_DigestUpdate(mctx, SharedInfo, SharedInfolen)) { ++ goto err; ++ } ++ if (!EVP_DigestFinal(mctx, dgst, NULL)) { ++ goto err; ++ } ++ ++ if (outlen > mdlen) { ++ memcpy(out, dgst, mdlen); ++ out += mdlen; ++ outlen -= mdlen; ++ } else { ++ memcpy(out, dgst, outlen); ++ memset(dgst, 0, mdlen); ++ break; ++ } ++ } ++ ++ retval = 1; ++ ++err: ++ EVP_MD_CTX_free(mctx); ++ return retval; ++} ++ ++int sm2_kap_compute_key(void *out, size_t outlen, int server,\ ++ const uint8_t *peer_uid, int peer_uid_len, const uint8_t *self_uid, int self_uid_len, \ ++ const EC_KEY *peer_ecdhe_key, const EC_KEY *self_ecdhe_key, const EC_KEY *peer_pub_key, const EC_KEY *self_eckey, \ ++ const EVP_MD *md) ++{ ++ BN_CTX *ctx = NULL; ++ EC_POINT *UorV = NULL; ++ const EC_POINT *Rs, *Rp; ++ BIGNUM *Xs = NULL, *Xp = NULL, *h = NULL, *t = NULL, *two_power_w = NULL, *order = NULL; ++ const BIGNUM *priv_key, *r; ++ const EC_GROUP *group; ++ int w; ++ int ret = -1; ++ size_t buflen, len; ++ unsigned char *buf = NULL; ++ ++ if (outlen > INT_MAX) { ++ goto err; ++ } ++ ++ if (!peer_pub_key || !self_eckey) { ++ goto err; ++ } ++ ++ priv_key = EC_KEY_get0_private_key(self_eckey); ++ if (!priv_key) { ++ goto err; ++ } ++ ++ if (!peer_ecdhe_key || !self_ecdhe_key) { ++ goto err; ++ } ++ ++ Rs = EC_KEY_get0_public_key(self_ecdhe_key); ++ Rp = EC_KEY_get0_public_key(peer_ecdhe_key); ++ r = EC_KEY_get0_private_key(self_ecdhe_key); ++ ++ if (!Rs || !Rp || !r) { ++ goto err; ++ } ++ ++ ctx = BN_CTX_new(); ++ Xs = BN_new(); ++ Xp = BN_new(); ++ h = BN_new(); ++ t = BN_new(); ++ two_power_w = BN_new(); ++ order = BN_new(); ++ if (!Xs || !Xp || !h || !t || !two_power_w || !order) { ++ goto err; ++ } ++ ++ group = EC_KEY_get0_group(self_eckey); ++ ++ /*Second: Caculate -- w*/ ++ if (!EC_GROUP_get_order(group, order, ctx) || !EC_GROUP_get_cofactor(group, h, ctx)) { ++ goto err; ++ } ++ ++ w = (BN_num_bits(order) + 1) / 2 - 1; ++ if (!BN_lshift(two_power_w, BN_value_one(), w)) { ++ goto err; ++ } ++ ++ /*Third: Caculate -- X = 2 ^ w + (x & (2 ^ w - 1)) = 2 ^ w + (x mod 2 ^ w)*/ ++ UorV = EC_POINT_new(group); ++ ++ if (!UorV) { ++ goto err; ++ } ++ ++ /*Test peer public key On curve*/ ++ if (!EC_POINT_is_on_curve(group, Rp, ctx)) { ++ goto err; ++ } ++ ++ /*Get x*/ ++ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { ++ if (!EC_POINT_get_affine_coordinates_GFp(group, Rs, Xs, NULL, ctx)) { ++ goto err; ++ } ++ ++ if (!EC_POINT_get_affine_coordinates_GFp(group, Rp, Xp, NULL, ctx)) { ++ goto err; ++ } ++ } ++ ++ /*x mod 2 ^ w*/ ++ /*Caculate Self x*/ ++ if (!BN_nnmod(Xs, Xs, two_power_w, ctx)) { ++ goto err; ++ } ++ ++ if (!BN_add(Xs, Xs, two_power_w)) { ++ goto err; ++ } ++ ++ /*Caculate Peer x*/ ++ if (!BN_nnmod(Xp, Xp, two_power_w, ctx)) { ++ goto err; ++ } ++ ++ if (!BN_add(Xp, Xp, two_power_w)) { ++ goto err; ++ } ++ ++ /*Forth: Caculate t*/ ++ if (!BN_mod_mul(t, Xs, r, order, ctx)) { ++ goto err; ++ } ++ ++ if (!BN_mod_add(t, t, priv_key, order, ctx)) { ++ goto err; ++ } ++ ++ /*Fifth: Caculate V or U*/ ++ if (!BN_mul(t, t, h, ctx)) { ++ goto err; ++ } ++ ++ /* [x]R */ ++ if (!EC_POINT_mul(group, UorV, NULL, Rp, Xp, ctx)) { ++ goto err; ++ } ++ ++ /* P + [x]R */ ++ if (!EC_POINT_add(group, UorV, UorV, EC_KEY_get0_public_key(peer_pub_key), ctx)) { ++ goto err; ++ } ++ ++ if (!EC_POINT_mul(group, UorV, NULL, UorV, t, ctx)) { ++ goto err; ++ } ++ ++ /* Detect UorV is in */ ++ if (EC_POINT_is_at_infinity(group, UorV)) { ++ goto err; ++ } ++ ++ /*Sixth: Caculate Key -- Need Xuorv, Yuorv, Zc, Zs, klen*/ ++ { ++ /* ++ size_t buflen, len; ++ unsigned char *buf = NULL; ++ */ ++ size_t elemet_len, idx; ++ ++ elemet_len = (size_t)((EC_GROUP_get_degree(group) + 7) / 8); ++ buflen = elemet_len * 2 + 32 * 2 + 1; /*add 1 byte tag*/ ++ buf = (unsigned char *)OPENSSL_malloc(buflen + 10); ++ if (!buf) { ++ goto err; ++ } ++ memset(buf, 0, buflen + 10); ++ /*1 : Get public key for UorV, Notice: the first byte is a tag, not a valid char*/ ++ idx = EC_POINT_point2oct(group, UorV, 4, buf, buflen, ctx); ++ if (!idx) { ++ goto err; ++ } ++ ++ if (!server) { ++ /*SIDE A*/ ++ len = buflen - idx; ++ if (!sm2_compute_z_digest( (unsigned char *)(buf + idx), md, (const uint8_t *)self_uid, self_uid_len, self_eckey)) { ++ goto err; ++ } ++ len = 32; ++ idx += len; ++ } ++ ++ /*Caculate Peer Z*/ ++ len = buflen - idx; ++ if (!sm2_compute_z_digest( (unsigned char *)(buf + idx), md, (const uint8_t *)peer_uid, peer_uid_len, peer_pub_key)) { ++ goto err; ++ } ++ len = 32; ++ idx += len; ++ ++ if (server) { ++ /*SIDE B*/ ++ len = buflen - idx; ++ if (!sm2_compute_z_digest( (unsigned char *)(buf + idx), md, (const uint8_t *)self_uid, self_uid_len, self_eckey)) { ++ goto err; ++ } ++ len = 32; ++ idx += len; ++ } ++ ++ len = outlen; ++ if (!kdf_gmt003_2012(out, len, (const unsigned char *)(buf + 1), idx - 1, NULL, 0, md)) { ++ goto err; ++ } ++ } ++ ++ ret = outlen; ++ ++err: ++ if (Xs) BN_free(Xs); ++ if (Xp) BN_free(Xp); ++ if (h) BN_free(h); ++ if (t) BN_free(t); ++ if (two_power_w) BN_free(two_power_w); ++ if (order) BN_free(order); ++ if (UorV) EC_POINT_free(UorV); ++ if (buf) OPENSSL_free(buf); ++ if (ctx) BN_CTX_free(ctx); ++ ++ return ret; ++} + +int SM2KAP_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, int server) +{ @@ -277,41 +656,41 @@ index 0000000..f9b8bb9 + goto out; + } + -+ ret = SM2_compute_key(out, outlen, server, id, sizeof(id), id, sizeof(id), pubkey, eckey, pubkey, eckey, (EVP_MD*)EVP_sm3()); ++ ret = sm2_kap_compute_key(out, outlen, server, id, sizeof(id), id, sizeof(id), pubkey, eckey, pubkey, eckey, (EVP_MD*)EVP_sm3()); + +out: + EC_KEY_free(pubkey); + return ret; +} diff --git a/mac.c b/mac.c -index bf051ba..d643dc8 100644 +index bf051ba..2de17a0 100644 --- a/mac.c +++ b/mac.c @@ -65,6 +65,7 @@ static const struct macalg macs[] = { { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -+ { "hmac-sm3", SSH_DIGEST, SSH_DIGEST_SM3, 0, 0, 0, 0 }, ++ { "hmac-sm3", SSH_DIGEST, SSH_DIGEST_SM3, 0, 0, 0, 0 }, /* Encrypt-then-MAC variants */ { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, diff --git a/pathnames.h b/pathnames.h -index a094888..0323fac 100644 +index a094888..0a805ad 100644 --- a/pathnames.h +++ b/pathnames.h @@ -80,6 +80,7 @@ #define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR "/id_xmss" #define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR "/id_ecdsa_sk" #define _PATH_SSH_CLIENT_ID_ED25519_SK _PATH_SSH_USER_DIR "/id_ed25519_sk" -+#define _PATH_SSH_CLIENT_ID_SM2 _PATH_SSH_USER_DIR "/id_sm2" ++#define _PATH_SSH_CLIENT_ID_SM2 _PATH_SSH_USER_DIR "/id_sm2" /* * Configuration file in user's home directory. This file need not be diff --git a/regress/agent.sh b/regress/agent.sh -index f187b67..046c2a6 100644 +index f187b67..42a5124 100644 --- a/regress/agent.sh +++ b/regress/agent.sh -@@ -87,9 +87,17 @@ fi +@@ -87,9 +87,18 @@ fi for t in ${SSH_KEYTYPES}; do trace "connect via agent using $t key" if [ "$t" = "ssh-dss" ]; then @@ -326,6 +705,7 @@ index f187b67..046c2a6 100644 + echo "PubkeyAcceptedAlgorithms +sm2,sm2-cert" >> $OBJ/ssh_proxy + echo "PubkeyAcceptedAlgorithms +sm2,sm2-cert" >> $OBJ/sshd_proxy + fi ++ ${SSH} -F $OBJ/ssh_proxy -i $OBJ/$t-agent.pub -oIdentitiesOnly=yes \ somehost exit 52 r=$? @@ -384,17 +764,17 @@ index b32502b..f260692 100644 sshkey_verify(ed25519, sig, slen, (const u_char *)data, dlen, NULL, 0, &details); sshkey_sig_details_free(details); diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c -index 3bd71a9..9c537d1 100644 +index 3bd71a9..312e8f2 100644 --- a/regress/unittests/kex/test_kex.c +++ b/regress/unittests/kex/test_kex.c -@@ -153,6 +153,7 @@ do_kex_with_key(char *kex, int keytype, int bits) +@@ -152,6 +152,7 @@ do_kex_with_key(char *kex, int keytype, int bits) + #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ server2->kex->kex[KEX_C25519_SHA256] = kex_gen_server; - server2->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + server2->kex->kex[KEX_SM2_SM3] = kex_gen_server; + server2->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; server2->kex->load_host_public_key = server->kex->load_host_public_key; server2->kex->load_host_private_key = server->kex->load_host_private_key; - server2->kex->sign = server->kex->sign; @@ -186,6 +187,7 @@ do_kex(char *kex) #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -412,7 +792,7 @@ index 3bd71a9..9c537d1 100644 do_kex("sntrup761x25519-sha512@openssh.com"); # endif /* USE_SNTRUP761X25519 */ diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c -index b036796..7eed8ae 100644 +index b036796..6697be6 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -66,7 +66,8 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, @@ -420,8 +800,8 @@ index b036796..7eed8ae 100644 if (key == NULL || key->ecdsa == NULL || - sshkey_type_plain(key->type) != KEY_ECDSA) -+ (sshkey_type_plain(key->type) != KEY_ECDSA && -+ sshkey_type_plain(key->type) != KEY_SM2)) ++ (sshkey_type_plain(key->type) != KEY_ECDSA && ++ sshkey_type_plain(key->type) != KEY_SM2)) return SSH_ERR_INVALID_ARGUMENT; if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) @@ -430,13 +810,13 @@ index b036796..7eed8ae 100644 if (key == NULL || key->ecdsa == NULL || - sshkey_type_plain(key->type) != KEY_ECDSA || -+ (sshkey_type_plain(key->type) != KEY_ECDSA && -+ sshkey_type_plain(key->type) != KEY_SM2) || ++ (sshkey_type_plain(key->type) != KEY_ECDSA && ++ sshkey_type_plain(key->type) != KEY_SM2) || signature == NULL || signaturelen == 0) return SSH_ERR_INVALID_ARGUMENT; diff --git a/ssh-keygen.c b/ssh-keygen.c -index e04bade..7fc616c 100644 +index b9c4dce..bd6ea16 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -192,6 +192,7 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) @@ -494,14 +874,14 @@ index e04bade..7fc616c 100644 " ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n" " [-P old_passphrase] [-Z cipher]\n" diff --git a/ssh-keyscan.c b/ssh-keyscan.c -index 9ec4d9a..94a734c 100644 +index 9ec4d9a..be2af0a 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -63,9 +63,10 @@ int ssh_port = SSH_DEFAULT_PORT; #define KT_XMSS (1<<4) #define KT_ECDSA_SK (1<<5) #define KT_ED25519_SK (1<<6) -+#define KT_SM2 (1<<7) ++#define KT_SM2 (1<<7) #define KT_MIN KT_DSA -#define KT_MAX KT_ED25519_SK @@ -515,9 +895,9 @@ index 9ec4d9a..94a734c 100644 break; + case KT_SM2: + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? -+ "sm2-cert" : -+ "sm2"; -+ break; ++ "sm2-cert" : ++ "sm2"; ++ break; case KT_ECDSA_SK: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" : @@ -535,16 +915,16 @@ index 9ec4d9a..94a734c 100644 break; + case KEY_SM2: + get_keytypes |= KT_SM2; -+ break; ++ break; case KEY_RSA: get_keytypes |= KT_RSA; break; diff --git a/ssh-sm2.c b/ssh-sm2.c new file mode 100644 -index 0000000..4d452e4 +index 0000000..c242139 --- /dev/null +++ b/ssh-sm2.c -@@ -0,0 +1,232 @@ +@@ -0,0 +1,220 @@ +#include "includes.h" +#include +#include @@ -566,25 +946,24 @@ index 0000000..4d452e4 + const u_char *data, size_t datalen, u_int compat) +{ + u_char *sig = NULL; -+ size_t slen = 0; ++ size_t slen = 0; + int pkey_len = 0; + int r = 0; + int len = 0; + EVP_PKEY *key_sm2 = NULL; -+ struct sshbuf *b = NULL; ++ struct sshbuf *b = NULL; + EVP_PKEY_CTX *pctx = NULL; + EVP_MD_CTX *mctx = NULL; -+ int ret = SSH_ERR_INTERNAL_ERROR; ++ int ret = SSH_ERR_INTERNAL_ERROR; + -+ if (lenp != NULL) -+ *lenp = 0; -+ if (sigp != NULL) -+ *sigp = NULL; ++ if (lenp != NULL) ++ *lenp = 0; ++ if (sigp != NULL) ++ *sigp = NULL; + + if (key == NULL || key->ecdsa == NULL || -+ sshkey_type_plain(key->type) != KEY_SM2) { ++ sshkey_type_plain(key->type) != KEY_SM2) + return SSH_ERR_INVALID_ARGUMENT; -+ } + + if ((key_sm2 = EVP_PKEY_new()) == NULL) { + return SSH_ERR_ALLOC_FAIL; @@ -595,85 +974,79 @@ index 0000000..4d452e4 + goto out; + } + -+ if ((pkey_len = EVP_PKEY_size(key_sm2)) == 0) { -+ ret = SSH_ERR_INVALID_ARGUMENT; -+ goto out; -+ } ++ if ((pkey_len = EVP_PKEY_size(key_sm2)) == 0) { ++ ret = SSH_ERR_INVALID_ARGUMENT; ++ goto out; ++ } + + slen = pkey_len; -+ -+ if ((EVP_PKEY_set_alias_type(key_sm2, EVP_PKEY_SM2)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ -+ if ((sig = OPENSSL_malloc(pkey_len)) == NULL) { ++ ++ if ((sig = OPENSSL_malloc(pkey_len)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; -+ } ++ } + + if ((pctx = EVP_PKEY_CTX_new(key_sm2, NULL)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; -+ goto out; ++ goto out; + } + + if (EVP_PKEY_CTX_set1_id(pctx, sm2_id, 16) != 1) { + ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; ++ goto out; + } -+ ++ + if ((mctx = EVP_MD_CTX_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; + } + + EVP_MD_CTX_set_pkey_ctx(mctx, pctx); + -+ if ((EVP_DigestSignInit(mctx, NULL, EVP_sm3(), NULL, key_sm2)) != 1) { ++ if ((EVP_DigestSignInit(mctx, NULL, EVP_sm3(), NULL, key_sm2)) != 1) { + ret = SSH_ERR_INTERNAL_ERROR; + goto out; + } + -+ if ((EVP_DigestSignUpdate(mctx, data, datalen)) != 1) { ++ if ((EVP_DigestSignUpdate(mctx, data, datalen)) != 1) { + ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; ++ goto out; + } -+ ++ + if ((EVP_DigestSignFinal(mctx, sig, &slen)) != 1) { + ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; ++ goto out; + } + + if ((b = sshbuf_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if ((r = sshbuf_put_cstring(b, "sm2")) != 0 || -+ (r = sshbuf_put_string(b, sig, slen)) != 0) -+ goto out; ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + ++ if ((r = sshbuf_put_cstring(b, "sm2")) != 0 || ++ (r = sshbuf_put_string(b, sig, slen)) != 0) ++ goto out; + len = sshbuf_len(b); + if (sigp != NULL) { -+ if ((*sigp = malloc(len)) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ memcpy(*sigp, sshbuf_ptr(b), len); -+ } ++ if ((*sigp = malloc(len)) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ memcpy(*sigp, sshbuf_ptr(b), len); ++ } + if (lenp != NULL) -+ *lenp = len; ++ *lenp = len; + ret = 0; + +out: + EVP_PKEY_free(key_sm2); -+ if (sig != NULL){ -+ explicit_bzero(sig, slen); -+ OPENSSL_free(sig); -+ } ++ if (sig != NULL) { ++ explicit_bzero(sig, slen); ++ OPENSSL_free(sig); ++ } + EVP_PKEY_CTX_free(pctx); + EVP_MD_CTX_free(mctx); -+ sshbuf_free(b); ++ sshbuf_free(b); + return ret; +} + @@ -685,95 +1058,90 @@ index 0000000..4d452e4 + const u_char *sig = NULL; + char *ktype = NULL; + size_t slen = 0; -+ int pkey_len = 0; -+ int r = 0; -+ int len = 0; ++ int pkey_len = 0; ++ int r = 0; ++ int len = 0; + EVP_PKEY *key_sm2 = NULL; -+ struct sshbuf *b = NULL; -+ EVP_PKEY_CTX *pctx = NULL; -+ EVP_MD_CTX *mctx = NULL; -+ int ret = SSH_ERR_INTERNAL_ERROR; ++ struct sshbuf *b = NULL; ++ EVP_PKEY_CTX *pctx = NULL; ++ EVP_MD_CTX *mctx = NULL; ++ int ret = SSH_ERR_INTERNAL_ERROR; + -+ if (key == NULL || -+ sshkey_type_plain(key->type) != KEY_SM2 || -+ signature == NULL || signaturelen == 0) -+ return SSH_ERR_INVALID_ARGUMENT; ++ if (key == NULL || ++ sshkey_type_plain(key->type) != KEY_SM2 || ++ signature == NULL || signaturelen == 0) ++ return SSH_ERR_INVALID_ARGUMENT; + -+ if ((b = sshbuf_from(signature, signaturelen)) == NULL) -+ return SSH_ERR_ALLOC_FAIL; ++ if ((b = sshbuf_from(signature, signaturelen)) == NULL) ++ return SSH_ERR_ALLOC_FAIL; + -+ if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 || -+ (r = sshbuf_get_string_direct(b, &sig, &slen)) != 0) -+ goto out; ++ if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 || ++ (r = sshbuf_get_string_direct(b, &sig, &slen)) != 0) ++ goto out; + + if (strcmp("sm2", ktype) != 0) { -+ ret = SSH_ERR_KEY_TYPE_MISMATCH; -+ goto out; ++ ret = SSH_ERR_KEY_TYPE_MISMATCH; ++ goto out; + } + -+ if (sshbuf_len(b) != 0) { -+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; -+ goto out; -+ } ++ if (sshbuf_len(b) != 0) { ++ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; ++ goto out; ++ } + -+ if ((key_sm2 = EVP_PKEY_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } ++ if ((key_sm2 = EVP_PKEY_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + -+ if ((EVP_PKEY_set1_EC_KEY(key_sm2, key->ecdsa)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } ++ if ((EVP_PKEY_set1_EC_KEY(key_sm2, key->ecdsa)) != 1) { ++ ret = SSH_ERR_INTERNAL_ERROR; ++ goto out; ++ } + -+ if ((pkey_len = EVP_PKEY_size(key_sm2)) == 0) { -+ ret = SSH_ERR_INVALID_ARGUMENT; -+ goto out; -+ } -+ -+ if ((EVP_PKEY_set_alias_type(key_sm2, EVP_PKEY_SM2)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } ++ if ((pkey_len = EVP_PKEY_size(key_sm2)) == 0) { ++ ret = SSH_ERR_INVALID_ARGUMENT; ++ goto out; ++ } + + if ((pctx = EVP_PKEY_CTX_new(key_sm2, NULL)) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + -+ if (EVP_PKEY_CTX_set1_id(pctx, sm2_id, 16) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } ++ if (EVP_PKEY_CTX_set1_id(pctx, sm2_id, 16) != 1) { ++ ret = SSH_ERR_INTERNAL_ERROR; ++ goto out; ++ } + -+ if ((mctx = EVP_MD_CTX_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } ++ if ((mctx = EVP_MD_CTX_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + + EVP_MD_CTX_set_pkey_ctx(mctx, pctx); + -+ if ((EVP_DigestVerifyInit(mctx, NULL, EVP_sm3(), NULL, key_sm2)) != 1) { ++ if ((EVP_DigestVerifyInit(mctx, NULL, EVP_sm3(), NULL, key_sm2)) != 1) { + ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; ++ goto out; + } -+ ++ + if ((EVP_DigestVerifyUpdate(mctx, data, datalen)) != 1) { + ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; ++ goto out; + } -+ ++ + if ((EVP_DigestVerifyFinal(mctx, sig, slen)) != 1) { + ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; ++ goto out; + } + + ret = 0; +out: + EVP_PKEY_free(key_sm2); -+ EVP_PKEY_CTX_free(pctx); -+ EVP_MD_CTX_free(mctx); -+ sshbuf_free(b); ++ EVP_PKEY_CTX_free(pctx); ++ EVP_MD_CTX_free(mctx); ++ sshbuf_free(b); + free(ktype); + return ret; +} @@ -798,7 +1166,7 @@ index d3c6617..adc2598 100644 #endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; diff --git a/sshconnect2.c b/sshconnect2.c -index aa32ece..e90eb89 100644 +index fafc0a2..9a01f1a 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -327,6 +327,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, @@ -810,7 +1178,7 @@ index aa32ece..e90eb89 100644 # ifdef GSSAPI if (options.gss_keyex) { diff --git a/sshd.c b/sshd.c -index b7b0c18..dd7cdee 100644 +index 8424e33..57d70fe 100644 --- a/sshd.c +++ b/sshd.c @@ -706,6 +706,7 @@ list_hostkey_types(void) @@ -856,7 +1224,7 @@ index b7b0c18..dd7cdee 100644 case KEY_ED25519: case KEY_ECDSA_SK: case KEY_ED25519_SK: -@@ -2570,6 +2576,7 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2572,6 +2578,7 @@ do_ssh2_kex(struct ssh *ssh) kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; @@ -865,7 +1233,7 @@ index b7b0c18..dd7cdee 100644 # ifdef GSSAPI if (options.gss_keyex) { diff --git a/sshkey.c b/sshkey.c -index b0c2189..1b70488 100644 +index b0c2189..51f8e51 100644 --- a/sshkey.c +++ b/sshkey.c @@ -159,6 +159,8 @@ static const struct keytype keytypes[] = { @@ -886,15 +1254,15 @@ index b0c2189..1b70488 100644 return 1; } return 0; -@@ -340,6 +344,8 @@ sshkey_size(const struct sshkey *k) - return BN_num_bits(dsa_p); - case KEY_ECDSA: +@@ -342,6 +346,8 @@ sshkey_size(const struct sshkey *k) case KEY_ECDSA_CERT: -+ case KEY_SM2: -+ case KEY_SM2_CERT: case KEY_ECDSA_SK: case KEY_ECDSA_SK_CERT: ++ case KEY_SM2: ++ case KEY_SM2_CERT: return sshkey_curve_nid_to_bits(k->ecdsa_nid); + #endif /* WITH_OPENSSL */ + case KEY_ED25519: @@ -366,6 +372,8 @@ sshkey_type_is_valid_ca(int type) case KEY_ED25519: case KEY_ED25519_SK: @@ -936,19 +1304,19 @@ index b0c2189..1b70488 100644 return "nistp521"; # endif /* OPENSSL_HAS_NISTP521 */ + case NID_sm2: -+ return "sm2"; ++ return "sm2"; default: return NULL; } -@@ -693,6 +709,8 @@ sshkey_new(int type) - break; - case KEY_ECDSA: +@@ -695,6 +711,8 @@ sshkey_new(int type) case KEY_ECDSA_CERT: -+ case KEY_SM2: -+ case KEY_SM2_CERT: case KEY_ECDSA_SK: case KEY_ECDSA_SK_CERT: ++ case KEY_SM2: ++ case KEY_SM2_CERT: /* Cannot do anything until we know the group */ + break; + #endif /* WITH_OPENSSL */ @@ -749,6 +767,8 @@ sshkey_free(struct sshkey *k) /* FALLTHROUGH */ case KEY_ECDSA: @@ -962,8 +1330,8 @@ index b0c2189..1b70488 100644 /* FALLTHROUGH */ case KEY_ECDSA_CERT: case KEY_ECDSA: -+ case KEY_SM2_CERT: + case KEY_SM2: ++ case KEY_SM2_CERT: if (a->ecdsa == NULL || b->ecdsa == NULL || EC_KEY_get0_public_key(a->ecdsa) == NULL || EC_KEY_get0_public_key(b->ecdsa) == NULL) @@ -1026,7 +1394,7 @@ index b0c2189..1b70488 100644 - &k->ecdsa); + &k->ecdsa, 0); + break; -+ case KEY_SM2: ++ case KEY_SM2: + ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid, + &k->ecdsa, 1); break; @@ -1049,14 +1417,14 @@ index b0c2189..1b70488 100644 case KEY_ECDSA_SK_CERT: /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { -@@ -2556,6 +2593,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, - } +@@ -2557,6 +2594,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, /* FALLTHROUGH */ case KEY_ECDSA: -+ case KEY_SM2: case KEY_ECDSA_SK: ++ case KEY_SM2: if ((key = sshkey_new(type)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; + goto out; @@ -2865,6 +2903,10 @@ sshkey_sign(struct sshkey *key, case KEY_ECDSA: r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat); @@ -1189,5 +1557,5 @@ index 43eef5e..3b84096 100644 #if !defined(WITH_OPENSSL) -- -2.33.0 +2.23.0 diff --git a/feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch b/feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch index 3fa984dd5f92aab25c3401a2a41680e58de0f2db..7af483cdf03eb969610d9f145af70f97fd9c2a6f 100644 --- a/feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch +++ b/feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch @@ -1,19 +1,20 @@ From 6d98c61e18fe65a52e21df9cece74675f9c18125 Mon Sep 17 00:00:00 2001 -From: s00467541 +From: shenyining Date: Thu, 16 Apr 2020 17:13:24 +0800 Subject: [PATCH] sync patch, add new judgement and delete default sftp-put-check.cfg -Signed-off-by: s00467541 +Signed-off-by: shenyining + --- - sftp-server.c | 703 +++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 691 insertions(+), 12 deletions(-) + sftp-server.c | 702 +++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 690 insertions(+), 12 deletions(-) diff --git a/sftp-server.c b/sftp-server.c -index 01d6f8f..682c19a 100644 +index 5677aa3..4eb06d1 100644 --- a/sftp-server.c +++ b/sftp-server.c -@@ -29,6 +29,12 @@ +@@ -30,6 +30,12 @@ #include #endif @@ -26,7 +27,7 @@ index 01d6f8f..682c19a 100644 #include #include #include -@@ -51,6 +57,17 @@ +@@ -57,6 +63,17 @@ #include "sftp.h" #include "sftp-common.h" @@ -44,7 +45,7 @@ index 01d6f8f..682c19a 100644 char *sftp_realpath(const char *, char *); /* sftp-realpath.c */ /* Maximum data read that we are willing to accept */ -@@ -89,6 +106,452 @@ struct Stat { +@@ -98,6 +115,452 @@ struct Stat { Attrib attrib; }; @@ -497,7 +498,7 @@ index 01d6f8f..682c19a 100644 /* Packet handlers */ static void process_open(u_int32_t id); static void process_close(u_int32_t id); -@@ -695,6 +1158,15 @@ process_open(u_int32_t id) +@@ -755,6 +1218,15 @@ process_open(u_int32_t id) (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ (r = decode_attrib(iqueue, &a)) != 0) fatal_fr(r, "parse"); @@ -513,7 +514,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: open flags %d", id, pflags); flags = flags_from_portable(pflags); -@@ -728,6 +1200,8 @@ process_open(u_int32_t id) +@@ -788,6 +1260,8 @@ process_open(u_int32_t id) (void) umask(old_umask); /* restore umask to something sane */ if (status != SSH2_FX_OK) send_status(id, status); @@ -522,7 +523,7 @@ index 01d6f8f..682c19a 100644 free(name); } -@@ -759,6 +1233,17 @@ process_read(u_int32_t id) +@@ -820,6 +1294,17 @@ process_read(u_int32_t id) (r = sshbuf_get_u32(iqueue, &len)) != 0) fatal_fr(r, "parse"); @@ -540,7 +541,7 @@ index 01d6f8f..682c19a 100644 debug("request %u: read \"%s\" (handle %d) off %llu len %u", id, handle_to_name(handle), handle, (unsigned long long)off, len); if ((fd = handle_to_fd(handle)) == -1) -@@ -800,6 +1285,18 @@ process_write(u_int32_t id) +@@ -874,6 +1359,18 @@ process_write(u_int32_t id) (r = sshbuf_get_string(iqueue, &data, &len)) != 0) fatal_fr(r, "parse"); @@ -559,7 +560,7 @@ index 01d6f8f..682c19a 100644 debug("request %u: write \"%s\" (handle %d) off %llu len %zu", id, handle_to_name(handle), handle, (unsigned long long)off, len); fd = handle_to_fd(handle); -@@ -813,17 +1310,30 @@ process_write(u_int32_t id) +@@ -888,17 +1385,30 @@ process_write(u_int32_t id) strerror(errno)); } else { /* XXX ATOMICIO ? */ @@ -600,7 +601,7 @@ index 01d6f8f..682c19a 100644 } } } -@@ -841,6 +1352,16 @@ process_do_stat(u_int32_t id, int do_lstat) +@@ -917,6 +1427,16 @@ process_do_stat(u_int32_t id, int do_lstat) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal_fr(r, "parse"); @@ -617,7 +618,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: %sstat", id, do_lstat ? "l" : ""); verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); r = do_lstat ? lstat(name, &st) : stat(name, &st); -@@ -877,6 +1398,16 @@ process_fstat(u_int32_t id) +@@ -953,6 +1473,16 @@ process_fstat(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) fatal_fr(r, "parse"); @@ -634,7 +635,7 @@ index 01d6f8f..682c19a 100644 debug("request %u: fstat \"%s\" (handle %u)", id, handle_to_name(handle), handle); fd = handle_to_fd(handle); -@@ -929,6 +1460,14 @@ process_setstat(u_int32_t id) +@@ -1005,6 +1535,14 @@ process_setstat(u_int32_t id) (r = decode_attrib(iqueue, &a)) != 0) fatal_fr(r, "parse"); @@ -649,7 +650,7 @@ index 01d6f8f..682c19a 100644 debug("request %u: setstat name \"%s\"", id, name); if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", -@@ -983,6 +1522,13 @@ process_fsetstat(u_int32_t id) +@@ -1059,6 +1597,13 @@ process_fsetstat(u_int32_t id) else { char *name = handle_to_name(handle); @@ -663,7 +664,7 @@ index 01d6f8f..682c19a 100644 if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a.size); -@@ -1040,6 +1586,14 @@ process_opendir(u_int32_t id) +@@ -1116,6 +1661,14 @@ process_opendir(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal_fr(r, "parse"); @@ -678,18 +679,17 @@ index 01d6f8f..682c19a 100644 debug3("request %u: opendir", id); logit("opendir \"%s\"", path); dirp = opendir(path); -@@ -1094,6 +1648,10 @@ process_readdir(u_int32_t id) +@@ -1170,6 +1723,9 @@ process_readdir(u_int32_t id) strcmp(path, "/") ? "/" : "", dp->d_name); if (lstat(pathname, &st) == -1) continue; -+ if (RETURN_OK != path_permition_check(pathname,FLAG_PERMITOP)) -+ { -+ continue; -+ } ++ if (RETURN_OK != path_permition_check(pathname,FLAG_PERMITOP)) { ++ continue; ++ } stat_to_attrib(&st, &(stats[count].attrib)); stats[count].name = xstrdup(dp->d_name); - stats[count].long_name = ls_file(dp->d_name, &st, 0, 0); -@@ -1125,6 +1683,14 @@ process_remove(u_int32_t id) + stats[count].long_name = ls_file(dp->d_name, &st, +@@ -1202,6 +1758,14 @@ process_remove(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal_fr(r, "parse"); @@ -704,7 +704,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: remove", id); logit("remove name \"%s\"", name); r = unlink(name); -@@ -1144,6 +1710,14 @@ process_mkdir(u_int32_t id) +@@ -1221,6 +1785,14 @@ process_mkdir(u_int32_t id) (r = decode_attrib(iqueue, &a)) != 0) fatal_fr(r, "parse"); @@ -719,7 +719,7 @@ index 01d6f8f..682c19a 100644 mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm & 07777 : 0777; debug3("request %u: mkdir", id); -@@ -1163,6 +1737,14 @@ process_rmdir(u_int32_t id) +@@ -1240,6 +1812,14 @@ process_rmdir(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal_fr(r, "parse"); @@ -734,7 +734,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); r = rmdir(name); -@@ -1187,8 +1769,12 @@ process_realpath(u_int32_t id) +@@ -1264,8 +1844,12 @@ process_realpath(u_int32_t id) } debug3("request %u: realpath", id); verbose("realpath \"%s\"", path); @@ -749,7 +749,7 @@ index 01d6f8f..682c19a 100644 } else { Stat s; attrib_clear(&s.attrib); -@@ -1209,6 +1795,16 @@ process_rename(u_int32_t id) +@@ -1286,6 +1870,16 @@ process_rename(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal_fr(r, "parse"); @@ -766,7 +766,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: rename", id); logit("rename old \"%s\" new \"%s\"", oldpath, newpath); status = SSH2_FX_FAILURE; -@@ -1268,6 +1864,14 @@ process_readlink(u_int32_t id) +@@ -1345,6 +1939,14 @@ process_readlink(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal_fr(r, "parse"); @@ -781,7 +781,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: readlink", id); verbose("readlink \"%s\"", path); if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) -@@ -1293,6 +1897,16 @@ process_symlink(u_int32_t id) +@@ -1370,6 +1972,16 @@ process_symlink(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal_fr(r, "parse"); @@ -798,7 +798,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ -@@ -1313,6 +1927,16 @@ process_extended_posix_rename(u_int32_t id) +@@ -1390,6 +2002,16 @@ process_extended_posix_rename(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal_fr(r, "parse"); @@ -815,7 +815,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); r = rename(oldpath, newpath); -@@ -1331,6 +1955,15 @@ process_extended_statvfs(u_int32_t id) +@@ -1408,6 +2030,15 @@ process_extended_statvfs(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal_fr(r, "parse"); @@ -831,7 +831,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: statvfs", id); logit("statvfs \"%s\"", path); -@@ -1349,6 +1982,17 @@ process_extended_fstatvfs(u_int32_t id) +@@ -1426,6 +2057,17 @@ process_extended_fstatvfs(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) fatal_fr(r, "parse"); @@ -849,7 +849,7 @@ index 01d6f8f..682c19a 100644 debug("request %u: fstatvfs \"%s\" (handle %u)", id, handle_to_name(handle), handle); if ((fd = handle_to_fd(handle)) < 0) { -@@ -1371,6 +2015,15 @@ process_extended_hardlink(u_int32_t id) +@@ -1448,6 +2090,15 @@ process_extended_hardlink(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal_fr(r, "parse"); @@ -865,7 +865,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: hardlink", id); logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath); r = link(oldpath, newpath); -@@ -1387,6 +2040,17 @@ process_extended_fsync(u_int32_t id) +@@ -1464,6 +2115,17 @@ process_extended_fsync(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) fatal_fr(r, "parse"); @@ -883,7 +883,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: fsync (handle %u)", id, handle); verbose("fsync \"%s\"", handle_to_name(handle)); if ((fd = handle_to_fd(handle)) < 0) -@@ -1672,6 +2336,22 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle +@@ -2006,6 +2668,22 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); @@ -907,5 +907,5 @@ index 01d6f8f..682c19a 100644 * On platforms where we can, avoid making /proc/self/{mem,maps} * available to the user so that sftp access doesn't automatically -- -2.23.0 +2.27.0 diff --git a/openssh-5.8p2-sigpipe.patch b/openssh-5.8p2-sigpipe.patch index 56af045eae3345321228940764359c0fa9c81759..4147dcba40cd88ebc3f5baffc099c70a7a481727 100644 --- a/openssh-5.8p2-sigpipe.patch +++ b/openssh-5.8p2-sigpipe.patch @@ -1,12 +1,15 @@ +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-5.8p2-sigpipe.patch diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c --- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200 +++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200 -@@ -715,6 +715,8 @@ main(int argc, char **argv) +@@ -715,6 +715,9 @@ main(int argc, char **argv) + if (maxfd > fdlim_get(0)) fdlim_set(maxfd); fdcon = xcalloc(maxfd, sizeof(con)); - ++ + signal(SIGPIPE, SIG_IGN); + - read_wait_nfdset = howmany(maxfd, NFDBITS); - read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); + read_wait = xcalloc(maxfd, sizeof(struct pollfd)); + for (j = 0; j < maxfd; j++) + read_wait[j].fd = -1; diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 426c1727d167a90f41107fcf67fe7191febecb13..9e626a5fc0c42aa807c0fdc0e5606258488a0c84 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -1,3 +1,4 @@ +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-6.6.1p1-log-in-chroot.patch diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c --- openssh-8.6p1/log.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 +++ openssh-8.6p1/log.c 2021-04-19 14:43:08.544843434 +0200 @@ -207,8 +208,8 @@ diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c -sftp_server_main(int argc, char **argv, struct passwd *user_pw) +sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler) { - fd_set *rset, *wset; - int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; + int i, r, in, out, ch, skipargs = 0, log_stderr = 0; + ssize_t len, olen; @@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv, extern char *__progname; diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 2aa14bd44e420e4e5a87f56dc6df9da1d935e5cd..2e0318fae2e9e46b47d930032fb3c40baf3d1b1e 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,3 +1,4 @@ +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-6.6p1-keycat.patch diff -up openssh/misc.c.keycat openssh/misc.c --- openssh/misc.c.keycat 2015-06-24 10:57:50.158849606 +0200 +++ openssh/misc.c 2015-06-24 11:04:23.989868638 +0200 @@ -61,13 +62,13 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in ssh-xmss.o \ @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) - $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) + $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o -+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS) ++ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS) $(CHANNELLIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) - $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS) @@ -321,6 +325,7 @@ install-files: $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 930de695266cb117a05b906dad8caa17861e8a1c..d13a22741a40cd0bb6c67a79616936753fa7940d 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -1,41 +1,38 @@ -diff -up openssh-8.5p1/addr.c.coverity openssh-8.5p1/addr.c ---- openssh-8.5p1/addr.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/addr.c 2021-03-24 12:03:33.782968159 +0100 -@@ -312,8 +312,10 @@ addr_pton(const char *p, struct xaddr *n - if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) - return -1; - -- if (ai == NULL || ai->ai_addr == NULL) -+ if (ai == NULL || ai->ai_addr == NULL) { -+ freeaddrinfo(ai); - return -1; -+ } - - if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, - n) == -1) { -@@ -336,12 +338,16 @@ addr_sa_pton(const char *h, const char * - if (h == NULL || getaddrinfo(h, s, &hints, &ai) != 0) - return -1; - -- if (ai == NULL || ai->ai_addr == NULL) -+ if (ai == NULL || ai->ai_addr == NULL) { -+ freeaddrinfo(ai); - return -1; -+ } - - if (sa != NULL) { -- if (slen < ai->ai_addrlen) -+ if (slen < ai->ai_addrlen) { -+ freeaddrinfo(ai); - return -1; -+ } - memcpy(sa, &ai->ai_addr, ai->ai_addrlen); - } - -diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c ---- openssh-8.5p1/auth-krb5.c.coverity 2021-03-24 12:03:33.724967756 +0100 -+++ openssh-8.5p1/auth-krb5.c 2021-03-24 12:03:33.782968159 +0100 -@@ -426,6 +426,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-6.7p1-coverity.patch + +--- + auth-krb5.c | 2 ++ + auth-options.c | 1 + + channels.c | 6 ++++-- + dns.c | 1 + + gss-genr.c | 3 ++- + kexgssc.c | 4 +++- + krl.c | 4 ++++ + loginrec.c | 4 ++++ + misc.c | 3 +++ + moduli.c | 1 + + monitor.c | 4 ++-- + monitor_wrap.c | 6 +++--- + openbsd-compat/bindresvport.c | 2 +- + openbsd-compat/bsd-pselect.c | 8 ++++---- + readconf.c | 1 + + scp.c | 4 ++-- + servconf.c | 5 +++-- + serverloop.c | 2 +- + session.c | 2 ++ + sftp.c | 3 ++- + ssh-agent.c | 5 +++-- + ssh-keygen.c | 7 +++++++ + ssh.c | 1 + + sshd.c | 9 +++++++-- + sshsig.c | 1 + + 25 files changed, 65 insertions(+), 24 deletions(-) + +diff --git a/auth-krb5.c b/auth-krb5.c +index d80c3ab..71ea1e3 100644 +--- a/auth-krb5.c ++++ b/auth-krb5.c +@@ -426,6 +426,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm umask(old_umask); if (tmpfd == -1) { logit("mkstemp(): %.100s", strerror(oerrno)); @@ -43,7 +40,7 @@ diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c return oerrno; } -@@ -433,6 +434,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, +@@ -433,6 +434,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm oerrno = errno; logit("fchmod(): %.100s", strerror(oerrno)); close(tmpfd); @@ -51,10 +48,11 @@ 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 * +diff --git a/auth-options.c b/auth-options.c +index 7cb2a64..a4b1db4 100644 +--- a/auth-options.c ++++ b/auth-options.c +@@ -723,6 +723,7 @@ serialise_array(struct sshbuf *m, char **a, size_t n) return r; } /* success */ @@ -62,19 +60,11 @@ diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c return 0; } -diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c ---- openssh-7.4p1/channels.c.coverity 2016-12-23 16:40:26.881788686 +0100 -+++ openssh-7.4p1/channels.c 2016-12-23 16:42:36.244818763 +0100 -@@ -1875,7 +1875,7 @@ channel_post_connecting(struct ssh *ssh, - debug("channel %d: connection failed: %s", - c->self, strerror(err)); - /* Try next address, if any */ -- if ((sock = connect_next(&c->connect_ctx)) > 0) { -+ if ((sock = connect_next(&c->connect_ctx)) >= 0) { - close(c->sock); - c->sock = c->rfd = c->wfd = sock; - channel_find_maxfd(ssh->chanctxt); -@@ -3804,7 +3804,7 @@ int +diff --git a/channels.c b/channels.c +index 300c753..ea4d8da 100644 +--- a/channels.c ++++ b/channels.c +@@ -4081,7 +4081,7 @@ int channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) { int r, success = 0, idx = -1; @@ -83,7 +73,7 @@ diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c int port_to_connect, listen_port; /* Send the forward request to the remote side. */ -@@ -3832,7 +3832,6 @@ channel_request_remote_forwarding(struct +@@ -4109,7 +4109,6 @@ channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) success = 1; if (success) { /* Record that connection to this host/port is permitted. */ @@ -91,7 +81,7 @@ diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c port_to_connect = listen_port = 0; if (fwd->connect_path != NULL) { host_to_connect = xstrdup(fwd->connect_path); -@@ -3853,6 +3852,9 @@ channel_request_remote_forwarding(struct +@@ -4130,6 +4129,9 @@ channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) host_to_connect, port_to_connect, listen_host, listen_path, listen_port, NULL); } @@ -101,37 +91,23 @@ diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c return idx; } -diff -up openssh-8.5p1/compat.c.coverity openssh-8.5p1/compat.c ---- openssh-8.5p1/compat.c.coverity 2021-03-24 12:03:33.768968062 +0100 -+++ openssh-8.5p1/compat.c 2021-03-24 12:03:33.783968166 +0100 -@@ -191,10 +191,12 @@ compat_kex_proposal(struct ssh *ssh, cha - return p; - debug2_f("original KEX proposal: %s", p); - if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) -+ /* coverity[overwrite_var : FALSE] */ - if ((p = match_filter_denylist(p, - "curve25519-sha256@libssh.org")) == NULL) - fatal("match_filter_denylist failed"); - if ((ssh->compat & SSH_OLD_DHGEX) != 0) { -+ /* coverity[overwrite_var : FALSE] */ - if ((p = match_filter_denylist(p, - "diffie-hellman-group-exchange-sha256," - "diffie-hellman-group-exchange-sha1")) == NULL) -diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c ---- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 -@@ -282,6 +282,7 @@ verify_host_key_dns(const char *hostname - &hostkey_digest, &hostkey_digest_len, hostkey)) { - error("Error calculating key fingerprint."); - freerrset(fingerprints); +diff --git a/dns.c b/dns.c +index f2310be..15218f1 100644 +--- a/dns.c ++++ b/dns.c +@@ -259,6 +259,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, + &hostkey_digest, &hostkey_digest_len, hostkey)) { + error("Error calculating key fingerprint."); + freerrset(fingerprints); + free(dnskey_digest); - return -1; - } - -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 -@@ -167,8 +167,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + return -1; + } + +diff --git a/gss-genr.c b/gss-genr.c +index 9f9745b..810b382 100644 +--- a/gss-genr.c ++++ b/gss-genr.c +@@ -168,8 +168,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, enclen = __b64_ntop(digest, ssh_digest_bytes(SSH_DIGEST_MD5), encoded, ssh_digest_bytes(SSH_DIGEST_MD5) * 2); @@ -142,9 +118,10 @@ 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 +diff --git a/kexgssc.c b/kexgssc.c +index 1c62740..080cf04 100644 +--- a/kexgssc.c ++++ b/kexgssc.c @@ -98,8 +98,10 @@ kexgss_client(struct ssh *ssh) default: fatal_f("Unexpected KEX type %d", kex->kex_type); @@ -157,10 +134,11 @@ diff -up openssh-8.5p1/kexgssc.c.coverity openssh-8.5p1/kexgssc.c 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 +diff --git a/krl.c b/krl.c +index 473a9d7..ae19762 100644 +--- a/krl.c ++++ b/krl.c +@@ -1209,6 +1209,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, sshkey_free(key); sshbuf_free(copy); sshbuf_free(sect); @@ -168,7 +146,7 @@ diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c return r; } -@@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons +@@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); free(rb.blob); @@ -176,7 +154,7 @@ diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c if (erb != NULL) { KRL_DBG(("revoked by key SHA1")); return SSH_ERR_KEY_REVOKED; -@@ -1271,6 +1273,7 @@ is_key_revoked(struct ssh_krl *krl, cons +@@ -1271,6 +1273,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb); free(rb.blob); @@ -184,7 +162,7 @@ diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c if (erb != NULL) { KRL_DBG(("revoked by key SHA256")); return SSH_ERR_KEY_REVOKED; -@@ -1282,6 +1285,7 @@ is_key_revoked(struct ssh_krl *krl, cons +@@ -1282,6 +1285,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); free(rb.blob); @@ -192,10 +170,11 @@ diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c if (erb != NULL) { KRL_DBG(("revoked by explicit key")); return SSH_ERR_KEY_REVOKED; -diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c ---- openssh-8.5p1/loginrec.c.coverity 2021-03-24 13:18:53.793225885 +0100 -+++ openssh-8.5p1/loginrec.c 2021-03-24 13:21:27.948404751 +0100 -@@ -690,9 +690,11 @@ construct_utmp(struct logininfo *li, +diff --git a/loginrec.c b/loginrec.c +index 4f21499..e0606be 100644 +--- a/loginrec.c ++++ b/loginrec.c +@@ -691,9 +691,11 @@ construct_utmp(struct logininfo *li, */ /* Use strncpy because we don't necessarily want null termination */ @@ -207,7 +186,7 @@ diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); # endif -@@ -1690,6 +1692,7 @@ record_failed_login(struct ssh *ssh, con +@@ -1691,6 +1693,7 @@ record_failed_login(struct ssh *ssh, const char *username, const char *hostname, memset(&ut, 0, sizeof(ut)); /* strncpy because we don't necessarily want nul termination */ @@ -215,7 +194,7 @@ diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c strncpy(ut.ut_user, username, sizeof(ut.ut_user)); strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); -@@ -1699,6 +1702,7 @@ record_failed_login(struct ssh *ssh, con +@@ -1700,6 +1703,7 @@ record_failed_login(struct ssh *ssh, const char *username, const char *hostname, ut.ut_pid = getpid(); /* strncpy because we don't necessarily want nul termination */ @@ -223,10 +202,11 @@ diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); if (ssh_packet_connection_is_on_socket(ssh) && -diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c ---- openssh-8.5p1/misc.c.coverity 2021-03-24 12:03:33.745967902 +0100 -+++ openssh-8.5p1/misc.c 2021-03-24 13:31:47.037079617 +0100 -@@ -1425,6 +1425,8 @@ sanitise_stdfd(void) +diff --git a/misc.c b/misc.c +index e4d3120..5420e24 100644 +--- a/misc.c ++++ b/misc.c +@@ -1492,6 +1492,8 @@ sanitise_stdfd(void) } if (nullfd > STDERR_FILENO) close(nullfd); @@ -235,7 +215,7 @@ diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c } char * -@@ -2511,6 +2513,7 @@ stdfd_devnull(int do_stdin, int do_stdou +@@ -2625,6 +2627,7 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) } if (devnull > STDERR_FILENO) close(devnull); @@ -243,10 +223,11 @@ diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c return ret; } -diff -up openssh-8.5p1/moduli.c.coverity openssh-8.5p1/moduli.c ---- openssh-8.5p1/moduli.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/moduli.c 2021-03-24 12:03:33.784968173 +0100 -@@ -476,6 +476,7 @@ write_checkpoint(char *cpfile, u_int32_t +diff --git a/moduli.c b/moduli.c +index 9f660ef..2669edd 100644 +--- a/moduli.c ++++ b/moduli.c +@@ -476,6 +476,7 @@ write_checkpoint(char *cpfile, u_int32_t lineno) else logit("failed to write to checkpoint file '%s': %s", cpfile, strerror(errno)); @@ -254,10 +235,11 @@ diff -up openssh-8.5p1/moduli.c.coverity openssh-8.5p1/moduli.c } static unsigned long -diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.coverity 2016-12-23 16:40:26.888788688 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 16:40:26.900788691 +0100 -@@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx +diff --git a/monitor.c b/monitor.c +index fc05db6..dca2fe7 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -397,7 +397,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) mm_get_keystate(ssh, pmonitor); /* Drain any buffered messages from the child */ @@ -266,7 +248,7 @@ diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c ; if (pmonitor->m_recvfd >= 0) -@@ -1678,7 +1678,7 @@ mm_answer_pty(struct ssh *ssh, int sock, +@@ -1684,7 +1684,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) s->ptymaster = s->ptyfd; debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd); @@ -275,10 +257,11 @@ 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, +diff --git a/monitor_wrap.c b/monitor_wrap.c +index e125eca..c394d68 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -612,10 +612,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || (tmp2 = dup(pmonitor->m_recvfd)) == -1) { error_f("cannot allocate fds for pty"); @@ -292,10 +275,11 @@ diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c 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 -@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr +diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c +index 346c7fe..f42792f 100644 +--- a/openbsd-compat/bindresvport.c ++++ b/openbsd-compat/bindresvport.c +@@ -59,7 +59,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) struct sockaddr_in6 *in6; u_int16_t *portp; u_int16_t port; @@ -304,9 +288,10 @@ diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/open int i; if (sa == NULL) { -diff -up openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity openssh-8.7p1/openbsd-compat/bsd-pselect.c ---- openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity 2021-08-30 16:36:11.357288009 +0200 -+++ openssh-8.7p1/openbsd-compat/bsd-pselect.c 2021-08-30 16:37:21.791897976 +0200 +diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c +index b363208..cf7157c 100644 +--- a/openbsd-compat/bsd-pselect.c ++++ b/openbsd-compat/bsd-pselect.c @@ -113,13 +113,13 @@ pselect_notify_setup(void) static void pselect_notify_parent(void) @@ -334,10 +319,11 @@ diff -up openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity openssh-8.7p1/openb debug2_f("reading"); FD_CLR(notify_pipe[0], readset); } -diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c ---- openssh-8.5p1/readconf.c.coverity 2021-03-24 12:03:33.778968131 +0100 -+++ openssh-8.5p1/readconf.c 2021-03-24 12:03:33.785968180 +0100 -@@ -1847,6 +1847,7 @@ parse_pubkey_algos: +diff --git a/readconf.c b/readconf.c +index 1e1b78d..b6c998e 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -1933,6 +1933,7 @@ parse_pubkey_algos: } else if (r != 0) { error("%.200s line %d: glob failed for %s.", filename, linenum, arg2); @@ -345,10 +331,11 @@ 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) +diff --git a/scp.c b/scp.c +index 6146260..74f5b10 100644 +--- a/scp.c ++++ b/scp.c +@@ -187,11 +187,11 @@ killchild(int signo) { if (do_cmd_pid > 1) { kill(do_cmd_pid, signo ? signo : SIGTERM); @@ -362,10 +349,11 @@ diff -up openssh-8.7p1/scp.c.coverity openssh-8.7p1/scp.c } 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 -@@ -1638,8 +1638,9 @@ process_server_config_line(ServerOptions +diff --git a/servconf.c b/servconf.c +index 8b9540d..d72fb62 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -2081,8 +2081,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, if (*activep && *charptr == NULL) { *charptr = tilde_expand_filename(arg, getuid()); /* increase optional counter */ @@ -377,10 +365,11 @@ diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c } break; -diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c ---- openssh-8.7p1/serverloop.c.coverity 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/serverloop.c 2021-08-30 16:28:22.416226981 +0200 -@@ -547,7 +547,7 @@ server_request_tun(struct ssh *ssh) +diff --git a/serverloop.c b/serverloop.c +index b4c0d82..62c7e90 100644 +--- a/serverloop.c ++++ b/serverloop.c +@@ -546,7 +546,7 @@ server_request_tun(struct ssh *ssh) debug_f("invalid tun"); goto done; } @@ -389,10 +378,11 @@ 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-8.5p1/session.c.coverity openssh-8.5p1/session.c ---- openssh-8.5p1/session.c.coverity 2021-03-24 12:03:33.777968124 +0100 -+++ openssh-8.5p1/session.c 2021-03-24 12:03:33.786968187 +0100 -@@ -1223,12 +1223,14 @@ do_setup_env(struct ssh *ssh, Session *s +diff --git a/session.c b/session.c +index 58cf557..cdb301b 100644 +--- a/session.c ++++ b/session.c +@@ -1222,12 +1222,14 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) /* Environment specified by admin */ for (i = 0; i < options.num_setenv; i++) { cp = xstrdup(options.setenv[i]); @@ -407,10 +397,11 @@ diff -up openssh-8.5p1/session.c.coverity openssh-8.5p1/session.c } /* SSH_CLIENT deprecated */ -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) +diff --git a/sftp.c b/sftp.c +index c3c347e..c18a354 100644 +--- a/sftp.c ++++ b/sftp.c +@@ -226,7 +226,7 @@ killchild(int signo) pid = sshpid; if (pid > 1) { kill(pid, SIGTERM); @@ -419,16 +410,7 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c } _exit(1); -@@ -762,6 +762,8 @@ process_put(struct sftp_conn *conn, cons - fflag || global_fflag) == -1) - err = -1; - } -+ free(abs_dst); -+ abs_dst = NULL; - } - - out: -@@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co +@@ -1029,6 +1029,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path, if (lflag & LS_LONG_VIEW) { if (g.gl_statv[i] == NULL) { error("no stat information for %s", fname); @@ -436,21 +418,11 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c continue; } lname = ls_file(fname, g.gl_statv[i], 1, -diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c ---- openssh-8.5p1/sk-usbhid.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/sk-usbhid.c 2021-03-24 12:03:33.786968187 +0100 -@@ -1256,6 +1256,7 @@ sk_load_resident_keys(const char *pin, s - freezero(rks[i], sizeof(*rks[i])); - } - free(rks); -+ free(device); - return ret; - } - -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 -@@ -869,6 +869,7 @@ sanitize_pkcs11_provider(const char *pro +diff --git a/ssh-agent.c b/ssh-agent.c +index 50d0638..a292a9e 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -1391,6 +1391,7 @@ sanitize_pkcs11_provider(const char *provider) if (pkcs11_uri_parse(provider, uri) != 0) { error("Failed to parse PKCS#11 URI"); @@ -458,7 +430,7 @@ 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) +@@ -2080,8 +2081,8 @@ main(int ac, char **av) sanitise_stdfd(); /* drop */ @@ -469,10 +441,43 @@ diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c 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) +diff --git a/ssh-keygen.c b/ssh-keygen.c +index 6ae72ab..076dd33 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -2365,6 +2365,9 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, + r = ssh_krl_revoke_key_sha256(krl, blob, blen); + if (r != 0) + fatal_fr(r, "revoke key failed"); ++ freezero(blob, blen); ++ blob = NULL; ++ blen = 0; + } else { + if (strncasecmp(cp, "key:", 4) == 0) { + cp += 4; +@@ -3023,6 +3026,7 @@ do_moduli_screen(const char *out_file, char **opts, size_t nopts) + } else if (strncmp(opts[i], "start-line=", 11) == 0) { + start_lineno = strtoul(opts[i]+11, NULL, 10); + } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { ++ free(checkpoint); + checkpoint = xstrdup(opts[i]+11); + } else if (strncmp(opts[i], "generator=", 10) == 0) { + generator_wanted = (u_int32_t)strtonum( +@@ -3064,6 +3068,9 @@ do_moduli_screen(const char *out_file, char **opts, size_t nopts) + #else /* WITH_OPENSSL */ + fatal("Moduli screening is not supported"); + #endif /* WITH_OPENSSL */ ++ free(checkpoint); ++ if (in != stdin) ++ fclose(in); + } + + /* Read and confirm a passphrase */ +diff --git a/ssh.c b/ssh.c +index a5155f4..68558d4 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -1755,6 +1755,7 @@ control_persist_detach(void) close(muxserver_sock); muxserver_sock = -1; options.control_master = SSHCTL_MASTER_NO; @@ -480,10 +485,11 @@ diff -up openssh-8.5p1/ssh.c.coverity openssh-8.5p1/ssh.c 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 -@@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt) +diff --git a/sshd.c b/sshd.c +index e05dd82..a4a1b79 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -595,8 +595,10 @@ privsep_preauth(struct ssh *ssh) privsep_preauth_child(ssh); setproctitle("%s", "[net]"); @@ -495,26 +501,7 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c return 0; } -@@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so - explicit_bzero(rnd, sizeof(rnd)); - } - } -+ -+ if (fdset != NULL) -+ free(fdset); - } - - /* -@@ -2474,7 +2479,7 @@ do_ssh2_kex(struct ssh *ssh) - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); -- -+ /* coverity[leaked_storage : FALSE]*/ - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( - ssh, list_hostkey_types()); - -@@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2560,8 +2562,11 @@ do_ssh2_kex(struct ssh *ssh) if (newstr) myproposal[PROPOSAL_KEX_ALGS] = newstr; @@ -527,45 +514,18 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c } #endif -diff -up openssh-8.5p1/ssh-keygen.c.coverity openssh-8.5p1/ssh-keygen.c ---- openssh-8.5p1/ssh-keygen.c.coverity 2021-03-24 12:03:33.780968145 +0100 -+++ openssh-8.5p1/ssh-keygen.c 2021-03-24 12:03:33.787968194 +0100 -@@ -2332,6 +2332,9 @@ update_krl_from_file(struct passwd *pw, - r = ssh_krl_revoke_key_sha256(krl, blob, blen); - if (r != 0) - fatal_fr(r, "revoke key failed"); -+ freezero(blob, blen); -+ blob = NULL; -+ blen = 0; - } else { - if (strncasecmp(cp, "key:", 4) == 0) { - cp += 4; -@@ -2879,6 +2882,7 @@ do_moduli_screen(const char *out_file, c - } else if (strncmp(opts[i], "start-line=", 11) == 0) { - start_lineno = strtoul(opts[i]+11, NULL, 10); - } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { -+ free(checkpoint); - checkpoint = xstrdup(opts[i]+11); - } else if (strncmp(opts[i], "generator=", 10) == 0) { - generator_wanted = (u_int32_t)strtonum( -@@ -2920,6 +2924,9 @@ do_moduli_screen(const char *out_file, c - #else /* WITH_OPENSSL */ - fatal("Moduli screening is not supported"); - #endif /* WITH_OPENSSL */ -+ free(checkpoint); -+ if (in != stdin) -+ fclose(in); - } - - static char * -diff -up openssh-8.5p1/sshsig.c.coverity openssh-8.5p1/sshsig.c ---- openssh-8.5p1/sshsig.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/sshsig.c 2021-03-24 12:03:33.787968194 +0100 -@@ -515,6 +515,7 @@ hash_file(int fd, const char *hashalg, s - oerrno = errno; - error_f("read: %s", strerror(errno)); - ssh_digest_free(ctx); -+ ctx = NULL; - errno = oerrno; - r = SSH_ERR_SYSTEM_ERROR; - goto out; +diff --git a/sshsig.c b/sshsig.c +index eb2a931..3e91c14 100644 +--- a/sshsig.c ++++ b/sshsig.c +@@ -551,6 +551,7 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) + oerrno = errno; + sshbuf_free(b); + ssh_digest_free(ctx); ++ ctx = NULL; + explicit_bzero(hash, sizeof(hash)); + errno = oerrno; + return r; +-- +2.27.0 + diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index 135f05016f07c5f3a67444749e4f4bb4ec8e7d35..f2b331eabf02957870aae6b0a7d1933cf8d6fc31 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -1,7 +1,19 @@ -diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c ---- openssh-7.4p1/channels.c.x11max 2016-12-23 15:46:32.071506625 +0100 -+++ openssh-7.4p1/channels.c 2016-12-23 15:46:32.139506636 +0100 -@@ -152,8 +152,8 @@ static int all_opens_permitted = 0; +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-7.3p1-x11-max-displays.patch + +--- + channels.c | 23 ++++++++++++++--------- + channels.h | 2 +- + servconf.c | 12 +++++++++++- + servconf.h | 2 ++ + session.c | 5 +++-- + sshd_config.5 | 7 +++++++ + 6 files changed, 38 insertions(+), 13 deletions(-) + +diff --git a/channels.c b/channels.c +index 7230540..040a4c6 100644 +--- a/channels.c ++++ b/channels.c +@@ -101,8 +101,8 @@ #define FWD_PERMIT_ANY_HOST "*" /* -- X11 forwarding */ @@ -10,9 +22,9 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c +/* Minimum port number for X11 forwarding */ +#define X11_PORT_MIN 6000 - /* Per-channel callback for pre/post select() actions */ - typedef void chan_fn(struct ssh *, Channel *c, -@@ -4228,7 +4228,7 @@ channel_send_window_changes(void) + /* Per-channel callback for pre/post IO actions */ + typedef void chan_fn(struct ssh *, Channel *c); +@@ -4801,7 +4801,7 @@ rdynamic_connect_finish(struct ssh *ssh, Channel *c) */ int x11_create_display_inet(struct ssh *ssh, int x11_display_offset, @@ -21,7 +33,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c u_int *display_numberp, int **chanids) { Channel *nc = NULL; -@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_ +@@ -4814,10 +4814,15 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, if (chanids == NULL) return -1; @@ -39,7 +51,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c memset(&hints, 0, sizeof(hints)); hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; -@@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_ +@@ -4870,7 +4875,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, if (num_socks > 0) break; } @@ -48,7 +60,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c error("Failed to allocate internet-domain X11 display socket."); return -1; } -@@ -4441,7 +4447,7 @@ x11_connect_display(void) +@@ -5054,7 +5059,7 @@ x11_connect_display(struct ssh *ssh) memset(&hints, 0, sizeof(hints)); hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_socktype = SOCK_STREAM; @@ -57,7 +69,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { error("%.100s: unknown host. (%s)", buf, ssh_gai_strerror(gaierr)); -@@ -4457,7 +4463,7 @@ x11_connect_display(void) +@@ -5070,7 +5075,7 @@ x11_connect_display(struct ssh *ssh) /* Connect it to the display. */ if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { debug2("connect %.100s port %u: %.100s", buf, @@ -66,21 +78,20 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c close(sock); continue; } -@@ -4466,8 +4472,8 @@ x11_connect_display(void) - } +@@ -5080,7 +5085,7 @@ x11_connect_display(struct ssh *ssh) freeaddrinfo(aitop); if (!ai) { -- error("connect %.100s port %u: %.100s", buf, + error("connect %.100s port %u: %.100s", buf, - 6000 + display_number, strerror(errno)); -+ error("connect %.100s port %u: %.100s", buf, + X11_PORT_MIN + display_number, strerror(errno)); return -1; } set_nodelay(sock); -diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h ---- openssh-7.4p1/channels.h.x11max 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/channels.h 2016-12-23 15:46:32.139506636 +0100 -@@ -293,7 +293,7 @@ int permitopen_port(const char *); +diff --git a/channels.h b/channels.h +index 828c1b6..7d8a83e 100644 +--- a/channels.h ++++ b/channels.h +@@ -361,7 +361,7 @@ int permitopen_port(const char *); void channel_set_x11_refuse_time(struct ssh *, u_int); int x11_connect_display(struct ssh *); @@ -89,10 +100,11 @@ diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h void x11_request_forwarding_with_spoofing(struct ssh *, int, const char *, const char *, const char *, int); -diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.x11max 2016-12-23 15:46:32.133506635 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 15:47:27.320519121 +0100 -@@ -95,6 +95,7 @@ initialize_server_options(ServerOptions +diff --git a/servconf.c b/servconf.c +index 13c4a08..fdba127 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -115,6 +115,7 @@ initialize_server_options(ServerOptions *options) options->print_lastlog = -1; options->x11_forwarding = -1; options->x11_display_offset = -1; @@ -100,7 +112,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c options->x11_use_localhost = -1; options->permit_tty = -1; options->permit_user_rc = -1; -@@ -243,6 +244,8 @@ fill_default_server_options(ServerOption +@@ -330,6 +331,8 @@ fill_default_server_options(ServerOptions *options) options->x11_forwarding = 0; if (options->x11_display_offset == -1) options->x11_display_offset = 10; @@ -109,7 +121,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c if (options->x11_use_localhost == -1) options->x11_use_localhost = 1; if (options->xauth_location == NULL) -@@ -419,7 +422,7 @@ typedef enum { +@@ -518,7 +521,7 @@ typedef enum { sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -118,7 +130,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, -@@ -540,6 +543,7 @@ static struct { +@@ -652,6 +655,7 @@ static struct { { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, @@ -126,7 +138,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, -@@ -1316,6 +1320,10 @@ process_server_config_line(ServerOptions +@@ -1680,6 +1684,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, *intptr = value; break; @@ -137,7 +149,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c case sX11UseLocalhost: intptr = &options->x11_use_localhost; goto parse_flag; -@@ -2063,6 +2071,7 @@ copy_set_server_options(ServerOptions *d +@@ -2678,6 +2686,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); M_CP_INTOPT(x11_display_offset); M_CP_INTOPT(x11_forwarding); @@ -145,7 +157,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c M_CP_INTOPT(x11_use_localhost); M_CP_INTOPT(permit_tty); M_CP_INTOPT(permit_user_rc); -@@ -2315,6 +2324,7 @@ dump_config(ServerOptions *o) +@@ -2953,6 +2962,7 @@ dump_config(ServerOptions *o) #endif dump_cfg_int(sLoginGraceTime, o->login_grace_time); dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); @@ -153,10 +165,11 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c dump_cfg_int(sMaxAuthTries, o->max_authtries); dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); -diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.x11max 2016-12-23 15:46:32.133506635 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 15:46:32.140506636 +0100 -@@ -55,6 +55,7 @@ +diff --git a/servconf.h b/servconf.h +index 37d3a6f..77fd779 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -45,6 +45,7 @@ #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ @@ -164,7 +177,7 @@ diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h /* Magic name for internal sftp-server */ #define INTERNAL_SFTP_NAME "internal-sftp" -@@ -85,6 +86,7 @@ typedef struct { +@@ -105,6 +106,7 @@ typedef struct { int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ int x11_display_offset; /* What DISPLAY number to start * searching at */ @@ -172,13 +185,14 @@ diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h int x11_use_localhost; /* If true, use localhost for fake X11 server. */ char *xauth_location; /* Location of xauth program */ int permit_tty; /* If false, deny pty allocation */ -diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.x11max 2016-12-23 15:46:32.136506636 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 15:46:32.141506636 +0100 -@@ -2518,8 +2518,9 @@ session_setup_x11fwd(Session *s) +diff --git a/session.c b/session.c +index 6040d51..dd7d148 100644 +--- a/session.c ++++ b/session.c +@@ -2612,8 +2612,9 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) return 0; } - if (x11_create_display_inet(ssh, options.x11_display_offset, + if (x11_create_display_inet(ssh, options.x11_display_offset, - options.x11_use_localhost, s->single_connection, - &s->display_number, &s->x11_chanids) == -1) { + options.x11_use_localhost, options.x11_max_displays, @@ -187,10 +201,11 @@ diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c debug("x11_create_display_inet failed."); return 0; } -diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.x11max 2016-12-23 15:46:32.134506635 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:46:32.141506636 +0100 -@@ -1133,6 +1133,7 @@ Available keywords are +diff --git a/sshd_config.5 b/sshd_config.5 +index 4396b93..440fe92 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -1280,6 +1280,7 @@ Available keywords are .Cm StreamLocalBindUnlink , .Cm TrustedUserCAKeys , .Cm X11DisplayOffset , @@ -198,7 +213,7 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 .Cm X11Forwarding and .Cm X11UseLocalhost . -@@ -1566,6 +1567,12 @@ Specifies the first display number avail +@@ -1847,6 +1848,12 @@ Specifies the first display number available for X11 forwarding. This prevents sshd from interfering with real X11 servers. The default is 10. @@ -211,3 +226,6 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 .It Cm X11Forwarding Specifies whether X11 forwarding is permitted. The argument must be +-- +2.27.0 + diff --git a/openssh-7.4p1-systemd.patch b/openssh-7.4p1-systemd.patch index 4f9e58a99044003969ed299391e20206d395093e..3ed0333491809613f8db4d6de2218bbb485d0cc5 100644 --- a/openssh-7.4p1-systemd.patch +++ b/openssh-7.4p1-systemd.patch @@ -1,16 +1,19 @@ -commit 0e22b79bfde45a7cf7a2e51a68ec11c4285f3b31 -Author: Jakub Jelen -Date: Mon Nov 21 15:04:06 2016 +0100 +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-7.4p1-systemd.patch - systemd stuff +--- + configure.ac | 24 ++++++++++++++++++++++++ + contrib/sshd.service | 16 ++++++++++++++++ + sshd.c | 9 +++++++++ + 3 files changed, 49 insertions(+) + create mode 100644 contrib/sshd.service diff --git a/configure.ac b/configure.ac -index 2ffc369..162ce92 100644 +index bbe133e..6f7dc48 100644 --- a/configure.ac +++ b/configure.ac -@@ -4265,6 +4265,30 @@ AC_ARG_WITH([kerberos5], - AC_SUBST([GSSLIBS]) +@@ -4822,6 +4822,29 @@ AC_SUBST([GSSLIBS]) AC_SUBST([K5LIBS]) + AC_SUBST([CHANNELLIBS]) +# Check whether user wants systemd support +SYSTEMD_MSG="no" @@ -34,12 +37,11 @@ index 2ffc369..162ce92 100644 + fi + fi ] +) -+ + # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -@@ -5097,6 +5121,7 @@ echo " libedit support: $LIBEDIT_MSG" +@@ -5621,6 +5644,7 @@ echo " libldns support: $LDNS_MSG" echo " Solaris process contract support: $SPC_MSG" echo " Solaris project support: $SP_MSG" echo " Solaris privilege support: $SPP_MSG" @@ -70,10 +72,10 @@ index 0000000..e0d4923 +WantedBy=multi-user.target + diff --git a/sshd.c b/sshd.c -index 816611c..b8b9d13 100644 +index 0d4cfef..2a9b96d 100644 --- a/sshd.c +++ b/sshd.c -@@ -85,6 +85,10 @@ +@@ -88,6 +88,10 @@ #include #endif @@ -84,7 +86,7 @@ index 816611c..b8b9d13 100644 #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" -@@ -1888,6 +1892,11 @@ main(int ac, char **av) +@@ -2121,6 +2125,11 @@ main(int ac, char **av) } } @@ -96,3 +98,6 @@ index 816611c..b8b9d13 100644 /* Accept a connection and return in a forked child */ server_accept_loop(&sock_in, &sock_out, &newsock, config_s); +-- +2.27.0 + diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 44735188a9c8b6a600cc784673c815973a347db6..68629742e88acc3975d265cfd3335640c4c71533 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1,7 +1,55 @@ -diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c ---- openssh-8.6p1/audit-bsm.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/audit-bsm.c 2021-04-19 16:47:35.753062106 +0200 -@@ -373,13 +373,26 @@ audit_connection_from(const char *host, +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-7.6p1-audit.patch + +--- + Makefile.in | 2 +- + audit-bsm.c | 45 ++++++- + audit-linux.c | 301 +++++++++++++++++++++++++++++++++++++++++++--- + audit.c | 129 ++++++++++++++++++-- + audit.h | 22 +++- + auditstub.c | 52 ++++++++ + auth.c | 3 - + auth.h | 5 + + auth2-hostbased.c | 16 ++- + auth2-pubkey.c | 16 ++- + auth2.c | 3 - + cipher.c | 21 +--- + cipher.h | 20 ++- + kex.c | 61 ++++++++-- + kex.h | 2 + + mac.c | 14 +++ + mac.h | 1 + + monitor.c | 194 ++++++++++++++++++++++++++++-- + monitor.h | 8 +- + monitor_wrap.c | 130 +++++++++++++++++++- + monitor_wrap.h | 11 +- + packet.c | 98 +++++++++++++-- + packet.h | 1 + + session.c | 84 +++++++++++-- + session.h | 10 +- + sshd.c | 103 +++++++++++++--- + sshkey.c | 32 +++++ + sshkey.h | 1 + + 28 files changed, 1274 insertions(+), 111 deletions(-) + create mode 100644 auditstub.c + +diff --git a/Makefile.in b/Makefile.in +index 45f7a93..9b4c06b 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -114,7 +114,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ +- sshbuf-io.o ++ sshbuf-io.o auditstub.o + + SKOBJS= ssh-sk-client.o + +diff --git a/audit-bsm.c b/audit-bsm.c +index ccfcf6f..a49abb9 100644 +--- a/audit-bsm.c ++++ b/audit-bsm.c +@@ -373,12 +373,25 @@ audit_connection_from(const char *host, int port) #endif } @@ -19,17 +67,16 @@ diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c /* not implemented */ } - void ++void +audit_count_session_open(void) +{ + /* not necessary */ +} + -+void + void audit_session_open(struct logininfo *li) { - /* not implemented */ -@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li +@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li) /* not implemented */ } @@ -42,7 +89,7 @@ diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c void audit_event(struct ssh *ssh, ssh_audit_event_t event) { -@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_e +@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) debug("%s: unhandled event %d", __func__, event); } } @@ -71,234 +118,10 @@ diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh-8.6p1/audit.c.audit openssh-8.6p1/audit.c ---- openssh-8.6p1/audit.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/audit.c 2021-04-19 16:47:35.753062106 +0200 -@@ -34,6 +34,12 @@ - #include "log.h" - #include "hostfile.h" - #include "auth.h" -+#include "ssh-gss.h" -+#include "monitor_wrap.h" -+#include "xmalloc.h" -+#include "misc.h" -+#include "servconf.h" -+#include "ssherr.h" - - /* - * Care must be taken when using this since it WILL NOT be initialized when -@@ -41,6 +47,7 @@ - * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. - */ - extern Authctxt *the_authctxt; -+extern ServerOptions options; - - /* Maybe add the audit class to struct Authmethod? */ - ssh_audit_event_t -@@ -69,13 +76,10 @@ audit_classify_auth(const char *method) - const char * - audit_username(void) - { -- static const char unknownuser[] = "(unknown user)"; -- static const char invaliduser[] = "(invalid user)"; -+ static const char unknownuser[] = "(unknown)"; - -- if (the_authctxt == NULL || the_authctxt->user == NULL) -+ if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid) - return (unknownuser); -- if (!the_authctxt->valid) -- return (invaliduser); - return (the_authctxt->user); - } - -@@ -109,6 +113,35 @@ audit_event_lookup(ssh_audit_event_t ev) - return(event_lookup[i].name); - } - -+void -+audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) -+{ -+ char *fp; -+ -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) -+ *rv = -SSH_ERR_INTERNAL_ERROR; -+ free(fp); -+} -+ -+void -+audit_unsupported(struct ssh *ssh, int what) -+{ -+ PRIVSEP(audit_unsupported_body(ssh, what)); -+} -+ -+void -+audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) -+{ -+ PRIVSEP(audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid())); -+} -+ -+void -+audit_session_key_free(struct ssh *ssh, int ctos) -+{ -+ PRIVSEP(audit_session_key_free_body(ssh, ctos, getpid(), getuid())); -+} -+ - # ifndef CUSTOM_SSH_AUDIT_EVENTS - /* - * Null implementations of audit functions. -@@ -138,6 +171,17 @@ audit_event(struct ssh *ssh, ssh_audit_e - } - - /* -+ * Called when a child process has called, or will soon call, -+ * audit_session_open. -+ */ -+void -+audit_count_session_open(void) -+{ -+ debug("audit count session open euid %d user %s", geteuid(), -+ audit_username()); -+} -+ -+/* - * Called when a user session is started. Argument is the tty allocated to - * the session, or NULL if no tty was allocated. - * -@@ -172,13 +216,82 @@ audit_session_close(struct logininfo *li - /* - * This will be called when a user runs a non-interactive command. Note that - * it may be called multiple times for a single connection since SSH2 allows -- * multiple sessions within a single connection. -+ * multiple sessions within a single connection. Returns a "handle" for -+ * audit_end_command. - */ --void --audit_run_command(const char *command) -+int -+audit_run_command(struct ssh *ssh, const char *command) - { - debug("audit run command euid %d user %s command '%.200s'", geteuid(), - audit_username(), command); -+ return 0; -+} -+ -+/* -+ * This will be called when the non-interactive command finishes. Note that -+ * it may be called multiple times for a single connection since SSH2 allows -+ * multiple sessions within a single connection. "handle" should come from -+ * the corresponding audit_run_command. -+ */ -+void -+audit_end_command(struct ssh *ssh, int handle, const char *command) -+{ -+ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(), -+ audit_username(), command); -+} -+ -+/* -+ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key. -+ * -+ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. -+ */ -+int -+audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) -+{ -+ debug("audit %s key usage euid %d user %s fingerprint %s, result %d", -+ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), -+ fp, rv); -+} -+ -+/* -+ * This will be called when the protocol negotiation fails. -+ */ -+void -+audit_unsupported_body(struct ssh *ssh, int what) -+{ -+ debug("audit unsupported protocol euid %d type %d", geteuid(), what); -+} -+ -+/* -+ * This will be called on succesfull protocol negotiation. -+ */ -+void -+audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, -+ uid_t uid) -+{ -+ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, -+ (unsigned)uid); -+} -+ -+/* -+ * This will be called on succesfull session key discard -+ */ -+void -+audit_session_key_free_body(struct ssh *, int ctos, pid_t pid, uid_t uid) -+{ -+ debug("audit session key discard euid %u direction %d from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); -+} -+ -+/* -+ * This will be called on destroy private part of the server key -+ */ -+void -+audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) -+{ -+ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", -+ geteuid(), fp, (long)pid, (unsigned)uid); - } - # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ - #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-8.6p1/audit.h.audit openssh-8.6p1/audit.h ---- openssh-8.6p1/audit.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/audit.h 2021-04-19 16:47:35.753062106 +0200 -@@ -26,6 +26,7 @@ - # define _SSH_AUDIT_H - - #include "loginrec.h" -+#include "sshkey.h" - - struct ssh; - -@@ -45,13 +46,32 @@ enum ssh_audit_event_type { - SSH_CONNECTION_ABANDON, /* closed without completing auth */ - SSH_AUDIT_UNKNOWN - }; -+ -+enum ssh_audit_kex { -+ SSH_AUDIT_UNSUPPORTED_CIPHER, -+ SSH_AUDIT_UNSUPPORTED_MAC, -+ SSH_AUDIT_UNSUPPORTED_COMPRESSION -+}; - typedef enum ssh_audit_event_type ssh_audit_event_t; - -+int listening_for_clients(void); -+ - void audit_connection_from(const char *, int); - void audit_event(struct ssh *, ssh_audit_event_t); -+void audit_count_session_open(void); - void audit_session_open(struct logininfo *); - void audit_session_close(struct logininfo *); --void audit_run_command(const char *); -+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); -+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 *); -+void audit_unsupported_body(struct ssh *, int); -+void audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); -+void audit_session_key_free(struct ssh *, int ctos); -+void audit_session_key_free_body(struct ssh *, int ctos, pid_t, uid_t); -+void audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); - - #endif /* _SSH_AUDIT_H */ -diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c ---- openssh-8.6p1/audit-linux.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/audit-linux.c 2021-04-19 16:47:35.753062106 +0200 +diff --git a/audit-linux.c b/audit-linux.c +index 3fcbe5c..a823c30 100644 +--- a/audit-linux.c ++++ b/audit-linux.c @@ -33,27 +33,40 @@ #include "log.h" @@ -310,11 +133,10 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c +#include "servconf.h" #include "canohost.h" #include "packet.h" -- +#include "cipher.h" +#include "channels.h" +#include "session.h" -+ + +#define AUDIT_LOG_SIZE 256 + +extern ServerOptions options; @@ -348,7 +170,7 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c saved_errno = errno; close(audit_fd); -@@ -65,9 +78,96 @@ linux_audit_record_event(int uid, const +@@ -65,9 +78,96 @@ linux_audit_record_event(int uid, const char *username, const char *hostname, rc = 0; errno = saved_errno; @@ -446,7 +268,7 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c /* Below is the sshd audit API code */ void -@@ -76,49 +176,210 @@ audit_connection_from(const char *host, +@@ -76,49 +176,210 @@ audit_connection_from(const char *host, int port) /* not implemented */ } @@ -560,118 +382,347 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c } + +void -+audit_unsupported_body(struct ssh *ssh, int what) ++audit_unsupported_body(struct ssh *ssh, int what) ++{ ++#ifdef AUDIT_CRYPTO_SESSION ++ char buf[AUDIT_LOG_SIZE]; ++ const static char *name[] = { "cipher", "mac", "comp" }; ++ char *s; ++ int audit_fd; ++ ++ snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ", ++ name[what], ssh_remote_port(ssh), (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), ++ ssh_local_port(ssh)); ++ free(s); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) ++ /* no problem, the next instruction will be fatal() */ ++ return; ++ audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, ++ buf, NULL, ssh_remote_ipaddr(ssh), NULL, 0); ++ audit_close(audit_fd); ++#endif ++} ++ ++const static char *direction[] = { "from-server", "from-client", "both" }; ++ ++void ++audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, ++ char *pfs, pid_t pid, uid_t uid) ++{ ++#ifdef AUDIT_CRYPTO_SESSION ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ const struct sshcipher *cipher = cipher_by_name(enc); ++ char *s; ++ ++ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", ++ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, ++ (intmax_t)pid, (intmax_t)uid, ++ ssh_remote_port(ssh), (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), ssh_local_port(ssh)); ++ free(s); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return; /* No audit support in kernel */ ++ else ++ fatal("cannot open audit"); /* Must prevent login */ ++ } ++ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, ++ buf, NULL, ssh_remote_ipaddr(ssh), NULL, 1); ++ audit_close(audit_fd); ++ /* do not abort if the error is EPERM and sshd is run as non root user */ ++ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) ++ fatal("cannot write into audit"); /* Must prevent login */ ++#endif ++} ++ ++void ++audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ char *s; ++ ++ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", ++ direction[ctos], (intmax_t)pid, (intmax_t)uid, ++ ssh_remote_port(ssh), ++ (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), ++ ssh_local_port(ssh)); ++ free(s); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno != EINVAL && errno != EPROTONOSUPPORT && ++ errno != EAFNOSUPPORT) ++ error("cannot open audit"); ++ return; ++ } ++ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, ++ buf, NULL, ssh_remote_ipaddr(ssh), NULL, 1); ++ audit_close(audit_fd); ++ /* do not abort if the error is EPERM and sshd is run as non root user */ ++ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) ++ error("cannot write into audit"); ++} ++ ++void ++audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ ++ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ", ++ fp, (intmax_t)pid, (intmax_t)uid); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno != EINVAL && errno != EPROTONOSUPPORT && ++ errno != EAFNOSUPPORT) ++ error("cannot open audit"); ++ return; ++ } ++ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, ++ buf, NULL, ++ listening_for_clients() ? NULL : ssh_remote_ipaddr(ssh), ++ NULL, 1); ++ audit_close(audit_fd); ++ /* do not abort if the error is EPERM and sshd is run as non root user */ ++ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) ++ error("cannot write into audit"); ++} + #endif /* USE_LINUX_AUDIT */ +diff --git a/audit.c b/audit.c +index dd2f035..c8d54b1 100644 +--- a/audit.c ++++ b/audit.c +@@ -34,6 +34,12 @@ + #include "log.h" + #include "hostfile.h" + #include "auth.h" ++#include "ssh-gss.h" ++#include "monitor_wrap.h" ++#include "xmalloc.h" ++#include "misc.h" ++#include "servconf.h" ++#include "ssherr.h" + + /* + * Care must be taken when using this since it WILL NOT be initialized when +@@ -41,6 +47,7 @@ + * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. + */ + extern Authctxt *the_authctxt; ++extern ServerOptions options; + + /* Maybe add the audit class to struct Authmethod? */ + ssh_audit_event_t +@@ -69,13 +76,10 @@ audit_classify_auth(const char *method) + const char * + audit_username(void) + { +- static const char unknownuser[] = "(unknown user)"; +- static const char invaliduser[] = "(invalid user)"; ++ static const char unknownuser[] = "(unknown)"; + +- if (the_authctxt == NULL || the_authctxt->user == NULL) ++ if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid) + return (unknownuser); +- if (!the_authctxt->valid) +- return (invaliduser); + return (the_authctxt->user); + } + +@@ -109,6 +113,35 @@ audit_event_lookup(ssh_audit_event_t ev) + return(event_lookup[i].name); + } + ++void ++audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) ++{ ++ char *fp; ++ ++ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) ++ *rv = -SSH_ERR_INTERNAL_ERROR; ++ free(fp); ++} ++ ++void ++audit_unsupported(struct ssh *ssh, int what) ++{ ++ PRIVSEP(audit_unsupported_body(ssh, what)); ++} ++ ++void ++audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) ++{ ++ PRIVSEP(audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid())); ++} ++ ++void ++audit_session_key_free(struct ssh *ssh, int ctos) ++{ ++ PRIVSEP(audit_session_key_free_body(ssh, ctos, getpid(), getuid())); ++} ++ + # ifndef CUSTOM_SSH_AUDIT_EVENTS + /* + * Null implementations of audit functions. +@@ -137,6 +170,17 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) + audit_username(), event, audit_event_lookup(event)); + } + ++/* ++ * Called when a child process has called, or will soon call, ++ * audit_session_open. ++ */ ++void ++audit_count_session_open(void) ++{ ++ debug("audit count session open euid %d user %s", geteuid(), ++ audit_username()); ++} ++ + /* + * Called when a user session is started. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. +@@ -172,13 +216,82 @@ audit_session_close(struct logininfo *li) + /* + * This will be called when a user runs a non-interactive command. Note that + * it may be called multiple times for a single connection since SSH2 allows +- * multiple sessions within a single connection. ++ * multiple sessions within a single connection. Returns a "handle" for ++ * audit_end_command. + */ +-void +-audit_run_command(const char *command) ++int ++audit_run_command(struct ssh *ssh, const char *command) + { + debug("audit run command euid %d user %s command '%.200s'", geteuid(), + audit_username(), command); ++ return 0; ++} ++ ++/* ++ * This will be called when the non-interactive command finishes. Note that ++ * it may be called multiple times for a single connection since SSH2 allows ++ * multiple sessions within a single connection. "handle" should come from ++ * the corresponding audit_run_command. ++ */ ++void ++audit_end_command(struct ssh *ssh, int handle, const char *command) +{ -+#ifdef AUDIT_CRYPTO_SESSION -+ char buf[AUDIT_LOG_SIZE]; -+ const static char *name[] = { "cipher", "mac", "comp" }; -+ char *s; -+ int audit_fd; -+ -+ snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ", -+ name[what], ssh_remote_port(ssh), (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), -+ ssh_local_port(ssh)); -+ free(s); -+ audit_fd = audit_open(); -+ if (audit_fd < 0) -+ /* no problem, the next instruction will be fatal() */ -+ return; -+ audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, -+ buf, NULL, ssh_remote_ipaddr(ssh), NULL, 0); -+ audit_close(audit_fd); -+#endif ++ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(), ++ audit_username(), command); +} + -+const static char *direction[] = { "from-server", "from-client", "both" }; ++/* ++ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key. ++ * ++ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. ++ */ ++int ++audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) ++{ ++ debug("audit %s key usage euid %d user %s fingerprint %s, result %d", ++ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), ++ fp, rv); ++} + ++/* ++ * This will be called when the protocol negotiation fails. ++ */ +void -+audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, -+ char *pfs, pid_t pid, uid_t uid) ++audit_unsupported_body(struct ssh *ssh, int what) +{ -+#ifdef AUDIT_CRYPTO_SESSION -+ char buf[AUDIT_LOG_SIZE]; -+ int audit_fd, audit_ok; -+ const struct sshcipher *cipher = cipher_by_name(enc); -+ char *s; -+ -+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", -+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, -+ (intmax_t)pid, (intmax_t)uid, -+ ssh_remote_port(ssh), (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), ssh_local_port(ssh)); -+ free(s); -+ audit_fd = audit_open(); -+ if (audit_fd < 0) { -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || -+ errno == EAFNOSUPPORT) -+ return; /* No audit support in kernel */ -+ else -+ fatal("cannot open audit"); /* Must prevent login */ -+ } -+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, -+ buf, NULL, ssh_remote_ipaddr(ssh), NULL, 1); -+ audit_close(audit_fd); -+ /* do not abort if the error is EPERM and sshd is run as non root user */ -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) -+ fatal("cannot write into audit"); /* Must prevent login */ -+#endif ++ debug("audit unsupported protocol euid %d type %d", geteuid(), what); +} + ++/* ++ * This will be called on succesfull protocol negotiation. ++ */ +void -+audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) ++audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, ++ uid_t uid) +{ -+ char buf[AUDIT_LOG_SIZE]; -+ int audit_fd, audit_ok; -+ char *s; ++ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, ++ (unsigned)uid); ++} + -+ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", -+ direction[ctos], (intmax_t)pid, (intmax_t)uid, -+ ssh_remote_port(ssh), -+ (s = get_local_ipaddr(ssh_packet_get_connection_in(ssh))), -+ ssh_local_port(ssh)); -+ free(s); -+ audit_fd = audit_open(); -+ if (audit_fd < 0) { -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && -+ errno != EAFNOSUPPORT) -+ error("cannot open audit"); -+ return; -+ } -+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, -+ buf, NULL, ssh_remote_ipaddr(ssh), NULL, 1); -+ audit_close(audit_fd); -+ /* do not abort if the error is EPERM and sshd is run as non root user */ -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) -+ error("cannot write into audit"); ++/* ++ * This will be called on succesfull session key discard ++ */ ++void ++audit_session_key_free_body(struct ssh *, int ctos, pid_t pid, uid_t uid) ++{ ++ debug("audit session key discard euid %u direction %d from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); +} + ++/* ++ * This will be called on destroy private part of the server key ++ */ +void +audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_t uid) +{ -+ char buf[AUDIT_LOG_SIZE]; -+ int audit_fd, audit_ok; ++ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", ++ geteuid(), fp, (long)pid, (unsigned)uid); + } + # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ + #endif /* SSH_AUDIT_EVENTS */ +diff --git a/audit.h b/audit.h +index 38cb5ad..45d66cc 100644 +--- a/audit.h ++++ b/audit.h +@@ -26,6 +26,7 @@ + # define _SSH_AUDIT_H + + #include "loginrec.h" ++#include "sshkey.h" + + struct ssh; + +@@ -45,13 +46,32 @@ enum ssh_audit_event_type { + SSH_CONNECTION_ABANDON, /* closed without completing auth */ + SSH_AUDIT_UNKNOWN + }; + -+ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ", -+ fp, (intmax_t)pid, (intmax_t)uid); -+ audit_fd = audit_open(); -+ if (audit_fd < 0) { -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && -+ errno != EAFNOSUPPORT) -+ error("cannot open audit"); -+ return; -+ } -+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, -+ buf, NULL, -+ listening_for_clients() ? NULL : ssh_remote_ipaddr(ssh), -+ NULL, 1); -+ audit_close(audit_fd); -+ /* do not abort if the error is EPERM and sshd is run as non root user */ -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) -+ error("cannot write into audit"); -+} - #endif /* USE_LINUX_AUDIT */ -diff -up openssh-8.6p1/auditstub.c.audit openssh-8.6p1/auditstub.c ---- openssh-8.6p1/auditstub.c.audit 2021-04-19 16:47:35.754062114 +0200 -+++ openssh-8.6p1/auditstub.c 2021-04-19 16:47:35.754062114 +0200 ++enum ssh_audit_kex { ++ SSH_AUDIT_UNSUPPORTED_CIPHER, ++ SSH_AUDIT_UNSUPPORTED_MAC, ++ SSH_AUDIT_UNSUPPORTED_COMPRESSION ++}; + typedef enum ssh_audit_event_type ssh_audit_event_t; + ++int listening_for_clients(void); ++ + void audit_connection_from(const char *, int); + void audit_event(struct ssh *, ssh_audit_event_t); ++void audit_count_session_open(void); + void audit_session_open(struct logininfo *); + void audit_session_close(struct logininfo *); +-void audit_run_command(const char *); ++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); ++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 *); ++void audit_unsupported_body(struct ssh *, int); ++void audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); ++void audit_session_key_free(struct ssh *, int ctos); ++void audit_session_key_free_body(struct ssh *, int ctos, pid_t, uid_t); ++void audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); + + #endif /* _SSH_AUDIT_H */ +diff --git a/auditstub.c b/auditstub.c +new file mode 100644 +index 0000000..639a798 +--- /dev/null ++++ b/auditstub.c @@ -0,0 +1,52 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -725,23 +776,48 @@ diff -up openssh-8.6p1/auditstub.c.audit openssh-8.6p1/auditstub.c +audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh-8.6p1/auth2.c.audit openssh-8.6p1/auth2.c ---- openssh-8.6p1/auth2.c.audit 2021-04-19 16:47:35.682061561 +0200 -+++ openssh-8.6p1/auth2.c 2021-04-19 16:47:35.754062114 +0200 -@@ -298,9 +298,6 @@ input_userauth_request(int type, u_int32 - } else { - /* Invalid user, fake password information */ - authctxt->pw = fakepw(); +diff --git a/auth.c b/auth.c +index a449f27..1a477f8 100644 +--- a/auth.c ++++ b/auth.c +@@ -499,9 +499,6 @@ getpwnamallow(struct ssh *ssh, const char *user) + record_failed_login(ssh, user, + auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); + #endif -#ifdef SSH_AUDIT_EVENTS -- PRIVSEP(audit_event(ssh, SSH_INVALID_USER)); --#endif - } - #ifdef USE_PAM - if (options.use_pam) -diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c ---- openssh-8.6p1/auth2-hostbased.c.audit 2021-04-19 16:47:35.656061361 +0200 -+++ openssh-8.6p1/auth2-hostbased.c 2021-04-19 16:47:35.754062114 +0200 -@@ -158,7 +158,7 @@ userauth_hostbased(struct ssh *ssh) +- audit_event(ssh, SSH_INVALID_USER); +-#endif /* SSH_AUDIT_EVENTS */ + return (NULL); + } + if (!allowed_user(ssh, pw)) +diff --git a/auth.h b/auth.h +index fe32bee..6500eab 100644 +--- a/auth.h ++++ b/auth.h +@@ -197,6 +197,9 @@ struct passwd * getpwnamallow(struct ssh *, const char *user); + char *expand_authorized_keys(const char *, struct passwd *pw); + char *authorized_principals_file(struct passwd *); + ++int user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, ++ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); ++ + int auth_key_is_revoked(struct sshkey *); + + const char *auth_get_canonical_hostname(struct ssh *, int); +@@ -213,6 +216,8 @@ struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *); + int get_hostkey_index(struct sshkey *, int, struct ssh *); + int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, + u_char **, size_t *, const u_char *, size_t, const char *); ++int hostbased_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, ++ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); + + /* Key / cert options linkage to auth layer */ + const struct sshauthopt *auth_options(struct ssh *); +diff --git a/auth2-hostbased.c b/auth2-hostbased.c +index 0ac78d3..ee38cdb 100644 +--- a/auth2-hostbased.c ++++ b/auth2-hostbased.c +@@ -163,7 +163,7 @@ userauth_hostbased(struct ssh *ssh, const char *method) authenticated = 0; if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser, chost, key)) && @@ -750,7 +826,7 @@ diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0) authenticated = 1; -@@ -175,6 +175,20 @@ done: +@@ -180,6 +180,20 @@ done: return authenticated; } @@ -771,10 +847,11 @@ diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, -diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c ---- openssh-8.6p1/auth2-pubkey.c.audit 2021-04-19 16:47:35.726061899 +0200 -+++ openssh-8.6p1/auth2-pubkey.c 2021-04-19 16:47:35.754062114 +0200 -@@ -213,7 +213,7 @@ userauth_pubkey(struct ssh *ssh) +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index 95165b8..06f8155 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -236,7 +236,7 @@ userauth_pubkey(struct ssh *ssh, const char *method) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && @@ -783,7 +860,7 @@ diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, ssh->compat, &sig_details)) == 0) { -@@ -305,6 +305,20 @@ done: +@@ -329,6 +329,20 @@ done: return authenticated; } @@ -802,45 +879,26 @@ diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c +} + static int - match_principals_option(const char *principal_list, struct sshkey_cert *cert) - { -diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c ---- openssh-8.6p1/auth.c.audit 2021-04-19 16:47:35.681061553 +0200 -+++ openssh-8.6p1/auth.c 2021-04-19 16:47:35.754062114 +0200 -@@ -597,9 +597,6 @@ getpwnamallow(struct ssh *ssh, const cha - record_failed_login(ssh, user, - auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); - #endif + match_principals_file(struct passwd *pw, char *file, + struct sshkey_cert *cert, struct sshauthopt **authoptsp) +diff --git a/auth2.c b/auth2.c +index 7510c25..203ba01 100644 +--- a/auth2.c ++++ b/auth2.c +@@ -302,9 +302,6 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) + authctxt->valid = 0; + /* Invalid user, fake password information */ + authctxt->pw = fakepw(); -#ifdef SSH_AUDIT_EVENTS -- audit_event(ssh, SSH_INVALID_USER); --#endif /* SSH_AUDIT_EVENTS */ - return (NULL); - } - if (!allowed_user(ssh, pw)) -diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h ---- openssh-8.6p1/auth.h.audit 2021-04-19 16:47:35.697061676 +0200 -+++ openssh-8.6p1/auth.h 2021-04-19 16:47:35.754062114 +0200 -@@ -193,6 +193,8 @@ struct passwd * getpwnamallow(struct ssh - - char *expand_authorized_keys(const char *, struct passwd *pw); - char *authorized_principals_file(struct passwd *); -+int user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, -+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); - - FILE *auth_openkeyfile(const char *, struct passwd *, int); - FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -212,6 +214,8 @@ struct sshkey *get_hostkey_private_by_ty - int get_hostkey_index(struct sshkey *, int, struct ssh *); - int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, - u_char **, size_t *, const u_char *, size_t, const char *); -+int hostbased_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, -+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); - - /* Key / cert options linkage to auth layer */ - const struct sshauthopt *auth_options(struct ssh *); -diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c ---- openssh-8.6p1/cipher.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/cipher.c 2021-04-19 16:47:35.755062122 +0200 +- PRIVSEP(audit_event(ssh, SSH_INVALID_USER)); +-#endif + } + #ifdef USE_PAM + if (options.use_pam) +diff --git a/cipher.c b/cipher.c +index 02aea40..609450d 100644 +--- a/cipher.c ++++ b/cipher.c @@ -64,25 +64,6 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; @@ -867,7 +925,7 @@ diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES -@@ -422,7 +403,7 @@ cipher_get_length(struct sshcipher_ctx * +@@ -420,7 +401,7 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, void cipher_free(struct sshcipher_ctx *cc) { @@ -876,9 +934,10 @@ diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c return; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_free(cc->cp_ctx); -diff -up openssh-8.6p1/cipher.h.audit openssh-8.6p1/cipher.h ---- openssh-8.6p1/cipher.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/cipher.h 2021-04-19 16:47:35.755062122 +0200 +diff --git a/cipher.h b/cipher.h +index 1a591cd..48980ed 100644 +--- a/cipher.h ++++ b/cipher.h @@ -47,7 +47,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -906,9 +965,10 @@ diff -up openssh-8.6p1/cipher.h.audit openssh-8.6p1/cipher.h struct sshcipher_ctx; const struct sshcipher *cipher_by_name(const char *); -diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c ---- openssh-8.6p1/kex.c.audit 2021-04-19 16:47:35.743062030 +0200 -+++ openssh-8.6p1/kex.c 2021-04-19 16:47:35.755062122 +0200 +diff --git a/kex.c b/kex.c +index 050bece..14c7643 100644 +--- a/kex.c ++++ b/kex.c @@ -65,6 +65,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -917,7 +977,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -816,12 +817,16 @@ kex_start_rekex(struct ssh *ssh) +@@ -836,12 +837,16 @@ kex_start_rekex(struct ssh *ssh) } static int @@ -936,7 +996,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) { error_f("unsupported cipher %s", name); free(name); -@@ -842,8 +847,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -862,8 +867,12 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); @@ -950,7 +1010,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c if (mac_setup(mac, name) < 0) { error_f("unsupported MAC %s", name); free(name); -@@ -856,12 +865,16 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -876,12 +885,16 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) } static int @@ -969,7 +1029,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; -@@ -1002,7 +1015,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1044,7 +1057,7 @@ kex_choose_conf(struct ssh *ssh) nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; @@ -978,7 +1038,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c sprop[nenc])) != 0) { kex->failed_choice = peer[nenc]; peer[nenc] = NULL; -@@ -1017,7 +1030,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1059,7 +1072,7 @@ kex_choose_conf(struct ssh *ssh) peer[nmac] = NULL; goto out; } @@ -987,7 +1047,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c sprop[ncomp])) != 0) { kex->failed_choice = peer[ncomp]; peer[ncomp] = NULL; -@@ -1040,6 +1053,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -1082,6 +1095,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); @@ -998,7 +1058,7 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1297,6 +1314,36 @@ dump_digest(const char *msg, const u_cha +@@ -1339,6 +1356,36 @@ dump_digest(const char *msg, const u_char *digest, int len) } #endif @@ -1035,10 +1095,11 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c /* * Send a plaintext error message to the peer, suffixed by \r\n. * Only used during banner exchange, and there only for the server. -diff -up openssh-8.6p1/kex.h.audit openssh-8.6p1/kex.h ---- openssh-8.6p1/kex.h.audit 2021-04-19 16:47:35.683061568 +0200 -+++ openssh-8.6p1/kex.h 2021-04-19 16:47:35.756062129 +0200 -@@ -226,6 +226,8 @@ int kexgss_client(struct ssh *); +diff --git a/kex.h b/kex.h +index 240dca8..eed3fe0 100644 +--- a/kex.h ++++ b/kex.h +@@ -233,6 +233,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1047,9 +1108,10 @@ diff -up openssh-8.6p1/kex.h.audit openssh-8.6p1/kex.h int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **); -diff -up openssh-8.6p1/mac.c.audit openssh-8.6p1/mac.c ---- openssh-8.6p1/mac.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/mac.c 2021-04-19 16:47:35.756062129 +0200 +diff --git a/mac.c b/mac.c +index f3dda66..bf051ba 100644 +--- a/mac.c ++++ b/mac.c @@ -239,6 +239,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1071,31 +1133,21 @@ diff -up openssh-8.6p1/mac.c.audit openssh-8.6p1/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh-8.6p1/mac.h.audit openssh-8.6p1/mac.h ---- openssh-8.6p1/mac.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/mac.h 2021-04-19 16:47:35.756062129 +0200 -@@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 +diff --git a/mac.h b/mac.h +index 0b119d7..5fb593b 100644 +--- a/mac.h ++++ b/mac.h +@@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); void mac_clear(struct sshmac *); +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh-8.6p1/Makefile.in.audit openssh-8.6p1/Makefile.in ---- openssh-8.6p1/Makefile.in.audit 2021-04-19 16:47:35.731061937 +0200 -+++ openssh-8.6p1/Makefile.in 2021-04-19 16:47:35.756062129 +0200 -@@ -112,7 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kexsntrup761x25519.o sntrup761.o kexgen.o \ - kexgssc.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ -- sshbuf-io.o -+ sshbuf-io.o auditstub.o - - SKOBJS= ssh-sk-client.o - -diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c ---- openssh-8.6p1/monitor.c.audit 2021-04-19 16:47:35.707061753 +0200 -+++ openssh-8.6p1/monitor.c 2021-04-19 16:47:35.756062129 +0200 +diff --git a/monitor.c b/monitor.c +index a4d9062..fc05db6 100644 +--- a/monitor.c ++++ b/monitor.c @@ -93,6 +93,7 @@ #include "compat.h" #include "ssh2.h" @@ -1113,7 +1165,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c /* State exported from the child */ static struct sshbuf *child_state; -@@ -157,6 +160,11 @@ int mm_answer_gss_updatecreds(struct ssh +@@ -155,6 +158,11 @@ int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(struct ssh *, int, struct sshbuf *); int mm_answer_audit_command(struct ssh *, int, struct sshbuf *); @@ -1125,7 +1177,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c #endif static Authctxt *authctxt; -@@ -215,6 +223,10 @@ struct mon_table mon_dispatch_proto20[] +@@ -213,6 +221,10 @@ struct mon_table mon_dispatch_proto20[] = { #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1136,7 +1188,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -249,6 +261,11 @@ struct mon_table mon_dispatch_postauth20 +@@ -247,6 +259,11 @@ struct mon_table mon_dispatch_postauth20[] = { #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1148,7 +1200,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c #endif {0, 0, NULL} }; -@@ -1444,8 +1461,10 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1453,8 +1470,10 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) int r, ret, req_presence = 0, req_verify = 0, valid_data = 0; int encoded_ret; struct sshkey_sig_details *sig_details = NULL; @@ -1160,7 +1212,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c (r = sshbuf_get_string_direct(m, &signature, &signaturelen)) != 0 || (r = sshbuf_get_string_direct(m, &data, &datalen)) != 0 || (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) -@@ -1454,6 +1473,8 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1463,6 +1482,8 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal_f("bad key, not previously allowed"); @@ -1169,7 +1221,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1469,14 +1490,19 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1478,14 +1499,19 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) case MM_USERKEY: valid_data = monitor_valid_userblob(ssh, data, datalen); auth_method = "publickey"; @@ -1189,16 +1241,16 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c break; } if (!valid_data) -@@ -1488,8 +1514,6 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1497,8 +1523,6 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) SSH_FP_DEFAULT)) == NULL) fatal_f("sshkey_fingerprint failed"); - ret = sshkey_verify(key, signature, signaturelen, data, datalen, - sigalg, ssh->compat, &sig_details); - debug3_f("%s %s signature %s%s%s", auth_method, sshkey_type(key), - (ret == 0) ? "verified" : "unverified", - (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); -@@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session + debug3_f("%s %s signature using %s %s%s%s", auth_method, + sshkey_type(key), sigalg == NULL ? "default" : sigalg, + (ret == 0) ? "verified" : "unverified", +@@ -1586,13 +1610,19 @@ mm_record_login(struct ssh *ssh, Session *s, struct passwd *pw) } static void @@ -1219,7 +1271,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c session_unused(s->self); } -@@ -1649,7 +1679,7 @@ mm_answer_pty(struct ssh *ssh, int sock, +@@ -1659,7 +1689,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) error: if (s != NULL) @@ -1228,7 +1280,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c if ((r = sshbuf_put_u32(m, 0)) != 0) fatal_fr(r, "assemble 0"); mm_request_send(sock, MONITOR_ANS_PTY, m); -@@ -1668,7 +1698,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i +@@ -1678,7 +1708,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, int sock, struct sshbuf *m) if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) fatal_fr(r, "parse tty"); if ((s = session_by_tty(tty)) != NULL) @@ -1237,7 +1289,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c sshbuf_reset(m); free(tty); return (0); -@@ -1690,6 +1720,8 @@ mm_answer_term(struct ssh *ssh, int sock +@@ -1700,6 +1730,8 @@ mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req) sshpam_cleanup(); #endif @@ -1246,7 +1298,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1736,12 +1768,47 @@ mm_answer_audit_command(struct ssh *ssh, +@@ -1746,12 +1778,47 @@ mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) { char *cmd; int r; @@ -1295,7 +1347,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c free(cmd); return (0); } -@@ -1813,6 +1880,7 @@ monitor_apply_keystate(struct ssh *ssh, +@@ -1823,6 +1890,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) void mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { @@ -1303,7 +1355,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c debug3_f("Waiting for new keys"); if ((child_state = sshbuf_new()) == NULL) -@@ -1820,6 +1888,19 @@ mm_get_keystate(struct ssh *ssh, struct +@@ -1830,6 +1898,19 @@ mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3_f("GOT new keys"); @@ -1323,7 +1375,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c } -@@ -2111,3 +2192,102 @@ mm_answer_gss_updatecreds(struct ssh *ss +@@ -2121,3 +2202,102 @@ mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { #endif /* GSSAPI */ @@ -1426,9 +1478,10 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-8.6p1/monitor.h.audit openssh-8.6p1/monitor.h ---- openssh-8.6p1/monitor.h.audit 2021-04-19 16:47:35.707061753 +0200 -+++ openssh-8.6p1/monitor.h 2021-04-19 16:47:35.757062137 +0200 +diff --git a/monitor.h b/monitor.h +index ae77ce0..e26c803 100644 +--- a/monitor.h ++++ b/monitor.h @@ -65,7 +65,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1444,10 +1497,11 @@ diff -up openssh-8.6p1/monitor.h.audit openssh-8.6p1/monitor.h MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, -diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c ---- openssh-8.6p1/monitor_wrap.c.audit 2021-04-19 16:47:35.685061584 +0200 -+++ openssh-8.6p1/monitor_wrap.c 2021-04-19 16:47:35.757062137 +0200 -@@ -520,7 +520,7 @@ mm_key_allowed(enum mm_keytype type, con +diff --git a/monitor_wrap.c b/monitor_wrap.c +index 7fd3282..2117679 100644 +--- a/monitor_wrap.c ++++ b/monitor_wrap.c +@@ -520,7 +520,7 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, */ int @@ -1456,7 +1510,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c const u_char *data, size_t datalen, const char *sigalg, u_int compat, struct sshkey_sig_details **sig_detailsp) { -@@ -536,7 +536,8 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -536,7 +536,8 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -1466,7 +1520,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c (r = sshbuf_put_string(m, sig, siglen)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) -@@ -569,6 +570,22 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -569,6 +570,22 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, return 0; } @@ -1489,7 +1543,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c void mm_send_keystate(struct ssh *ssh, struct monitor *monitor) { -@@ -921,11 +938,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi +@@ -921,11 +938,12 @@ mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) sshbuf_free(m); } @@ -1504,7 +1558,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -935,6 +953,30 @@ mm_audit_run_command(const char *command +@@ -935,6 +953,30 @@ mm_audit_run_command(const char *command) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); @@ -1535,7 +1589,7 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1095,3 +1137,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1095,3 +1137,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) } #endif /* GSSAPI */ @@ -1619,10 +1673,11 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c + sshbuf_free(m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h ---- openssh-8.6p1/monitor_wrap.h.audit 2021-04-19 16:47:35.685061584 +0200 -+++ openssh-8.6p1/monitor_wrap.h 2021-04-19 16:47:35.757062137 +0200 -@@ -61,7 +61,9 @@ int mm_user_key_allowed(struct ssh *, st +diff --git a/monitor_wrap.h b/monitor_wrap.h +index 7bc2b0f..be94793 100644 +--- a/monitor_wrap.h ++++ b/monitor_wrap.h +@@ -61,7 +61,9 @@ int mm_user_key_allowed(struct ssh *ssh, struct passwd *, struct sshkey *, int, struct sshauthopt **); int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, const char *, struct sshkey *); @@ -1647,9 +1702,10 @@ diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h #endif struct Session; -diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c ---- openssh-8.6p1/packet.c.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/packet.c 2021-04-19 16:48:46.885608837 +0200 +diff --git a/packet.c b/packet.c +index 3f64d2d..c3328f3 100644 +--- a/packet.c ++++ b/packet.c @@ -81,6 +81,7 @@ #endif @@ -1658,7 +1714,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c #include "compat.h" #include "ssh2.h" #include "cipher.h" -@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh *ssh) return ssh->state->connection_out; } @@ -1672,7 +1728,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ss +@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) { struct session_state *state = ssh->state; u_int mode; @@ -1700,7 +1756,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; -@@ -634,8 +639,18 @@ ssh_packet_close_internal(struct ssh *ss +@@ -634,8 +639,18 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); @@ -1719,7 +1775,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); -@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod +@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode) (unsigned long long)state->p_send.bytes, (unsigned long long)state->p_send.blocks); kex_free_newkeys(state->newkeys[mode]); @@ -1727,7 +1783,7 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2173,6 +2189,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2183,6 +2199,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1800,19 +1856,21 @@ diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh-8.6p1/packet.h.audit openssh-8.6p1/packet.h ---- openssh-8.6p1/packet.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/packet.h 2021-04-19 16:47:35.758062145 +0200 -@@ -218,4 +218,5 @@ const u_char *sshpkt_ptr(struct ssh *, s +diff --git a/packet.h b/packet.h +index 176488b..46ef703 100644 +--- a/packet.h ++++ b/packet.h +@@ -220,4 +220,5 @@ const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); # undef EC_POINT #endif +void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ -diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c ---- openssh-8.6p1/session.c.audit 2021-04-19 16:47:35.722061868 +0200 -+++ openssh-8.6p1/session.c 2021-04-19 16:47:35.758062145 +0200 -@@ -136,7 +136,7 @@ extern char *__progname; +diff --git a/session.c b/session.c +index dd7d148..4602cd3 100644 +--- a/session.c ++++ b/session.c +@@ -135,7 +135,7 @@ extern char *__progname; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; @@ -1821,7 +1879,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; extern char *tun_fwd_ifnames; /* serverloop.c */ -@@ -644,6 +644,14 @@ do_exec_pty(struct ssh *ssh, Session *s, +@@ -643,6 +643,14 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1836,7 +1894,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; ssh_packet_set_interactive(ssh, 1, -@@ -736,15 +744,19 @@ do_exec(struct ssh *ssh, Session *s, con +@@ -735,15 +743,19 @@ do_exec(struct ssh *ssh, Session *s, const char *command) s->self); #ifdef SSH_AUDIT_EVENTS @@ -1858,7 +1916,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1550,8 +1562,11 @@ do_child(struct ssh *ssh, Session *s, co +@@ -1549,8 +1561,11 @@ do_child(struct ssh *ssh, Session *s, const char *command) sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); /* remove hostkey from the child's memory */ @@ -1871,7 +1929,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1763,6 +1778,9 @@ session_unused(int id) +@@ -1762,6 +1777,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1881,10 +1939,11 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1843,6 +1861,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1840,6 +1858,19 @@ session_open(Authctxt *authctxt, int chanid) + return 1; } - Session * ++Session * +session_by_id(int id) +{ + if (id >= 0 && id < sessions_nalloc) { @@ -1897,11 +1956,10 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c + return NULL; +} + -+Session * + Session * session_by_tty(char *tty) { - int i; -@@ -2450,6 +2481,32 @@ session_exit_message(struct ssh *ssh, Se +@@ -2448,6 +2479,32 @@ session_exit_message(struct ssh *ssh, Session *s, int status) chan_write_failed(ssh, c); } @@ -1934,7 +1992,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c void session_close(struct ssh *ssh, Session *s) { -@@ -2463,6 +2520,10 @@ session_close(struct ssh *ssh, Session * +@@ -2461,6 +2518,10 @@ session_close(struct ssh *ssh, Session *s) if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1945,7 +2003,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2537,14 +2598,14 @@ session_close_by_channel(struct ssh *ssh +@@ -2535,14 +2596,14 @@ session_close_by_channel(struct ssh *ssh, int id, void *arg) } void @@ -1962,7 +2020,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c else session_close(ssh, s); } -@@ -2671,6 +2732,15 @@ do_authenticated2(struct ssh *ssh, Authc +@@ -2669,6 +2730,15 @@ do_authenticated2(struct ssh *ssh, Authctxt *authctxt) server_loop2(ssh, authctxt); } @@ -1978,7 +2036,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2734,7 +2804,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au +@@ -2732,7 +2802,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) @@ -1987,9 +2045,10 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c } /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h ---- openssh-8.6p1/session.h.audit 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/session.h 2021-04-19 16:47:35.758062145 +0200 +diff --git a/session.h b/session.h +index ce59dab..bcd4b1d 100644 +--- a/session.h ++++ b/session.h @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2017,10 +2076,11 @@ diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h Session *session_by_tty(char *); void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); -diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c ---- openssh-8.6p1/sshd.c.audit 2021-04-19 16:47:35.727061907 +0200 -+++ openssh-8.6p1/sshd.c 2021-04-19 16:47:35.759062152 +0200 -@@ -122,6 +122,7 @@ +diff --git a/sshd.c b/sshd.c +index 2fb129d..13a217d 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -125,6 +125,7 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" @@ -2028,7 +2088,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c #include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" -@@ -260,8 +261,8 @@ struct sshbuf *loginmsg; +@@ -263,8 +264,8 @@ struct sshbuf *loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2039,8 +2099,8 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c static void do_ssh2_kex(struct ssh *); static char *listener_proctitle; -@@ -279,6 +280,15 @@ close_listen_socks(void) - num_listen_socks = -1; +@@ -282,6 +283,15 @@ close_listen_socks(void) + num_listen_socks = 0; } +/* @@ -2049,14 +2109,14 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c + */ +int listening_for_clients(void) +{ -+ return num_listen_socks >= 0; ++ return num_listen_socks > 0; +} + static void close_startup_pipes(void) { -@@ -377,18 +387,45 @@ grace_alarm_handler(int sig) - } +@@ -376,18 +386,45 @@ grace_alarm_handler(int sig) + ssh_remote_port(the_active_state)); } -/* Destroy the host and server keys. They will no longer be needed. */ @@ -2104,7 +2164,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -397,20 +434,38 @@ destroy_sensitive_data(void) +@@ -396,20 +433,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2144,7 +2204,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c } /* Certs do not need demotion */ } -@@ -438,7 +493,7 @@ reseed_prngs(void) +@@ -437,7 +492,7 @@ reseed_prngs(void) } static void @@ -2153,7 +2213,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c { gid_t gidset[1]; -@@ -453,7 +508,7 @@ privsep_preauth_child(void) +@@ -452,7 +507,7 @@ privsep_preauth_child(void) reseed_prngs(); /* Demote the private keys to public keys. */ @@ -2162,7 +2222,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c #ifdef WITH_SELINUX sshd_selinux_change_privsep_preauth_context(); -@@ -492,7 +547,7 @@ privsep_preauth(struct ssh *ssh) +@@ -491,7 +546,7 @@ privsep_preauth(struct ssh *ssh) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2171,7 +2231,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -537,7 +592,7 @@ privsep_preauth(struct ssh *ssh) +@@ -536,7 +591,7 @@ privsep_preauth(struct ssh *ssh) /* Arrange for logging to be sent to the monitor */ set_log_handler(mm_log_handler, pmonitor); @@ -2180,7 +2240,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c setproctitle("%s", "[net]"); if (box != NULL) ssh_sandbox_child(box); -@@ -589,7 +644,7 @@ privsep_postauth(struct ssh *ssh, Authct +@@ -588,7 +643,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ @@ -2189,16 +2249,16 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c reseed_prngs(); -@@ -1143,7 +1198,7 @@ server_listen(void) +@@ -1142,7 +1197,7 @@ server_listen(void) * from this function are in a forked subprocess. */ static void -server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) +server_accept_loop(struct ssh *ssh, int *sock_in, int *sock_out, int *newsock, int *config_s) { - fd_set *fdset; - int i, j, ret, maxfd; -@@ -1204,6 +1259,7 @@ server_accept_loop(int *sock_in, int *so + struct pollfd *pfd = NULL; + int i, j, ret, npfd; +@@ -1187,6 +1242,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2206,7 +2266,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -2098,7 +2154,7 @@ main(int ac, char **av) +@@ -2131,7 +2187,7 @@ main(int ac, char **av) #endif /* Accept a connection and return in a forked child */ @@ -2215,7 +2275,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c &newsock, config_s); } -@@ -2333,6 +2389,9 @@ main(int ac, char **av) +@@ -2359,6 +2415,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ @@ -2225,7 +2285,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c ssh_packet_get_bytes(ssh, &ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2513,6 +2572,15 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2542,6 +2601,15 @@ do_ssh2_kex(struct ssh *ssh) void cleanup_exit(int i) { @@ -2241,7 +2301,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c if (the_active_state != NULL && the_authctxt != NULL) { do_cleanup(the_active_state, the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2525,9 +2593,16 @@ cleanup_exit(int i) +@@ -2554,9 +2622,16 @@ cleanup_exit(int i) } } } @@ -2259,13 +2319,15 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh-8.6p1/sshkey.c.audit openssh-8.6p1/sshkey.c ---- openssh-8.6p1/sshkey.c.audit 2021-04-19 16:47:35.741062014 +0200 -+++ openssh-8.6p1/sshkey.c 2021-04-19 16:47:35.759062152 +0200 -@@ -371,6 +371,38 @@ sshkey_type_is_valid_ca(int type) +diff --git a/sshkey.c b/sshkey.c +index 151f5af..80f131f 100644 +--- a/sshkey.c ++++ b/sshkey.c +@@ -399,6 +399,38 @@ sshkey_type_is_valid_ca(int type) + } } - int ++int +sshkey_is_private(const struct sshkey *k) +{ + switch (k->type) { @@ -2297,14 +2359,14 @@ diff -up openssh-8.6p1/sshkey.c.audit openssh-8.6p1/sshkey.c + } +} + -+int + int sshkey_is_cert(const struct sshkey *k) { - if (k == NULL) -diff -up openssh-8.6p1/sshkey.h.audit openssh-8.6p1/sshkey.h ---- openssh-8.6p1/sshkey.h.audit 2021-04-19 16:47:35.741062014 +0200 -+++ openssh-8.6p1/sshkey.h 2021-04-19 16:47:35.759062152 +0200 -@@ -189,6 +189,7 @@ int sshkey_shield_private(struct sshke +diff --git a/sshkey.h b/sshkey.h +index a51d713..bb817a6 100644 +--- a/sshkey.h ++++ b/sshkey.h +@@ -189,6 +189,7 @@ int sshkey_shield_private(struct sshkey *); int sshkey_unshield_private(struct sshkey *); int sshkey_type_from_name(const char *); @@ -2312,3 +2374,6 @@ diff -up openssh-8.6p1/sshkey.h.audit openssh-8.6p1/sshkey.h int sshkey_is_cert(const struct sshkey *); int sshkey_is_sk(const struct sshkey *); int sshkey_type_is_cert(int); +-- +2.27.0 + diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index a628243aeb13d2e804cdc1aa5e4a8faa78739df3..87ea29df2313d03490204724453167ff7cad0577 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,25 +1,21 @@ -diff -up openssh-8.6p1/cipher-ctr.c.fips openssh-8.6p1/cipher-ctr.c ---- openssh-8.6p1/cipher-ctr.c.fips 2021-04-19 16:53:02.994577324 +0200 -+++ openssh-8.6p1/cipher-ctr.c 2021-04-19 16:53:03.064577862 +0200 -@@ -179,7 +179,8 @@ evp_aes_128_ctr(void) - aes_ctr.do_cipher = ssh_aes_ctr; - #ifndef SSH_OLD_EVP - aes_ctr.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 (&aes_ctr); - } +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-7.7p1-fips.patch 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-04-19 16:58:47.750263410 +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()) { -+ logit("Using arbitrary primes is not allowed in FIPS mode." ++ verbose("Using arbitrary primes is not allowed in FIPS mode." + " Falling back to known groups."); + return (dh_new_group_fallback(max)); + } @@ -67,8 +63,8 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c + #endif /* WITH_OPENSSL */ diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h ---- openssh-8.6p1/dh.h.fips 2021-04-19 16:53:03.064577862 +0200 -+++ openssh-8.6p1/dh.h 2021-04-19 16:59:31.951616078 +0200 +--- 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); @@ -78,8 +74,16 @@ diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h 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-04-19 16:53:03.058577815 +0200 -+++ openssh-8.6p1/kex.c 2021-04-19 16:53:03.065577869 +0200 +--- 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, ","))) { @@ -94,12 +98,12 @@ diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c } 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-04-19 16:53:03.065577869 +0200 ++++ openssh-8.6p1/kexgexc.c 2021-05-06 12:08:36.498926877 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL -+#include ++#include #include #include @@ -116,7 +120,7 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c /* 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-04-19 16:53:03.065577869 +0200 ++++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200 @@ -57,6 +57,18 @@ "rsa-sha2-512," \ "rsa-sha2-256" @@ -131,7 +135,7 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h + "ecdsa-sha2-nistp384," \ + "ecdsa-sha2-nistp521," \ + "rsa-sha2-512," \ -+ "rsa-sha2-256," \ ++ "rsa-sha2-256" + #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ @@ -165,8 +169,16 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h #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-04-19 16:53:02.999577362 +0200 -+++ openssh-8.6p1/readconf.c 2021-04-19 16:53:03.065577869 +0200 +--- 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, ','); @@ -190,8 +202,8 @@ diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c 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-04-19 16:53:03.034577631 +0200 -+++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-04-19 16:53:03.065577869 +0200 +--- 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), @@ -203,8 +215,16 @@ diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-secco 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-04-19 16:53:03.027577577 +0200 -+++ openssh-8.6p1/servconf.c 2021-04-19 16:53:03.066577877 +0200 +--- 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, ','); @@ -228,13 +248,13 @@ diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c 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-04-19 16:53:03.038577662 +0200 -+++ openssh-8.6p1/ssh.c 2021-04-19 16:53:03.066577877 +0200 +--- 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 #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" @@ -250,13 +270,13 @@ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c 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-04-19 16:53:03.055577792 +0200 -+++ openssh-8.6p1/sshconnect2.c 2021-04-19 16:53:03.066577877 +0200 +--- 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 + #include "openbsd-compat/sys-queue.h" @@ -331,10 +351,10 @@ diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c } #endif diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c ---- openssh-8.6p1/sshd.c.fips 2021-04-19 16:53:03.060577831 +0200 -+++ openssh-8.6p1/sshd.c 2021-04-19 16:57:45.827769340 +0200 +--- 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 @@ - #include + #endif #include #include +#include @@ -345,7 +365,7 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c #include #include #include -+#include ++#include #include "openbsd-compat/openssl-compat.h" #endif @@ -357,6 +377,20 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; +@@ -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); @@ -388,13 +422,13 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c 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-04-19 16:53:03.061577838 +0200 -+++ openssh-8.6p1/sshkey.c 2021-04-19 16:53:03.067577885 +0200 +--- 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 @@ -34,6 +34,7 @@ #include #include #include -+#include ++#include #endif #include "crypto_api.h" @@ -406,18 +440,80 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c #include "ssh-sk.h" #ifdef WITH_XMSS -@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA - } - if (!BN_set_word(f4, RSA_F4) || - !RSA_generate_key_ex(private, bits, f4, NULL)) { -+ 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; +@@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai + for (kt = keytypes; kt->type != -1; kt++) { + if (kt->name == NULL || kt->type == KEY_NULL) + continue; ++ if (FIPS_mode()) { ++ switch (kt->type) { ++ case KEY_ED25519: ++ case KEY_ED25519_SK: ++ case KEY_ED25519_CERT: ++ case KEY_ED25519_SK_CERT: ++ continue; ++ break; ++ default: ++ break; ++ } ++ } + if (!include_sigonly && kt->sigonly) + continue; + if ((certs_only && !kt->cert) || (plain_only && kt->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 */ + ret->type = type; + if (sshkey_is_cert(ret)) { +@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key, + break; + case KEY_ED25519_SK: + case KEY_ED25519_SK_CERT: ++ if (FIPS_mode()) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++ /* Fallthrough */ + case KEY_ECDSA_SK_CERT: + case KEY_ECDSA_SK: + r = sshsk_sign(sk_provider, key, sigp, lenp, data, +@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key, + return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); + case KEY_ED25519_SK: + case KEY_ED25519_SK_CERT: ++ if (FIPS_mode()) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } + return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen, + compat, detailsp); + #ifdef WITH_XMSS diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c ---- openssh-8.6p1/ssh-keygen.c.fips 2021-04-19 16:53:03.038577662 +0200 -+++ openssh-8.6p1/ssh-keygen.c 2021-04-19 16:53:03.068577892 +0200 +--- 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 } @@ -425,7 +521,7 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c + if (FIPS_mode()) { + if (type == KEY_DSA) + fatal("DSA keys are not allowed in FIPS mode"); -+ if (type == KEY_ED25519) ++ if (type == KEY_ED25519 || type == KEY_ED25519_SK) + fatal("ED25519 keys are not allowed in FIPS mode"); + } switch (type) { @@ -450,3 +546,122 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c if ((fd = mkstemp(prv_tmp)) == -1) { error("Could not save your private key in %s: %s", prv_tmp, strerror(errno)); +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 * + datalen >= INT_MAX - crypto_sign_ed25519_BYTES || + signature == NULL || signaturelen == 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(signature, signaturelen)) == NULL) + return SSH_ERR_ALLOC_FAIL; diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index 8560c9fe1e6257a7b1a5dbaf97af9c7baa20f74e..2242b98c817872339acea0bb541d2811d1e30c92 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -1,13 +1,14 @@ +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-7.8p1-UsePAM-warning.patch diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c --- openssh-8.6p1/sshd.c.log-usepam-no 2021-04-19 14:00:45.099735129 +0200 +++ openssh-8.6p1/sshd.c 2021-04-19 14:03:21.140920974 +0200 @@ -1749,6 +1749,10 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, - cfg, &includes, NULL); + cfg, &includes, NULL, rexeced_flag); -+ /* 'UsePAM no' is not supported in Fedora */ ++ /* 'UsePAM no' is not supported in openEuler */ + if (! options.use_pam) -+ logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems."); ++ logit("WARNING: 'UsePAM no' is not supported in openEuler and may cause several problems."); + #ifdef WITH_OPENSSL if (options.moduli_file != NULL) @@ -19,7 +20,7 @@ diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication # and KbdInteractiveAuthentication to 'no'. -+# WARNING: 'UsePAM no' is not supported in Fedora and may cause several ++# WARNING: 'UsePAM no' is not supported in openEuler and may cause several +# problems. #UsePAM no diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 48f9f1002d660119c2543a7913b7fa5d3459cd52..4dc460a530f46109d540e3a586d4b329c6ef420e 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -93,7 +93,7 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#endif (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || - (r = sshbuf_put_cstring(b, "hostbased")) != 0 || + (r = sshbuf_put_cstring(b, method)) != 0 || (r = sshbuf_put_string(b, pkalg, alen)) != 0 || diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c --- openssh/auth2-pubkey.c.role-mls 2018-08-22 11:14:56.816430924 +0200 @@ -240,14 +240,14 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh, - { struct sshbuf *b; + struct sshkey *hostkey = NULL; const u_char *p; - char *userstyle, *cp; + char *userstyle, *s, *cp; size_t len; u_char type; - int r, fail = 0; + int hostbound = 0, r, fail = 0; @@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh, fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 2ad438c1100d23ad7b20ee538a57755d237a66ff..75bd3aa491f21e23f5094eceb8dd07de3cb41fe8 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,13 +1,14 @@ -diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 ---- openssh-8.7p1/ssh_config.5.crypto-policies 2021-08-30 13:29:00.174292872 +0200 -+++ openssh-8.7p1/ssh_config.5 2021-08-30 13:31:32.009548808 +0200 -@@ -373,17 +373,13 @@ or +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-8.0p1-crypto-policies.patch +diff --color -ru a/ssh_config.5 b/ssh_config.5 +--- a/ssh_config.5 2022-07-12 15:05:22.550013071 +0200 ++++ b/ssh_config.5 2022-07-12 15:17:20.016704545 +0200 +@@ -373,17 +373,13 @@ causes no CNAMEs to be considered for canonicalization. This is the default behaviour. .It Cm CASignatureAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies which algorithms are allowed for signing of certificates @@ -24,13 +25,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -445,20 +441,25 @@ If the option is set to +@@ -445,20 +441,25 @@ (the default), the check will not be executed. .It Cm Ciphers +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the ciphers allowed and their order of preference. @@ -54,7 +55,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -474,13 +475,6 @@ aes256-gcm@openssh.com +@@ -474,13 +475,6 @@ chacha20-poly1305@openssh.com .Ed .Pp @@ -68,19 +69,19 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClearAllForwardings -@@ -874,6 +868,11 @@ command line will be passed untouched to +@@ -874,6 +868,11 @@ The default is .Dq no . .It Cm GSSAPIKexAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are .Bd -literal -offset 3n -@@ -886,10 +885,8 @@ gss-nistp256-sha256-, +@@ -886,10 +885,8 @@ gss-curve25519-sha256- .Ed .Pp @@ -92,13 +93,58 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -1219,29 +1216,25 @@ it may be zero or more of: +@@ -913,36 +910,25 @@ + but may be manually hashed using + .Xr ssh-keygen 1 . + .It Cm HostbasedAcceptedAlgorithms ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page ++.Xr update-crypto-policies 8 . ++.Pp + Specifies the signature algorithms that will be used for hostbased + authentication as a comma-separated list of patterns. + Alternately if the specified list begins with a + .Sq + + character, then the specified signature algorithms will be appended +-to the default set instead of replacing them. ++to the built-in openssh default set instead of replacing them. + If the specified list begins with a + .Sq - + character, then the specified signature algorithms (including wildcards) +-will be removed from the default set instead of replacing them. ++will be removed from the built-in openssh default set instead of replacing them. + If the specified list begins with a + .Sq ^ + character, then the specified signature algorithms will be placed +-at the head of the default set. +-The default for this option is: +-.Bd -literal -offset 3n +-ssh-ed25519-cert-v01@openssh.com, +-ecdsa-sha2-nistp256-cert-v01@openssh.com, +-ecdsa-sha2-nistp384-cert-v01@openssh.com, +-ecdsa-sha2-nistp521-cert-v01@openssh.com, +-sk-ssh-ed25519-cert-v01@openssh.com, +-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, +-rsa-sha2-512-cert-v01@openssh.com, +-rsa-sha2-256-cert-v01@openssh.com, +-ssh-ed25519, +-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-sk-ssh-ed25519@openssh.com, +-sk-ecdsa-sha2-nistp256@openssh.com, +-rsa-sha2-512,rsa-sha2-256 +-.Ed ++at the head of the built-in openssh default set. + .Pp + The + .Fl Q +@@ -1219,30 +1216,25 @@ and .Cm pam . .It Cm KexAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the available KEX (Key Exchange) algorithms. @@ -107,7 +153,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .Sq + -character, then the specified algorithms will be appended to the default set -instead of replacing them. -+character, then the specified algorithms will be appended to the built-in ++character, then the specified methods will be appended to the built-in +openssh default set instead of replacing them. If the specified list begins with a .Sq - @@ -120,6 +166,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 -default set. -The default is: -.Bd -literal -offset indent +-sntrup761x25519-sha512@openssh.com, -curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, @@ -131,13 +178,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .Pp The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . -@@ -1351,37 +1344,33 @@ function, and all code in the +@@ -1351,37 +1344,33 @@ file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the MAC (message authentication code) algorithms @@ -178,13 +225,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1553,36 +1542,25 @@ instead of continuing to execute and pas +@@ -1553,36 +1542,25 @@ The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the signature algorithms that will be used for public key @@ -224,16 +271,27 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 ---- openssh-8.7p1/sshd_config.5.crypto-policies 2021-08-30 13:29:00.157292731 +0200 -+++ openssh-8.7p1/sshd_config.5 2021-08-30 13:32:16.263918533 +0200 -@@ -373,17 +373,13 @@ If the argument is +@@ -2237,7 +2207,9 @@ for those users who do not have a config + This file must be world-readable. + .El + .Sh SEE ALSO +-.Xr ssh 1 ++.Xr ssh 1 , ++.Xr crypto-policies 7 , ++.Xr update-crypto-policies 8 + .Sh AUTHORS + .An -nosplit + OpenSSH is a derivative of the original and free +diff --color -ru a/sshd_config.5 b/sshd_config.5 +--- a/sshd_config.5 2022-07-12 15:05:22.535012771 +0200 ++++ b/sshd_config.5 2022-07-12 15:15:33.394809258 +0200 +@@ -373,17 +373,13 @@ then no banner is displayed. By default, no banner is displayed. .It Cm CASignatureAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies which algorithms are allowed for signing of certificates @@ -250,13 +308,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -450,20 +446,25 @@ The default is +@@ -450,20 +446,25 @@ indicating not to .Xr chroot 2 . .It Cm Ciphers +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the ciphers allowed. @@ -280,7 +338,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 .Pp The supported ciphers are: .Pp -@@ -490,13 +491,6 @@ aes256-gcm@openssh.com +@@ -490,13 +491,6 @@ chacha20-poly1305@openssh.com .El .Pp @@ -294,13 +352,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -685,21 +679,22 @@ For this to work +@@ -685,53 +679,43 @@ .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp The list of key exchange algorithms that are accepted by GSSAPI @@ -326,19 +384,59 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 -gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . This option only applies to connections using GSSAPI. .It Cm HostbasedAcceptedAlgorithms ++The default is handled system-wide by ++.Xr crypto-policies 7 . ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page ++.Xr update-crypto-policies 8 . ++.Pp Specifies the signature algorithms that will be accepted for hostbased -@@ -799,26 +794,13 @@ is specified, the location of the socket + authentication as a list of comma-separated patterns. + Alternately if the specified list begins with a + .Sq + + character, then the specified signature algorithms will be appended to +-the default set instead of replacing them. ++the built-in openssh default set instead of replacing them. + If the specified list begins with a + .Sq - + character, then the specified signature algorithms (including wildcards) +-will be removed from the default set instead of replacing them. ++will be removed from the built-in openssh default set instead of replacing them. + If the specified list begins with a + .Sq ^ + character, then the specified signature algorithms will be placed at +-the head of the default set. +-The default for this option is: +-.Bd -literal -offset 3n +-ssh-ed25519-cert-v01@openssh.com, +-ecdsa-sha2-nistp256-cert-v01@openssh.com, +-ecdsa-sha2-nistp384-cert-v01@openssh.com, +-ecdsa-sha2-nistp521-cert-v01@openssh.com, +-sk-ssh-ed25519-cert-v01@openssh.com, +-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, +-rsa-sha2-512-cert-v01@openssh.com, +-rsa-sha2-256-cert-v01@openssh.com, +-ssh-ed25519, +-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-sk-ssh-ed25519@openssh.com, +-sk-ecdsa-sha2-nistp256@openssh.com, +-rsa-sha2-512,rsa-sha2-256 +-.Ed ++the head of the built-in openssh default set. + .Pp + The list of available signature algorithms may also be obtained using + .Qq ssh -Q HostbasedAcceptedAlgorithms . +@@ -799,25 +794,14 @@ .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the host key signature algorithms that the server offers. --The default for this option is: + The default for this option is: -.Bd -literal -offset 3n -ssh-ed25519-cert-v01@openssh.com, -ecdsa-sha2-nistp256-cert-v01@openssh.com, @@ -348,24 +446,23 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 -sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, -rsa-sha2-512-cert-v01@openssh.com, -rsa-sha2-256-cert-v01@openssh.com, --ssh-rsa-cert-v01@openssh.com, -ssh-ed25519, -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, -sk-ssh-ed25519@openssh.com, -sk-ecdsa-sha2-nistp256@openssh.com, --rsa-sha2-512,rsa-sha2-256,ssh-rsa +-rsa-sha2-512,rsa-sha2-256 -.Ed -.Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -965,20 +947,25 @@ Specifies whether to look at .k5login fi +@@ -965,20 +947,25 @@ The default is .Cm yes . .It Cm KexAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the available KEX (Key Exchange) algorithms. @@ -374,7 +471,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 .Sq + -character, then the specified algorithms will be appended to the default set -instead of replacing them. -+character, then the specified algorithms will be appended to the built-in ++character, then the specified methods will be appended to the built-in +openssh default set instead of replacing them. If the specified list begins with a .Sq - @@ -389,12 +486,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The supported algorithms are: .Pp .Bl -item -compact -offset indent -@@ -1010,15 +997,6 @@ ecdh-sha2-nistp521 +@@ -1010,16 +997,6 @@ sntrup761x25519-sha512@openssh.com .El .Pp -The default is: -.Bd -literal -offset indent +-sntrup761x25519-sha512@openssh.com, -curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, @@ -405,13 +503,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The list of available key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress -@@ -1104,21 +1082,26 @@ function, and all code in the +@@ -1104,21 +1082,26 @@ file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the available MAC (message authentication code) algorithms. @@ -436,7 +534,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 .Pp The algorithms that contain .Qq -etm -@@ -1161,15 +1144,6 @@ umac-64-etm@openssh.com +@@ -1161,15 +1144,6 @@ umac-128-etm@openssh.com .El .Pp @@ -452,13 +550,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1548,37 +1522,25 @@ or equivalent.) +@@ -1548,36 +1522,25 @@ The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . -+To see the defaults and how to modify this default, see manual page ++Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp Specifies the signature algorithms that will be accepted for public key @@ -488,14 +586,24 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 -sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, -rsa-sha2-512-cert-v01@openssh.com, -rsa-sha2-256-cert-v01@openssh.com, --ssh-rsa-cert-v01@openssh.com, -ssh-ed25519, -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, -sk-ssh-ed25519@openssh.com, -sk-ecdsa-sha2-nistp256@openssh.com, --rsa-sha2-512,rsa-sha2-256,ssh-rsa +-rsa-sha2-512,rsa-sha2-256 -.Ed +built-in openssh default set. .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . +@@ -2011,7 +1968,9 @@ This file should be writable by root onl + .El + .Sh SEE ALSO + .Xr sftp-server 8 , +-.Xr sshd 8 ++.Xr sshd 8 , ++.Xr crypto-policies 7 , ++.Xr update-crypto-policies 8 + .Sh AUTHORS + .An -nosplit + OpenSSH is a derivative of the original and free diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index e26bebdae03254946f6534bd8445d088bf1fdb5a..9db6a9f6a85b39e29f7b6ad08dc04717193959cd 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -1,8 +1,52 @@ +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-8.0p1-gssapi-keyex.patch + +--- + Makefile.in | 3 +- + auth.c | 94 +------- + auth2-gss.c | 56 ++++- + auth2.c | 2 + + canohost.c | 93 ++++++++ + canohost.h | 3 + + clientloop.c | 11 + + configure.ac | 24 ++ + gss-genr.c | 297 +++++++++++++++++++++++- + gss-serv-krb5.c | 97 +++++++- + gss-serv.c | 205 +++++++++++++++-- + kex.c | 66 +++++- + kex.h | 29 +++ + kexdh.c | 10 + + kexgen.c | 2 +- + kexgssc.c | 599 ++++++++++++++++++++++++++++++++++++++++++++++++ + kexgsss.c | 474 ++++++++++++++++++++++++++++++++++++++ + monitor.c | 138 ++++++++++- + monitor.h | 2 + + monitor_wrap.c | 57 ++++- + monitor_wrap.h | 4 +- + readconf.c | 70 ++++++ + readconf.h | 6 + + servconf.c | 47 ++++ + servconf.h | 3 + + session.c | 10 +- + ssh-gss.h | 54 ++++- + ssh.1 | 8 + + ssh.c | 6 +- + ssh_config | 2 + + ssh_config.5 | 58 +++++ + sshconnect2.c | 156 ++++++++++++- + sshd.c | 62 ++++- + sshd_config | 2 + + sshd_config.5 | 31 +++ + sshkey.c | 3 +- + sshkey.h | 1 + + 37 files changed, 2623 insertions(+), 162 deletions(-) + create mode 100644 kexgssc.c + create mode 100644 kexgsss.c + diff --git a/Makefile.in b/Makefile.in -index e7549470..b68c1710 100644 +index f4c7540..8229885 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -109,6 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -112,6 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ kexsntrup761x25519.o sntrup761.o kexgen.o \ @@ -10,19 +54,20 @@ index e7549470..b68c1710 100644 sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ sshbuf-io.o -@@ -125,7 +126,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ +@@ -128,7 +129,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ monitor.o monitor_wrap.o auth-krb5.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -up a/auth.c.gsskex b/auth.c ---- a/auth.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/auth.c 2021-08-27 12:41:51.262788953 +0200 -@@ -402,7 +402,8 @@ auth_root_allowed(struct ssh *ssh, const +diff --git a/auth.c b/auth.c +index 13e8d79..a449f27 100644 +--- a/auth.c ++++ b/auth.c +@@ -358,7 +358,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -32,10 +77,11 @@ diff -up a/auth.c.gsskex b/auth.c return 1; break; case PERMIT_FORCED_ONLY: -@@ -730,97 +731,6 @@ fakepw(void) +@@ -639,97 +640,6 @@ fakepw(void) + return (&fake); } - /* +-/* - * Returns the remote DNS hostname as a string. The returned string must not - * be freed. NB. this will usually trigger a DNS query the first time it is - * called. @@ -126,16 +172,15 @@ diff -up a/auth.c.gsskex b/auth.c - return xstrdup(name); -} - --/* + /* * Return the canonical name of the host in the other side of the current * connection. The host name is cached, so it is efficient to call this - * several times. diff --git a/auth2-gss.c b/auth2-gss.c -index 9351e042..d6446c0c 100644 +index d9b192c..cd6487c 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ - /* $OpenBSD: auth2-gss.c,v 1.32 2021/01/27 10:15:08 djm Exp $ */ + /* $OpenBSD: auth2-gss.c,v 1.33 2021/12/19 22:12:07 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -143,7 +188,7 @@ index 9351e042..d6446c0c 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -54,6 +54,48 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); +@@ -55,6 +55,48 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); static int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -192,7 +237,7 @@ index 9351e042..d6446c0c 100644 /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -260,7 +302,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) +@@ -261,7 +303,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) if ((r = sshpkt_get_end(ssh)) != 0) fatal_fr(r, "parse packet"); @@ -202,7 +247,7 @@ index 9351e042..d6446c0c 100644 if ((!use_privsep || mm_is_monitor()) && (displayname = ssh_gssapi_displayname()) != NULL) -@@ -306,7 +349,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -314,7 +357,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) gssbuf.length = sshbuf_len(b); if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) @@ -212,7 +257,7 @@ 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) +@@ -336,6 +380,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) return 0; } @@ -224,12 +269,12 @@ index 9351e042..d6446c0c 100644 + Authmethod method_gssapi = { "gssapi-with-mic", - userauth_gssapi, + NULL, diff --git a/auth2.c b/auth2.c -index 0e776224..1c217268 100644 +index 15ae306..7510c25 100644 --- a/auth2.c +++ b/auth2.c -@@ -73,6 +73,7 @@ extern Authmethod method_passwd; +@@ -71,6 +71,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI @@ -237,7 +282,7 @@ index 0e776224..1c217268 100644 extern Authmethod method_gssapi; #endif -@@ -80,6 +81,7 @@ Authmethod *authmethods[] = { +@@ -78,6 +79,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI @@ -246,7 +291,7 @@ index 0e776224..1c217268 100644 #endif &method_passwd, diff --git a/canohost.c b/canohost.c -index abea9c6e..8e81b519 100644 +index a810da0..fe337d7 100644 --- a/canohost.c +++ b/canohost.c @@ -35,6 +35,99 @@ @@ -350,7 +395,7 @@ index abea9c6e..8e81b519 100644 ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) { diff --git a/canohost.h b/canohost.h -index 26d62855..0cadc9f1 100644 +index 26d6285..0cadc9f 100644 --- a/canohost.h +++ b/canohost.h @@ -15,6 +15,9 @@ @@ -364,10 +409,10 @@ index 26d62855..0cadc9f1 100644 int get_peer_port(int); char *get_local_ipaddr(int); diff --git a/clientloop.c b/clientloop.c -index ebd0dbca..1bdac6a4 100644 +index 0050f3e..6f6216a 100644 --- a/clientloop.c +++ b/clientloop.c -@@ -112,6 +112,10 @@ +@@ -115,6 +115,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -375,34 +420,28 @@ index ebd0dbca..1bdac6a4 100644 +#include "ssh-gss.h" +#endif + - /* import options */ - extern Options options; + /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ + #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -@@ -1379,9 +1383,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, - break; - - /* Do channel operations unless rekeying in progress. */ -- if (!ssh_packet_is_rekeying(ssh)) -+ if (!ssh_packet_is_rekeying(ssh)) { - channel_after_select(ssh, readset, writeset); +@@ -1350,6 +1354,13 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, + /* Do channel operations. */ + channel_after_poll(ssh, pfd, npfd_active); +#ifdef GSSAPI -+ if (options.gss_renewal_rekey && -+ ssh_gssapi_credentials_updated(NULL)) { ++ if (options.gss_renewal_rekey && ++ ssh_gssapi_credentials_updated(NULL)) { + debug("credentials updated - forcing rekey"); + need_rekeying = 1; -+ } -+#endif + } -+ - /* Buffer input from the connection. */ - client_process_net_input(ssh, readset); ++#endif + /* Buffer input from the connection. */ + if (conn_in_ready) diff --git a/configure.ac b/configure.ac -index b689db4b..efafb6bd 100644 +index 51545ee..bbe133e 100644 --- a/configure.ac +++ b/configure.ac -@@ -674,6 +674,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +@@ -736,6 +736,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -434,7 +473,7 @@ index b689db4b..efafb6bd 100644 AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff --git a/gss-genr.c b/gss-genr.c -index d56257b4..763a63ff 100644 +index 2cd695e..9f9745b 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -1,7 +1,7 @@ @@ -446,7 +485,7 @@ index d56257b4..763a63ff 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -41,9 +41,33 @@ +@@ -42,9 +42,33 @@ #include "sshbuf.h" #include "log.h" #include "ssh2.h" @@ -480,7 +519,7 @@ index d56257b4..763a63ff 100644 /* sshbuf_get for gss_buffer_desc */ int ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) -@@ -62,6 +86,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) +@@ -60,6 +84,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) return 0; } @@ -640,7 +679,7 @@ index d56257b4..763a63ff 100644 /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -218,7 +398,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, +@@ -216,7 +393,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, } ctx->major = gss_init_sec_context(&ctx->minor, @@ -649,7 +688,7 @@ index d56257b4..763a63ff 100644 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -247,9 +427,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) +@@ -245,9 +422,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) return (ctx->major); } @@ -693,7 +732,7 @@ index d56257b4..763a63ff 100644 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -257,6 +471,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) +@@ -255,6 +466,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) return (ctx->major); } @@ -713,7 +752,7 @@ index d56257b4..763a63ff 100644 void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context, const struct sshbuf *session_id) -@@ -273,11 +500,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, +@@ -271,11 +495,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, } int @@ -731,7 +770,7 @@ index d56257b4..763a63ff 100644 /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -287,6 +519,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -285,6 +514,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -742,7 +781,7 @@ index d56257b4..763a63ff 100644 if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -296,10 +532,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -294,10 +527,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) GSS_C_NO_BUFFER); } @@ -811,7 +850,7 @@ index d56257b4..763a63ff 100644 + #endif /* GSSAPI */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index a151bc1e..8d2b677f 100644 +index a151bc1..8d2b677 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -1,7 +1,7 @@ @@ -951,7 +990,7 @@ index a151bc1e..8d2b677f 100644 #endif /* KRB5 */ diff --git a/gss-serv.c b/gss-serv.c -index ab3a15f0..6ce56e92 100644 +index b5d4bb2..4287579 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ @@ -1251,7 +1290,7 @@ index ab3a15f0..6ce56e92 100644 /* Privileged */ diff --git a/kex.c b/kex.c -index ce85f043..574c7609 100644 +index 0bcd27d..9e58a64 100644 --- a/kex.c +++ b/kex.c @@ -57,11 +57,16 @@ @@ -1271,7 +1310,7 @@ index ce85f043..574c7609 100644 /* prototype */ static int kex_choose_conf(struct ssh *); static int kex_input_newkeys(int, u_int32_t, struct ssh *); -@@ -115,15 +120,28 @@ static const struct kexalg kexalgs[] = { +@@ -117,15 +122,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ { NULL, 0, -1, -1}, }; @@ -1303,7 +1342,7 @@ index ce85f043..574c7609 100644 if (ret != NULL) ret[rlen++] = sep; nlen = strlen(k->name); -@@ -138,6 +156,18 @@ kex_alg_list(char sep) +@@ -140,6 +158,18 @@ kex_alg_list(char sep) return ret; } @@ -1322,7 +1361,7 @@ index ce85f043..574c7609 100644 static const struct kexalg * kex_alg_by_name(const char *name) { -@@ -147,6 +177,10 @@ kex_alg_by_name(const char *name) +@@ -149,6 +179,10 @@ kex_alg_by_name(const char *name) if (strcmp(k->name, name) == 0) return k; } @@ -1333,7 +1372,7 @@ index ce85f043..574c7609 100644 return NULL; } -@@ -315,6 +349,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) +@@ -317,6 +351,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) return r; } @@ -1363,18 +1402,18 @@ index ce85f043..574c7609 100644 /* put algorithm proposal into buffer */ int kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) -@@ -698,6 +755,9 @@ kex_free(struct kex *kex) +@@ -717,6 +774,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); sshbuf_free(kex->session_id); +#ifdef GSSAPI + free(kex->gss_host); +#endif /* GSSAPI */ + sshbuf_free(kex->initial_sig); + sshkey_free(kex->initial_hostkey); free(kex->failed_choice); - free(kex->hostkey_alg); - free(kex->name); diff --git a/kex.h b/kex.h -index a5ae6ac0..fe714141 100644 +index c353295..240dca8 100644 --- a/kex.h +++ b/kex.h @@ -102,6 +102,15 @@ enum kex_exchange { @@ -1393,7 +1432,7 @@ index a5ae6ac0..fe714141 100644 KEX_MAX }; -@@ -153,6 +162,12 @@ struct kex { +@@ -159,6 +168,12 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1406,7 +1445,7 @@ index a5ae6ac0..fe714141 100644 char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -174,8 +189,10 @@ struct kex { +@@ -180,8 +195,10 @@ struct kex { int kex_names_valid(const char *); char *kex_alg_list(char); @@ -1417,7 +1456,7 @@ index a5ae6ac0..fe714141 100644 int kex_exchange_identification(struct ssh *, int, const char *); -@@ -202,6 +219,12 @@ int kexgex_client(struct ssh *); +@@ -209,6 +226,12 @@ int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kex_gen_client(struct ssh *); int kex_gen_server(struct ssh *); @@ -1430,7 +1469,7 @@ index a5ae6ac0..fe714141 100644 int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -234,6 +257,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, +@@ -241,6 +264,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, const BIGNUM *, const u_char *, size_t, u_char *, size_t *); @@ -1444,10 +1483,10 @@ index a5ae6ac0..fe714141 100644 __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); diff --git a/kexdh.c b/kexdh.c -index 67133e33..edaa4676 100644 +index c1084f2..0faab21 100644 --- a/kexdh.c +++ b/kexdh.c -@@ -48,13 +48,23 @@ kex_dh_keygen(struct kex *kex) +@@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: @@ -1472,7 +1511,7 @@ index 67133e33..edaa4676 100644 break; case KEX_DH_GRP18_SHA512: diff --git a/kexgen.c b/kexgen.c -index 69348b96..c0e8c2f4 100644 +index 20f3c57..ca70484 100644 --- a/kexgen.c +++ b/kexgen.c @@ -44,7 +44,7 @@ @@ -1486,7 +1525,7 @@ index 69348b96..c0e8c2f4 100644 const struct sshbuf *client_version, diff --git a/kexgssc.c b/kexgssc.c new file mode 100644 -index 00000000..f6e1405e +index 0000000..1c62740 --- /dev/null +++ b/kexgssc.c @@ -0,0 +1,599 @@ @@ -2091,7 +2130,7 @@ index 00000000..f6e1405e +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/kexgsss.c b/kexgsss.c new file mode 100644 -index 00000000..60bc02de +index 0000000..a2c0214 --- /dev/null +++ b/kexgsss.c @@ -0,0 +1,474 @@ @@ -2570,7 +2609,7 @@ index 00000000..60bc02de +} +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/monitor.c b/monitor.c -index 2ce89fe9..ebf76c7f 100644 +index 7d42b6c..983082e 100644 --- a/monitor.c +++ b/monitor.c @@ -148,6 +148,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); @@ -2582,7 +2621,7 @@ index 2ce89fe9..ebf76c7f 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -220,11 +222,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -223,11 +225,18 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, @@ -2601,7 +2640,7 @@ index 2ce89fe9..ebf76c7f 100644 #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -293,6 +302,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -296,6 +305,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -2612,7 +2651,7 @@ index 2ce89fe9..ebf76c7f 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -406,6 +419,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -407,6 +420,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2623,7 +2662,7 @@ index 2ce89fe9..ebf76c7f 100644 if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1713,6 +1730,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1777,6 +1794,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2641,7 +2680,7 @@ index 2ce89fe9..ebf76c7f 100644 #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -@@ -1806,8 +1834,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1869,8 +1897,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; @@ -2652,7 +2691,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal_fr(r, "parse"); -@@ -1839,8 +1867,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1902,8 +1930,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2663,7 +2702,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal_fr(r, "ssh_gssapi_get_buffer_desc"); -@@ -1860,6 +1888,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1923,6 +1951,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2671,7 +2710,7 @@ index 2ce89fe9..ebf76c7f 100644 } return (0); } -@@ -1871,8 +1900,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1934,8 +1963,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 ret; int r; @@ -2682,7 +2721,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -1898,13 +1927,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1961,13 +1990,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -2704,7 +2743,7 @@ index 2ce89fe9..ebf76c7f 100644 sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1913,7 +1946,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1976,7 +2009,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -2717,7 +2756,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1921,5 +1958,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1984,5 +2021,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2803,10 +2842,10 @@ index 2ce89fe9..ebf76c7f 100644 #endif /* GSSAPI */ diff --git a/monitor.h b/monitor.h -index 683e5e07..2b1a2d59 100644 +index 6174b96..2878f66 100644 --- a/monitor.h +++ b/monitor.h -@@ -63,6 +63,8 @@ enum monitor_reqtype { +@@ -67,6 +67,8 @@ enum monitor_reqtype { MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, @@ -2816,10 +2855,10 @@ index 683e5e07..2b1a2d59 100644 struct ssh; diff --git a/monitor_wrap.c b/monitor_wrap.c -index 001a8fa1..6edb509a 100644 +index 0de136a..7fd3282 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -993,13 +993,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +@@ -1020,13 +1020,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int @@ -2836,7 +2875,7 @@ index 001a8fa1..6edb509a 100644 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, -@@ -1012,4 +1014,57 @@ mm_ssh_gssapi_userok(char *user) +@@ -1039,4 +1041,57 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -2895,10 +2934,10 @@ index 001a8fa1..6edb509a 100644 + #endif /* GSSAPI */ diff --git a/monitor_wrap.h b/monitor_wrap.h -index 23ab096a..485590c1 100644 +index 6fb5ef6..7bc2b0f 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -64,8 +64,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, +@@ -68,8 +68,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -2910,9 +2949,10 @@ index 23ab096a..485590c1 100644 #endif #ifdef USE_PAM -diff -up a/readconf.c.gsskex b/readconf.c ---- a/readconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/readconf.c 2021-08-27 12:25:42.556421509 +0200 +diff --git a/readconf.c b/readconf.c +index 42be690..fde930b 100644 +--- a/readconf.c ++++ b/readconf.c @@ -67,6 +67,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -2953,7 +2993,7 @@ diff -up a/readconf.c.gsskex b/readconf.c #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1113,10 +1128,42 @@ parse_time: +@@ -1120,10 +1135,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2996,7 +3036,7 @@ diff -up a/readconf.c.gsskex b/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -2306,7 +2353,13 @@ initialize_options(Options * options) +@@ -2332,7 +2379,13 @@ initialize_options(Options * options) options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; options->gss_authentication = -1; @@ -3010,8 +3050,8 @@ diff -up a/readconf.c.gsskex b/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2463,8 +2516,18 @@ fill_default_options(Options * options) - options->pubkey_authentication = 1; +@@ -2490,8 +2543,18 @@ fill_default_options(Options * options) + options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; + if (options->gss_keyex == -1) @@ -3029,7 +3069,7 @@ diff -up a/readconf.c.gsskex b/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -3246,7 +3309,14 @@ dump_client_config(Options *o, const cha +@@ -3286,7 +3349,14 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -3044,9 +3084,10 @@ diff -up a/readconf.c.gsskex b/readconf.c #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff -up a/readconf.h.gsskex b/readconf.h ---- a/readconf.h.gsskex 2021-08-27 12:05:29.248142431 +0200 -+++ b/readconf.h 2021-08-27 12:22:19.270679852 +0200 +diff --git a/readconf.h b/readconf.h +index ffb5ec4..788a534 100644 +--- a/readconf.h ++++ b/readconf.h @@ -39,7 +39,13 @@ typedef struct { int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ @@ -3061,9 +3102,10 @@ diff -up a/readconf.h.gsskex b/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up a/servconf.c.gsskex b/servconf.c ---- a/servconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/servconf.c 2021-08-27 12:28:15.887735189 +0200 +diff --git a/servconf.c b/servconf.c +index 423772b..eb574f5 100644 +--- a/servconf.c ++++ b/servconf.c @@ -70,6 +70,7 @@ #include "auth.h" #include "myproposal.h" @@ -3072,7 +3114,7 @@ diff -up a/servconf.c.gsskex b/servconf.c static void add_listen_addr(ServerOptions *, const char *, const char *, int); -@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions +@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3084,7 +3126,7 @@ diff -up a/servconf.c.gsskex b/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -356,10 +360,18 @@ fill_default_server_options(ServerOption +@@ -357,10 +361,18 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3103,7 +3145,7 @@ diff -up a/servconf.c.gsskex b/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -506,6 +518,7 @@ typedef enum { +@@ -508,6 +520,7 @@ typedef enum { sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -3111,7 +3153,7 @@ diff -up a/servconf.c.gsskex b/servconf.c sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -587,12 +600,22 @@ static struct { +@@ -590,12 +603,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3134,7 +3176,7 @@ diff -up a/servconf.c.gsskex b/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ -@@ -1576,6 +1599,10 @@ process_server_config_line_depth(ServerO +@@ -1578,6 +1601,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; @@ -3145,7 +3187,7 @@ diff -up a/servconf.c.gsskex b/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1584,6 +1611,22 @@ process_server_config_line_depth(ServerO +@@ -1586,6 +1613,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3168,7 +3210,7 @@ diff -up a/servconf.c.gsskex b/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2892,6 +2935,10 @@ dump_config(ServerOptions *o) +@@ -2906,6 +2949,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -3180,10 +3222,10 @@ diff -up a/servconf.c.gsskex b/servconf.c dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --git a/servconf.h b/servconf.h -index 4202a2d0..3f47ea25 100644 +index 9346155..cb7af38 100644 --- a/servconf.h +++ b/servconf.h -@@ -132,8 +132,11 @@ typedef struct { +@@ -141,8 +141,11 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -3196,10 +3238,10 @@ index 4202a2d0..3f47ea25 100644 * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/session.c b/session.c -index 8c0e54f7..06a33442 100644 +index baf2e3f..dfe2911 100644 --- a/session.c +++ b/session.c -@@ -2678,13 +2678,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2671,13 +2671,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3222,7 +3264,7 @@ index 8c0e54f7..06a33442 100644 /* remove agent socket */ diff --git a/ssh-gss.h b/ssh-gss.h -index 36180d07..70dd3665 100644 +index a8af117..58471bf 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -1,6 +1,6 @@ @@ -3268,7 +3310,7 @@ index 36180d07..70dd3665 100644 void *data; } ssh_gssapi_ccache; -@@ -72,8 +92,11 @@ typedef struct { +@@ -72,8 +96,11 @@ typedef struct { gss_buffer_desc displayname; gss_buffer_desc exportedname; gss_cred_id_t creds; @@ -3280,7 +3322,7 @@ index 36180d07..70dd3665 100644 } ssh_gssapi_client; typedef struct ssh_gssapi_mech_struct { -@@ -84,6 +107,7 @@ typedef struct ssh_gssapi_mech_struct { +@@ -84,6 +111,7 @@ typedef struct ssh_gssapi_mech_struct { int (*userok) (ssh_gssapi_client *, char *); int (*localname) (ssh_gssapi_client *, char **); void (*storecreds) (ssh_gssapi_client *); @@ -3288,7 +3330,7 @@ index 36180d07..70dd3665 100644 } ssh_gssapi_mech; typedef struct { -@@ -94,10 +118,11 @@ typedef struct { +@@ -94,10 +122,11 @@ typedef struct { gss_OID oid; /* client */ gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ @@ -3301,7 +3343,7 @@ index 36180d07..70dd3665 100644 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -109,6 +134,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); +@@ -109,6 +138,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); struct sshbuf; int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); @@ -3309,7 +3351,7 @@ index 36180d07..70dd3665 100644 OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, -@@ -123,17 +149,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); +@@ -123,17 +153,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(struct sshbuf *, const char *, const char *, const char *, const struct sshbuf *); @@ -3346,10 +3388,10 @@ index 36180d07..70dd3665 100644 #endif /* _SSH_GSS_H */ diff --git a/ssh.1 b/ssh.1 -index 60de6087..db5c65bc 100644 +index 9fe3d51..ba95ea6 100644 --- a/ssh.1 +++ b/ssh.1 -@@ -503,7 +503,13 @@ For full details of the options listed below, and their possible values, see +@@ -533,7 +533,13 @@ For full details of the options listed below, and their possible values, see .It GatewayPorts .It GlobalKnownHostsFile .It GSSAPIAuthentication @@ -3363,7 +3405,7 @@ index 60de6087..db5c65bc 100644 .It HashKnownHosts .It Host .It HostbasedAcceptedAlgorithms -@@ -579,6 +585,8 @@ flag), +@@ -611,6 +617,8 @@ flag), (supported message integrity codes), .Ar kex (key exchange algorithms), @@ -3373,10 +3415,10 @@ index 60de6087..db5c65bc 100644 (key types), .Ar key-cert diff --git a/ssh.c b/ssh.c -index 15aee569..110cf9c1 100644 +index 25be53d..244b7f3 100644 --- a/ssh.c +++ b/ssh.c -@@ -747,6 +747,8 @@ main(int ac, char **av) +@@ -783,6 +783,8 @@ main(int ac, char **av) else if (strcmp(optarg, "kex") == 0 || strcasecmp(optarg, "KexAlgorithms") == 0) cp = kex_alg_list('\n'); @@ -3385,7 +3427,7 @@ index 15aee569..110cf9c1 100644 else if (strcmp(optarg, "key") == 0) cp = sshkey_alg_list(0, 0, 0, '\n'); else if (strcmp(optarg, "key-cert") == 0) -@@ -772,8 +774,8 @@ main(int ac, char **av) +@@ -810,8 +812,8 @@ main(int ac, char **av) } else if (strcmp(optarg, "help") == 0) { cp = xstrdup( "cipher\ncipher-auth\ncompression\nkex\n" @@ -3397,7 +3439,7 @@ index 15aee569..110cf9c1 100644 if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); diff --git a/ssh_config b/ssh_config -index 5e8ef548..1ff999b6 100644 +index 036539d..255e9e0 100644 --- a/ssh_config +++ b/ssh_config @@ -24,6 +24,8 @@ @@ -3410,10 +3452,10 @@ index 5e8ef548..1ff999b6 100644 # CheckHostIP yes # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 -index 06a32d31..3f490697 100644 +index d1ede18..0a6c4a6 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -766,10 +766,68 @@ The default is +@@ -833,10 +833,68 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -3483,10 +3525,10 @@ index 06a32d31..3f490697 100644 Indicates that .Xr ssh 1 diff --git a/sshconnect2.c b/sshconnect2.c -index af00fb30..03bc87eb 100644 +index 58fe98d..4a7931f 100644 --- a/sshconnect2.c +++ b/sshconnect2.c -@@ -80,8 +80,6 @@ +@@ -81,8 +81,6 @@ #endif /* import */ @@ -3495,8 +3537,8 @@ index af00fb30..03bc87eb 100644 extern Options options; /* -@@ -163,6 +161,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) - char *s, *all_key; +@@ -226,6 +224,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, + char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; int r, use_known_hosts_order = 0; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3507,7 +3549,7 @@ index af00fb30..03bc87eb 100644 xxx_host = host; xxx_hostaddr = hostaddr; xxx_conn_info = cinfo; -@@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) +@@ -269,6 +272,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, compat_pkalg_proposal(ssh, options.hostkeyalgorithms); } @@ -3550,7 +3592,7 @@ index af00fb30..03bc87eb 100644 if (options.rekey_limit || options.rekey_interval) ssh_packet_set_rekey_limits(ssh, options.rekey_limit, options.rekey_interval); -@@ -224,16 +256,46 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) +@@ -287,16 +326,46 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, # ifdef OPENSSL_HAS_ECC ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; # endif @@ -3568,7 +3610,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) @@ -3598,7 +3640,7 @@ index af00fb30..03bc87eb 100644 if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) fatal_r(r, "kex_prop2buf"); -@@ -330,6 +392,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); +@@ -394,6 +463,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); static int input_gssapi_token(int type, u_int32_t, struct ssh *); static int input_gssapi_error(int, u_int32_t, struct ssh *); static int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -3606,7 +3648,7 @@ index af00fb30..03bc87eb 100644 #endif void userauth(struct ssh *, char *); -@@ -346,6 +409,11 @@ static char *authmethods_get(void); +@@ -410,6 +480,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -3618,7 +3660,7 @@ index af00fb30..03bc87eb 100644 {"gssapi-with-mic", userauth_gssapi, userauth_gssapi_cleanup, -@@ -716,12 +784,32 @@ userauth_gssapi(struct ssh *ssh) +@@ -785,12 +860,32 @@ userauth_gssapi(struct ssh *ssh) OM_uint32 min; int r, ok = 0; gss_OID mech = NULL; @@ -3652,7 +3694,7 @@ index af00fb30..03bc87eb 100644 /* Check to see whether the mechanism is usable before we offer it */ while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && -@@ -730,13 +811,15 @@ userauth_gssapi(struct ssh *ssh) +@@ -799,13 +894,15 @@ userauth_gssapi(struct ssh *ssh) elements[authctxt->mech_tried]; /* My DER encoding requires length<128 */ if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, @@ -3669,7 +3711,7 @@ index af00fb30..03bc87eb 100644 if (!ok || mech == NULL) return 0; -@@ -976,6 +1059,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) +@@ -1046,6 +1143,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) free(lang); return r; } @@ -3726,10 +3768,10 @@ index af00fb30..03bc87eb 100644 static int diff --git a/sshd.c b/sshd.c -index 60b2aaf7..d92f03aa 100644 +index 4662caf..c986698 100644 --- a/sshd.c +++ b/sshd.c -@@ -817,8 +817,8 @@ notify_hostkeys(struct ssh *ssh) +@@ -810,8 +810,8 @@ notify_hostkeys(struct ssh *ssh) } debug3_f("sent %u hostkeys", nkeys); if (nkeys == 0) @@ -3740,7 +3782,7 @@ index 60b2aaf7..d92f03aa 100644 sshpkt_fatal(ssh, r, "%s: send", __func__); sshbuf_free(buf); } -@@ -1852,7 +1852,8 @@ main(int ac, char **av) +@@ -1943,7 +1943,8 @@ main(int ac, char **av) free(fp); } accumulate_host_timing_secret(cfg, NULL); @@ -3750,9 +3792,9 @@ index 60b2aaf7..d92f03aa 100644 logit("sshd: no hostkeys available -- exiting."); exit(1); } -@@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh) - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( - ssh, list_hostkey_types()); +@@ -2429,6 +2430,48 @@ do_ssh2_kex(struct ssh *ssh) + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey = + compat_pkalg_proposal(ssh, list_hostkey_types()); +#if defined(GSSAPI) && defined(WITH_OPENSSL) + { @@ -3762,9 +3804,9 @@ index 60b2aaf7..d92f03aa 100644 + orig = myproposal[PROPOSAL_KEX_ALGS]; + + /* -+ * If we don't have a host key, then there's no point advertising -+ * the other key exchange algorithms -+ */ ++ * If we don't have a host key, then there's no point advertising ++ * the other key exchange algorithms ++ */ + + if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) + orig = NULL; @@ -3782,10 +3824,10 @@ index 60b2aaf7..d92f03aa 100644 + newstr = orig; + + /* -+ * If we've got GSSAPI mechanisms, then we've got the 'null' host -+ * key alg, but we can't tell people about it unless its the only -+ * host key algorithm we support -+ */ ++ * If we've got GSSAPI mechanisms, then we've got the 'null' host ++ * key alg, but we can't tell people about it unless its the only ++ * host key algorithm we support ++ */ + if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; + @@ -3799,7 +3841,7 @@ index 60b2aaf7..d92f03aa 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) fatal_r(r, "kex_setup"); -@@ -2362,7 +2405,18 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2444,7 +2487,18 @@ do_ssh2_kex(struct ssh *ssh) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -3820,10 +3862,10 @@ index 60b2aaf7..d92f03aa 100644 kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; kex->load_host_public_key=&get_hostkey_public_by_type; diff --git a/sshd_config b/sshd_config -index 19b7c91a..2c48105f 100644 +index 283bd88..47b5ecb 100644 --- a/sshd_config +++ b/sshd_config -@@ -69,6 +69,8 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -77,6 +77,8 @@ AuthorizedKeysFile .ssh/authorized_keys # GSSAPI options #GSSAPIAuthentication no #GSSAPICleanupCredentials yes @@ -3833,10 +3875,10 @@ index 19b7c91a..2c48105f 100644 # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will diff --git a/sshd_config.5 b/sshd_config.5 -index 70ccea44..f6b41a2f 100644 +index 57363e9..861a9ec 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -646,6 +646,11 @@ Specifies whether to automatically destroy the user's credentials cache +@@ -650,6 +650,11 @@ Specifies whether to automatically destroy the user's credentials cache on logout. The default is .Cm yes . @@ -3848,7 +3890,7 @@ index 70ccea44..f6b41a2f 100644 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -660,6 +665,32 @@ machine's default store. +@@ -664,6 +669,32 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Cm yes . @@ -3882,18 +3924,18 @@ index 70ccea44..f6b41a2f 100644 Specifies the signature algorithms that will be accepted for hostbased authentication as a list of comma-separated patterns. diff --git a/sshkey.c b/sshkey.c -index 57995ee6..fd5b7724 100644 +index 7709323..f78bc15 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -154,6 +154,7 @@ static const struct keytype keytypes[] = { - KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 }, +@@ -162,6 +162,7 @@ static const struct keytype keytypes[] = { + # endif /* ENABLE_SK */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ + { "null", "null", NULL, KEY_NULL, 0, 0, 0 }, { NULL, NULL, NULL, -1, -1, 0, 0 } }; -@@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -286,7 +287,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { @@ -3903,10 +3945,10 @@ index 57995ee6..fd5b7724 100644 if (!include_sigonly && kt->sigonly) continue; diff --git a/sshkey.h b/sshkey.h -index 71a3fddc..37a43a67 100644 +index be254e6..0e5ef9d 100644 --- a/sshkey.h +++ b/sshkey.h -@@ -69,6 +69,7 @@ enum sshkey_types { +@@ -71,6 +71,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, KEY_ED25519_SK_CERT, @@ -3914,3 +3956,6 @@ index 71a3fddc..37a43a67 100644 KEY_UNSPEC }; +-- +2.27.0 + diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 859260791dcfc7e6a703b14bc38cbe6600283a19..95030c50fdec49672d9edbee40e70a80d7a139e6 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,7 +1,98 @@ -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( +Reference:https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-8.0p1-pkcs11-uri.patch + +--- + Makefile.in | 20 +- + configure.ac | 37 ++ + regress/agent-pkcs11.sh | 2 +- + regress/pkcs11.sh | 349 +++++++++++++++ + regress/unittests/pkcs11/tests.c | 337 +++++++++++++++ + ssh-add.c | 44 +- + ssh-agent.c | 101 ++++- + ssh-keygen.c | 7 +- + ssh-pkcs11-client.c | 3 + + ssh-pkcs11-uri.c | 419 ++++++++++++++++++ + ssh-pkcs11-uri.h | 42 ++ + ssh-pkcs11.c | 715 +++++++++++++++++++++++-------- + ssh-pkcs11.h | 4 + + ssh.c | 104 +++-- + ssh_config.5 | 15 + + 15 files changed, 1961 insertions(+), 238 deletions(-) + create mode 100644 regress/pkcs11.sh + create mode 100644 regress/unittests/pkcs11/tests.c + create mode 100644 ssh-pkcs11-uri.c + create mode 100644 ssh-pkcs11-uri.h + +diff --git a/Makefile.in b/Makefile.in +index 8229885..45f7a93 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -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 \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o \ + hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ +@@ -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) ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so +@@ -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 +@@ -513,6 +517,7 @@ regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/sshkey + $(MKDIR_P) `pwd`/regress/unittests/sshsig + $(MKDIR_P) `pwd`/regress/unittests/utf8 ++ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 + $(MKDIR_P) `pwd`/regress/misc/sk-dummy + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile +@@ -679,6 +684,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) + ++UNITTESTS_TEST_PKCS11_OBJS=\ ++ regress/unittests/pkcs11/tests.o ++ ++regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ regress/unittests/test_helper/libtest_helper.a libssh.a ++ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ ++ regress/unittests/test_helper/libtest_helper.a \ ++ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) ++ + # These all need to be compiled -fPIC, so they are treated differently. + SK_DUMMY_OBJS=\ + regress/misc/sk-dummy/sk-dummy.lo \ +@@ -713,7 +728,8 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ + regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ + regress/unittests/sshkey/test_sshkey$(EXEEXT) \ + regress/unittests/sshsig/test_sshsig$(EXEEXT) \ +- regress/unittests/utf8/test_utf8$(EXEEXT) ++ regress/unittests/utf8/test_utf8$(EXEEXT) \ ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + + tests: file-tests t-exec interop-tests unit + echo all tests passed +diff --git a/configure.ac b/configure.ac +index 6f7dc48..b57d0a5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2035,12 +2035,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -16,7 +107,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]) +@@ -2064,6 +2066,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -57,7 +148,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 +@@ -5651,6 +5687,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -65,74 +156,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} \ - 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 \ -- ssh-pkcs11.o smult_curve25519_ref.o \ -+ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ - ssh-ed25519.o digest-openssl.o digest-libc.o \ - hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -302,6 +302,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) -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - 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 - 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 - (cd openbsd-compat && $(MAKE) distclean) - if test -d pkg ; then \ - rm -fr pkg ; \ -@@ -513,6 +517,7 @@ regress-prep: - $(MKDIR_P) `pwd`/regress/unittests/sshkey - $(MKDIR_P) `pwd`/regress/unittests/sshsig - $(MKDIR_P) `pwd`/regress/unittests/utf8 -+ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 - $(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 - regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+UNITTESTS_TEST_PKCS11_OBJS=\ -+ regress/unittests/pkcs11/tests.o -+ -+regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} \ -+ regress/unittests/test_helper/libtest_helper.a libssh.a -+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ -+ regress/unittests/test_helper/libtest_helper.a \ -+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -+ - # 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 - regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ - regress/unittests/sshkey/test_sshkey$(EXEEXT) \ - regress/unittests/sshsig/test_sshsig$(EXEEXT) \ -- regress/unittests/utf8/test_utf8$(EXEEXT) -+ regress/unittests/utf8/test_utf8$(EXEEXT) \ -+ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - - tests: file-tests t-exec interop-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 +diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh +index 268a70d..72efa3b 100644 +--- a/regress/agent-pkcs11.sh ++++ b/regress/agent-pkcs11.sh @@ -113,7 +113,7 @@ else done @@ -142,34 +169,11 @@ diff -up openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/ 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 - known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ - modpipe netcat no_identity_config \ - pidfile putty.rsa2 ready regress.log remote_pid \ -- revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \ -+ revoked-* rsa rsa-agent rsa-agent.pub rsa-agent-cert.pub \ -+ rsa.pub rsa_ssh2_cr.prv pkcs11*.crt pkcs11*.key pkcs11.info \ - 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: - V="" ; \ - test "x${USE_VALGRIND}" = "x" || \ - V=${.CURDIR}/valgrind-unit.sh ; \ -- $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ -- $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ -+ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ -+ $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ -+ $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -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 --git a/regress/pkcs11.sh b/regress/pkcs11.sh +new file mode 100644 +index 0000000..a91aee9 +--- /dev/null ++++ b/regress/pkcs11.sh @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -520,20 +524,11 @@ 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 @@ - - 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 +diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c +new file mode 100644 +index 0000000..d726fdf +--- /dev/null ++++ b/regress/unittests/pkcs11/tests.c @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2017 Red Hat @@ -872,26 +867,28 @@ 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 @@ - #include "digest.h" +diff --git a/ssh-add.c b/ssh-add.c +index 777f21e..940e3a0 100644 +--- a/ssh-add.c ++++ b/ssh-add.c +@@ -69,6 +69,7 @@ #include "ssh-sk.h" #include "sk-api.h" + #include "hostfile.h" +#include "ssh-pkcs11-uri.h" /* argv0 */ extern char *__progname; -@@ -229,6 +230,32 @@ delete_all(int agent_fd, int qflag) +@@ -230,6 +231,34 @@ delete_all(int agent_fd, int qflag) return ret; } +#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *, int, char *); ++static int update_card(int, int, const char *, int, struct dest_constraint **, size_t, char *); + +int -+update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) ++update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag, ++ struct dest_constraint **dest_constraints, size_t ndest_constraints) +{ + char *pin = NULL; + struct pkcs11_uri *uri; @@ -909,19 +906,20 @@ 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, pin); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag, ++ dest_constraints, ndest_constraints, pin); +} +#endif + static int add_file(int agent_fd, const char *filename, int key_only, int qflag, - const char *skprovider) -@@ -445,12 +472,11 @@ add_file(int agent_fd, const char *filen - } + const char *skprovider, struct dest_constraint **dest_constraints, +@@ -445,12 +474,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag, static int --update_card(int agent_fd, int add, const char *id, int qflag) -+update_card(int agent_fd, int add, const char *id, int qflag, char *pin) + 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) { - char *pin = NULL; int r, ret = -1; @@ -931,33 +929,35 @@ diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -630,6 +656,13 @@ static int - do_file(int agent_fd, int deleting, int key_only, char *file, int qflag, - const char *skprovider) +@@ -634,6 +662,14 @@ do_file(int agent_fd, int deleting, int key_only, 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) && + strncmp(file, PKCS11_URI_SCHEME, + strlen(PKCS11_URI_SCHEME)) == 0) { -+ return update_pkcs11_uri(agent_fd, !deleting, file, qflag); ++ return update_pkcs11_uri(agent_fd, !deleting, file, qflag, ++ dest_constraints, ndest_constraints); + } +#endif if (deleting) { if (delete_file(agent_fd, file, key_only, qflag) == -1) return -1; -@@ -813,7 +846,7 @@ main(int argc, char **argv) +@@ -960,7 +996,7 @@ main(int argc, char **argv) } if (pkcs11provider != NULL) { if (update_card(agent_fd, !deleting, pkcs11provider, -- qflag) == -1) -+ qflag, NULL) == -1) +- qflag, dest_constraints, ndest_constraints) == -1) ++ qflag, dest_constraints, ndest_constraints, 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 --git a/ssh-agent.c b/ssh-agent.c +index 006ddad..50d0638 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -1369,10 +1369,72 @@ no_identities(SocketEntry *e) } #ifdef ENABLE_PKCS11 @@ -1031,7 +1031,7 @@ 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 +@@ -1393,33 +1455,28 @@ process_add_smartcard_key(SocketEntry *e) error_f("failed to parse constraints"); goto send; } @@ -1073,15 +1073,15 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c } id->death = death; id->confirm = confirm; -@@ -910,6 +967,7 @@ process_add_smartcard_key(SocketEntry *e +@@ -1438,6 +1495,7 @@ process_add_smartcard_key(SocketEntry *e) send: free(pin); free(provider); + free(sane_uri); free(keys); free(comments); - send_status(e, success); -@@ -918,7 +976,7 @@ send: + free_dest_constraints(dest_constraints, ndest_constraints); +@@ -1447,7 +1505,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1090,7 +1090,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 +@@ -1459,30 +1517,29 @@ process_remove_smartcard_key(SocketEntry *e) } free(pin); @@ -1127,465 +1127,766 @@ 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 - .Cm CertificateFile - in order to provide any certificate also needed for authentication with - the identity. -+.Pp -+The authentication identity can be also specified in a form of PKCS#11 URI -+starting with a string -+.Cm pkcs11: . -+There is supported a subset of the PKCS#11 URI as defined -+in RFC 7512 (implemented path arguments -+.Cm id , -+.Cm manufacturer , -+.Cm object , -+.Cm token -+and query arguments -+.Cm module-path -+and -+.Cm pin-value -+). The URI can not be in quotes. - .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) - options.gss_deleg_creds = 1; - break; - case 'i': -+#ifdef ENABLE_PKCS11 -+ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(optarg, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ add_identity_file(&options, NULL, optarg, 1); -+ break; +diff --git a/ssh-keygen.c b/ssh-keygen.c +index 9b2beda..1a7de44 100644 +--- a/ssh-keygen.c ++++ b/ssh-keygen.c +@@ -864,8 +864,11 @@ do_download(struct passwd *pw) + free(fp); + } else { + (void) sshkey_write(keys[i], stdout); /* XXX check */ +- fprintf(stdout, "%s%s\n", +- *(comments[i]) == '\0' ? "" : " ", comments[i]); ++ if (*(comments[i]) != '\0') { ++ fprintf(stdout, " %s", comments[i]); + } -+#endif - 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) - #ifdef ENABLE_PKCS11 - (void)pkcs11_del_provider(options.pkcs11_provider); - #endif -+ pkcs11_terminate(); ++ (void) pkcs11_uri_write(keys[i], stdout); ++ fprintf(stdout, "\n"); + } + free(comments[i]); + sshkey_free(keys[i]); +diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c +index cfd833d..9e4f02b 100644 +--- a/ssh-pkcs11-client.c ++++ b/ssh-pkcs11-client.c +@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, + u_int nkeys, i; + struct sshbuf *msg; - skip_connect: - exit_status = ssh_session2(ssh, cinfo); -@@ -2197,6 +2206,45 @@ ssh_session2(struct ssh *ssh, const stru - options.escape_char : SSH_ESCAPECHAR_NONE, id); - } ++ 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 *pin, struct sshkey ***keysp, + *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); + if (labelsp) + *labelsp = xcalloc(nkeys, sizeof(char *)); ++ debug_f("nkeys = %u", nkeys); + for (i = 0; i < nkeys; i++) { + /* XXX clean up properly instead of fatal() */ + if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || +diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c +new file mode 100644 +index 0000000..a8a4946 +--- /dev/null ++++ b/ssh-pkcs11-uri.c +@@ -0,0 +1,419 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "includes.h" ++ +#ifdef ENABLE_PKCS11 -+static void -+load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], -+ struct sshkey *identity_keys[], int *n_ids) -+{ -+ int nkeys, i; -+ struct sshkey **keys; -+ struct pkcs11_uri *uri; + -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); ++#include ++#include + -+ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++#include "sshkey.h" ++#include "sshbuf.h" ++#include "log.h" + -+ /* we need to merge URI and provider together */ -+ if (options.pkcs11_provider != NULL && uri->module_path == NULL) -+ uri->module_path = strdup(options.pkcs11_provider); ++#define CRYPTOKI_COMPAT ++#include "pkcs11.h" + -+ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && -+ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { -+ for (i = 0; i < nkeys; i++) { -+ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { -+ sshkey_free(keys[i]); -+ continue; -+ } -+ identity_keys[*n_ids] = keys[i]; -+ identity_files[*n_ids] = pkcs11_uri_get(uri); -+ (*n_ids)++; -+ } -+ free(keys); -+ } ++#include "ssh-pkcs11-uri.h" + -+ pkcs11_uri_cleanup(uri); -+} -+#endif /* ENABLE_PKCS11 */ ++#define PKCS11_URI_PATH_SEPARATOR ";" ++#define PKCS11_URI_QUERY_SEPARATOR "&" ++#define PKCS11_URI_VALUE_SEPARATOR "=" ++#define PKCS11_URI_ID "id" ++#define PKCS11_URI_TOKEN "token" ++#define PKCS11_URI_OBJECT "object" ++#define PKCS11_URI_LIB_MANUF "library-manufacturer" ++#define PKCS11_URI_MANUF "manufacturer" ++#define PKCS11_URI_MODULE_PATH "module-path" ++#define PKCS11_URI_PIN_VALUE "pin-value" + - /* 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 - char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; - struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; - int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; --#ifdef ENABLE_PKCS11 -- struct sshkey **keys = NULL; -- char **comments = NULL; -- int nkeys; --#endif /* PKCS11 */ - - n_ids = n_certs = 0; - memset(identity_files, 0, sizeof(identity_files)); -@@ -2228,33 +2271,46 @@ load_public_identity_files(const struct - sizeof(certificate_file_userprovided)); - - #ifdef ENABLE_PKCS11 -- if (options.pkcs11_provider != NULL && -- options.num_identity_files < SSH_MAX_IDENTITY_FILES && -- (pkcs11_init(!options.batch_mode) == 0) && -- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, -- &keys, &comments)) > 0) { -- for (i = 0; i < nkeys; i++) { -- if (n_ids >= SSH_MAX_IDENTITY_FILES) { -- sshkey_free(keys[i]); -- free(comments[i]); -- continue; -- } -- identity_keys[n_ids] = keys[i]; -- identity_files[n_ids] = comments[i]; /* transferred */ -- n_ids++; -- } -- free(keys); -- free(comments); -+ /* handle fallback from PKCS11Provider option */ -+ pkcs11_init(!options.batch_mode); -+ -+ if (options.pkcs11_provider != NULL) { -+ struct pkcs11_uri *uri; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ /* Construct simple PKCS#11 URI to simplify access */ -+ uri->module_path = strdup(options.pkcs11_provider); ++/* Keyword tokens. */ ++typedef enum { ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, ++ pPinValue, pBadOption ++} pkcs11uriOpCodes; + -+ /* Add it as any other IdentityFile */ -+ cp = pkcs11_uri_get(uri); -+ add_identity_file(&options, NULL, cp, 1); -+ free(cp); ++/* Textual representation of the tokens. */ ++static struct { ++ const char *name; ++ pkcs11uriOpCodes opcode; ++} keywords[] = { ++ { PKCS11_URI_ID, pId }, ++ { PKCS11_URI_TOKEN, pToken }, ++ { PKCS11_URI_OBJECT, pObject }, ++ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, ++ { PKCS11_URI_MANUF, pManufacturer }, ++ { PKCS11_URI_MODULE_PATH, pModulePath }, ++ { PKCS11_URI_PIN_VALUE, pPinValue }, ++ { NULL, pBadOption } ++}; + -+ pkcs11_uri_cleanup(uri); - } - #endif /* ENABLE_PKCS11 */ - for (i = 0; i < options.num_identity_files; i++) { -+ char *name = options.identity_files[i]; - if (n_ids >= SSH_MAX_IDENTITY_FILES || -- strcasecmp(options.identity_files[i], "none") == 0) { -+ strcasecmp(name, "none") == 0) { - free(options.identity_files[i]); - options.identity_files[i] = NULL; - continue; - } -- cp = tilde_expand_filename(options.identity_files[i], getuid()); -+#ifdef ENABLE_PKCS11 -+ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(name, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ load_pkcs11_identity(name, identity_files, -+ identity_keys, &n_ids); -+ free(options.identity_files[i]); -+ continue; -+ } -+#endif /* ENABLE_PKCS11 */ -+ cp = tilde_expand_filename(name, getuid()); - 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) - free(fp); - } else { - (void) sshkey_write(keys[i], stdout); /* XXX check */ -- fprintf(stdout, "%s%s\n", -- *(comments[i]) == '\0' ? "" : " ", comments[i]); -+ if (*(comments[i]) != '\0') { -+ fprintf(stdout, " %s", comments[i]); -+ } -+ (void) pkcs11_uri_write(keys[i], stdout); -+ fprintf(stdout, "\n"); - } - 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; - struct sshbuf *msg; - -+ debug_f("called, name = %s", name); ++static pkcs11uriOpCodes ++parse_token(const char *cp) ++{ ++ u_int i; + - if (fd < 0 && pkcs11_start_helper() < 0) - return (-1); - -@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pi - *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); - if (labelsp) - *labelsp = xcalloc(nkeys, sizeof(char *)); -+ debug_f("nkeys = %u", nkeys); - 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 -@@ -55,8 +55,8 @@ struct pkcs11_slotinfo { - int logged_in; - }; - --struct pkcs11_provider { -- char *name; -+struct pkcs11_module { -+ char *module_path; - void *handle; - CK_FUNCTION_LIST *function_list; - CK_INFO info; -@@ -65,6 +65,13 @@ struct pkcs11_provider { - struct pkcs11_slotinfo *slotinfo; - int valid; - int refcount; -+}; ++ for (i = 0; keywords[i].name; i++) ++ if (strncasecmp(cp, keywords[i].name, ++ strlen(keywords[i].name)) == 0) ++ return keywords[i].opcode; + -+struct pkcs11_provider { -+ char *name; -+ struct pkcs11_module *module; /* can be shared between various providers */ -+ int refcount; -+ int valid; - TAILQ_ENTRY(pkcs11_provider) next; - }; - -@@ -75,6 +82,7 @@ struct pkcs11_key { - CK_ULONG slotidx; - char *keyid; - int keyid_len; -+ char *label; - }; - - int pkcs11_interactive = 0; -@@ -106,26 +114,61 @@ pkcs11_init(int interactive) - * this is called when a provider gets unregistered. - */ - static void --pkcs11_provider_finalize(struct pkcs11_provider *p) -+pkcs11_module_finalize(struct pkcs11_module *m) - { - CK_RV rv; - CK_ULONG i; - -- debug_f("provider \"%s\" refcount %d valid %d", -- p->name, p->refcount, p->valid); -- if (!p->valid) -+ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); -+ if (!m->valid) - return; -- for (i = 0; i < p->nslots; i++) { -- if (p->slotinfo[i].session && -- (rv = p->function_list->C_CloseSession( -- p->slotinfo[i].session)) != CKR_OK) -+ for (i = 0; i < m->nslots; i++) { -+ if (m->slotinfo[i].session && -+ (rv = m->function_list->C_CloseSession( -+ m->slotinfo[i].session)) != CKR_OK) - error("C_CloseSession failed: %lu", rv); - } -- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) -+ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) - error("C_Finalize failed: %lu", rv); -+ m->valid = 0; -+ m->function_list = NULL; -+ dlclose(m->handle); ++ return pBadOption; +} + -+/* -+ * remove a reference to the pkcs11 module. -+ * called when a provider is unregistered. -+ */ -+static void -+pkcs11_module_unref(struct pkcs11_module *m) ++int ++percent_decode(char *data, char **outp) +{ -+ debug_f("%p refcount %d", m, m->refcount); -+ if (--m->refcount <= 0) { -+ pkcs11_module_finalize(m); -+ if (m->valid) -+ error_f("%p still valid", m); -+ free(m->slotlist); -+ free(m->slotinfo); -+ free(m->module_path); -+ free(m); ++ char tmp[3]; ++ char *out, *tmp_end; ++ char *p = data; ++ long value; ++ size_t outlen = 0; ++ ++ out = malloc(strlen(data)+1); /* upper bound */ ++ if (out == NULL) ++ return -1; ++ while (*p != '\0') { ++ switch (*p) { ++ case '%': ++ p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[0] = *p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[1] = *p++; ++ tmp[2] = '\0'; ++ tmp_end = NULL; ++ value = strtol(tmp, &tmp_end, 16); ++ if (tmp_end != tmp+2) ++ goto fail; ++ else ++ out[outlen++] = (char) value; ++ break; ++ default: ++ out[outlen++] = *p++; ++ break; ++ } + } ++ ++ /* zero terminate */ ++ out[outlen] = '\0'; ++ *outp = out; ++ return outlen; ++fail: ++ free(out); ++ return -1; +} + -+/* -+ * finalize a provider shared library, it's no longer usable. -+ * however, there might still be keys referencing this provider, -+ * so the actual freeing of memory is handled by pkcs11_provider_unref(). -+ * this is called when a provider gets unregistered. -+ */ -+static void -+pkcs11_provider_finalize(struct pkcs11_provider *p) ++struct sshbuf * ++percent_encode(const char *data, size_t length, const char *allow_list) +{ -+ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); -+ if (!p->valid) -+ return; -+ pkcs11_module_unref(p->module); -+ p->module = NULL; - p->valid = 0; -- p->function_list = NULL; -- dlclose(p->handle); - } - - /* -@@ -137,11 +180,9 @@ pkcs11_provider_unref(struct pkcs11_prov - { - debug_f("provider \"%s\" refcount %d", p->name, p->refcount); - if (--p->refcount <= 0) { -- if (p->valid) -- error_f("provider \"%s\" still valid", p->name); - free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -+ if (p->module) -+ pkcs11_module_unref(p->module); - free(p); - } - } -@@ -159,6 +200,20 @@ pkcs11_terminate(void) - } - } - -+/* lookup provider by module path */ -+static struct pkcs11_module * -+pkcs11_provider_lookup_module(char *module_path) -+{ -+ struct pkcs11_provider *p; ++ struct sshbuf *b = NULL; ++ char tmp[4], *cp; ++ size_t i; + -+ TAILQ_FOREACH(p, &pkcs11_providers, next) { -+ debug("check %p %s (%s)", p, p->name, p->module->module_path); -+ if (!strcmp(module_path, p->module->module_path)) -+ return (p->module); ++ if ((b = sshbuf_new()) == NULL) ++ return NULL; ++ for (i = 0; i < length; i++) { ++ cp = strchr(allow_list, data[i]); ++ /* if c is specified as '\0' pointer to terminator is returned !! */ ++ if (cp != NULL && *cp != '\0') { ++ if (sshbuf_put(b, &data[i], 1) != 0) ++ goto err; ++ } else ++ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 ++ || sshbuf_put(b, tmp, 3) != 0) ++ goto err; + } -+ return (NULL); ++ if (sshbuf_put(b, "\0", 1) == 0) ++ return b; ++err: ++ sshbuf_free(b); ++ return NULL; +} + - /* lookup provider by name */ - static struct pkcs11_provider * - pkcs11_provider_lookup(char *provider_id) -@@ -173,19 +228,55 @@ pkcs11_provider_lookup(char *provider_id - return (NULL); - } - -+int pkcs11_del_provider_by_uri(struct pkcs11_uri *); ++char * ++pkcs11_uri_append(char *part, const char *separator, const char *key, ++ struct sshbuf *value) ++{ ++ char *new_part; ++ size_t size = 0; + - /* unregister provider by name */ - int - pkcs11_del_provider(char *provider_id) - { -+ int rv; -+ struct pkcs11_uri *uri; ++ if (value == NULL) ++ return NULL; + -+ debug_f("called, provider_id = %s", provider_id); ++ size = asprintf(&new_part, ++ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", ++ (part != NULL ? part : ""), ++ (part != NULL ? separator : ""), ++ key, sshbuf_ptr(value)); ++ sshbuf_free(value); ++ free(part); + -+ if (provider_id == NULL) -+ return 0; ++ if (size <= 0) ++ return NULL; ++ return new_part; ++} + -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); ++char * ++pkcs11_uri_get(struct pkcs11_uri *uri) ++{ ++ size_t size = 0; ++ char *p = NULL, *path = NULL, *query = NULL; + -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); ++ /* compose a percent-encoded ID */ ++ if (uri->id_len > 0) { ++ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_ID, key_id); ++ if (path == NULL) ++ goto err; + } + -+ rv = pkcs11_del_provider_by_uri(uri); -+ pkcs11_uri_cleanup(uri); -+ return rv; ++ /* Write object label */ ++ if (uri->object) { ++ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_OBJECT, label); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write token label */ ++ if (uri->token) { ++ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_TOKEN, label); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write manufacturer */ ++ if (uri->manuf) { ++ struct sshbuf *manuf = percent_encode(uri->manuf, ++ strlen(uri->manuf), PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_MANUF, manuf); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write module_path */ ++ if (uri->module_path) { ++ struct sshbuf *module = percent_encode(uri->module_path, ++ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); ++ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, ++ PKCS11_URI_MODULE_PATH, module); ++ if (query == NULL) ++ goto err; ++ } ++ ++ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", ++ path != NULL ? path : "", ++ query != NULL ? "?" : "", ++ query != NULL ? query : ""); ++err: ++ free(query); ++ free(path); ++ if (size <= 0) ++ return NULL; ++ return p; +} + -+/* unregister provider by PKCS#11 URI */ -+int -+pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) ++struct pkcs11_uri * ++pkcs11_uri_init() +{ - struct pkcs11_provider *p; -+ int rv = -1; -+ char *provider_uri = pkcs11_uri_get(uri); - -- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3_f("called with provider %s", provider_uri); ++ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); ++ return d; ++} ++ ++void ++pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) ++{ ++ if (pkcs11 == NULL) { ++ return; ++ } ++ ++ free(pkcs11->id); ++ free(pkcs11->module_path); ++ free(pkcs11->token); ++ free(pkcs11->object); ++ free(pkcs11->lib_manuf); ++ free(pkcs11->manuf); ++ if (pkcs11->pin) ++ freezero(pkcs11->pin, strlen(pkcs11->pin)); ++ free(pkcs11); ++} + -+ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); -- return (0); -+ rv = 0; - } -- return (-1); -+ free(provider_uri); -+ return rv; - } - - static RSA_METHOD *rsa_method; -@@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; - static int ec_key_idx = 0; - #endif - -+/* -+ * This can't be in the ssh-pkcs11-uri, becase we can not depend on -+ * PKCS#11 structures in ssh-agent (using client-helper communication) -+ */ +int -+pkcs11_uri_write(const struct sshkey *key, FILE *f) ++pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) +{ ++ char *saveptr1, *saveptr2, *str1, *str2, *tok; ++ int rv = 0, len; + char *p = NULL; -+ struct pkcs11_uri uri; -+ struct pkcs11_key *k11; + -+ /* sanity - is it a RSA key with associated app_data? */ -+ switch (key->type) { -+ case KEY_RSA: -+ k11 = RSA_get_ex_data(key->rsa, rsa_idx); -+ break; -+#ifdef HAVE_EC_KEY_METHOD_NEW -+ case KEY_ECDSA: -+ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); -+ break; -+#endif -+ default: -+ error("Unknown key type %d", key->type); ++ size_t scheme_len = strlen(PKCS11_URI_SCHEME); ++ if (strlen(uri) < scheme_len || /* empty URI matches everything */ ++ strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { ++ error_f("The '%s' does not look like PKCS#11 URI", uri); + return -1; + } -+ if (k11 == NULL) { -+ error("Failed to get ex_data for key type %d", key->type); -+ return (-1); -+ } + -+ /* omit type -- we are looking for private-public or private-certificate pairs */ -+ uri.id = k11->keyid; -+ uri.id_len = k11->keyid_len; -+ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; -+ uri.object = k11->label; -+ 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; ++ if (pkcs11 == NULL) { ++ error_f("Bad arguments. The pkcs11 can't be null"); ++ return -1; ++ } + -+ p = pkcs11_uri_get(&uri); ++ /* skip URI schema name */ ++ p = strdup(uri); ++ str1 = p; ++ ++ /* everything before ? */ ++ tok = strtok_r(str1, "?", &saveptr1); ++ if (tok == NULL) { ++ error_f("pk11-path expected, got EOF"); ++ rv = -1; ++ goto out; ++ } ++ ++ /* skip URI schema name: ++ * the scheme ensures that there is at least something before "?" ++ * allowing empty pk11-path. Resulting token at worst pointing to ++ * \0 byte */ ++ tok = tok + scheme_len; ++ ++ /* parse pk11-path */ ++ for (str2 = tok; ; str2 = NULL) { ++ char **charptr, *arg = NULL; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode != pBadOption) ++ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ ++ ++ switch (opcode) { ++ case pId: ++ /* CKA_ID */ ++ if (pkcs11->id != NULL) { ++ verbose_f("The id already set in the PKCS#11 URI"); ++ rv = -1; ++ goto out; ++ } ++ len = percent_decode(arg, &pkcs11->id); ++ if (len <= 0) { ++ verbose_f("Failed to percent-decode CKA_ID: %s", arg); ++ rv = -1; ++ goto out; ++ } else ++ pkcs11->id_len = len; ++ debug3_f("Setting CKA_ID = %s from PKCS#11 URI", arg); ++ break; ++ case pToken: ++ /* CK_TOKEN_INFO -> label */ ++ charptr = &pkcs11->token; ++ parse_string: ++ if (*charptr != NULL) { ++ verbose_f("The %s already set in the PKCS#11 URI", ++ keywords[opcode].name); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, charptr); ++ debug3_f("Setting %s = %s from PKCS#11 URI", ++ keywords[opcode].name, *charptr); ++ break; ++ ++ case pObject: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->object; ++ goto parse_string; ++ ++ case pManufacturer: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->manuf; ++ goto parse_string; ++ ++ case pLibraryManufacturer: ++ /* CK_INFO -> manufacturerID */ ++ charptr = &pkcs11->lib_manuf; ++ goto parse_string; ++ ++ default: ++ /* Unrecognized attribute in the URI path SHOULD be error */ ++ verbose_f("Unknown part of path in PKCS#11 URI: %s", tok); ++ } ++ } ++ ++ tok = strtok_r(NULL, "?", &saveptr1); ++ if (tok == NULL) { ++ goto out; ++ } ++ /* parse pk11-query (optional) */ ++ for (str2 = tok; ; str2 = NULL) { ++ char *arg; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode != pBadOption) ++ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ ++ ++ switch (opcode) { ++ case pModulePath: ++ /* module-path is PKCS11Provider */ ++ if (pkcs11->module_path != NULL) { ++ verbose_f("Multiple module-path attributes are" ++ "not supported the PKCS#11 URI"); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, &pkcs11->module_path); ++ debug3_f("Setting PKCS11Provider = %s from PKCS#11 URI", ++ pkcs11->module_path); ++ break; ++ ++ case pPinValue: ++ /* pin-value */ ++ if (pkcs11->pin != NULL) { ++ verbose_f("Multiple pin-value attributes are" ++ "not supported the PKCS#11 URI"); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, &pkcs11->pin); ++ debug3_f("Setting PIN from PKCS#11 URI"); ++ break; ++ ++ default: ++ /* Unrecognized attribute in the URI query SHOULD be ignored */ ++ verbose_f("Unknown part of query in PKCS#11 URI: %s", tok); ++ } ++ } ++out: ++ free(p); ++ return rv; ++} ++ ++#endif /* ENABLE_PKCS11 */ +diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h +new file mode 100644 +index 0000000..942a5a5 +--- /dev/null ++++ b/ssh-pkcs11-uri.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#define PKCS11_URI_SCHEME "pkcs11:" ++#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ ++ "0123456789_-.()" ++ ++struct pkcs11_uri { ++ /* path */ ++ char *id; ++ size_t id_len; ++ char *token; ++ char *object; ++ char *lib_manuf; ++ char *manuf; ++ /* query */ ++ char *module_path; ++ char *pin; /* Only parsed, but not printed */ ++}; ++ ++struct pkcs11_uri *pkcs11_uri_init(); ++void pkcs11_uri_cleanup(struct pkcs11_uri *); ++int pkcs11_uri_parse(const char *, struct pkcs11_uri *); ++struct pkcs11_uri *pkcs11_uri_init(); ++char *pkcs11_uri_get(struct pkcs11_uri *uri); ++ +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +index b2e2b32..720ae2a 100644 +--- a/ssh-pkcs11.c ++++ b/ssh-pkcs11.c +@@ -55,8 +55,8 @@ struct pkcs11_slotinfo { + int logged_in; + }; + +-struct pkcs11_provider { +- char *name; ++struct pkcs11_module { ++ char *module_path; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; +@@ -65,6 +65,13 @@ struct pkcs11_provider { + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; ++}; ++ ++struct pkcs11_provider { ++ char *name; ++ struct pkcs11_module *module; /* can be shared between various providers */ ++ int refcount; ++ int valid; + TAILQ_ENTRY(pkcs11_provider) next; + }; + +@@ -75,6 +82,7 @@ struct pkcs11_key { + CK_ULONG slotidx; + char *keyid; + int keyid_len; ++ char *label; + }; + + int pkcs11_interactive = 0; +@@ -106,26 +114,61 @@ pkcs11_init(int interactive) + * this is called when a provider gets unregistered. + */ + static void +-pkcs11_provider_finalize(struct pkcs11_provider *p) ++pkcs11_module_finalize(struct pkcs11_module *m) + { + CK_RV rv; + CK_ULONG i; + +- debug_f("provider \"%s\" refcount %d valid %d", +- p->name, p->refcount, p->valid); +- if (!p->valid) ++ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); ++ if (!m->valid) + return; +- for (i = 0; i < p->nslots; i++) { +- if (p->slotinfo[i].session && +- (rv = p->function_list->C_CloseSession( +- p->slotinfo[i].session)) != CKR_OK) ++ for (i = 0; i < m->nslots; i++) { ++ if (m->slotinfo[i].session && ++ (rv = m->function_list->C_CloseSession( ++ m->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } +- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) ++ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); ++ m->valid = 0; ++ m->function_list = NULL; ++ dlclose(m->handle); ++} ++ ++/* ++ * remove a reference to the pkcs11 module. ++ * called when a provider is unregistered. ++ */ ++static void ++pkcs11_module_unref(struct pkcs11_module *m) ++{ ++ debug_f("%p refcount %d", m, m->refcount); ++ if (--m->refcount <= 0) { ++ pkcs11_module_finalize(m); ++ if (m->valid) ++ error_f("%p still valid", m); ++ free(m->slotlist); ++ free(m->slotinfo); ++ free(m->module_path); ++ free(m); ++ } ++} ++ ++/* ++ * finalize a provider shared library, it's no longer usable. ++ * however, there might still be keys referencing this provider, ++ * so the actual freeing of memory is handled by pkcs11_provider_unref(). ++ * this is called when a provider gets unregistered. ++ */ ++static void ++pkcs11_provider_finalize(struct pkcs11_provider *p) ++{ ++ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); ++ if (!p->valid) ++ return; ++ pkcs11_module_unref(p->module); ++ p->module = NULL; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); + } + + /* +@@ -137,11 +180,9 @@ pkcs11_provider_unref(struct pkcs11_provider *p) + { + debug_f("provider \"%s\" refcount %d", p->name, p->refcount); + if (--p->refcount <= 0) { +- if (p->valid) +- error_f("provider \"%s\" still valid", p->name); + free(p->name); +- free(p->slotlist); +- free(p->slotinfo); ++ if (p->module) ++ pkcs11_module_unref(p->module); + free(p); + } + } +@@ -159,6 +200,20 @@ pkcs11_terminate(void) + } + } + ++/* lookup provider by module path */ ++static struct pkcs11_module * ++pkcs11_provider_lookup_module(char *module_path) ++{ ++ struct pkcs11_provider *p; ++ ++ TAILQ_FOREACH(p, &pkcs11_providers, next) { ++ debug("check %p %s (%s)", p, p->name, p->module->module_path); ++ if (!strcmp(module_path, p->module->module_path)) ++ return (p->module); ++ } ++ return (NULL); ++} ++ + /* lookup provider by name */ + static struct pkcs11_provider * + pkcs11_provider_lookup(char *provider_id) +@@ -173,19 +228,55 @@ pkcs11_provider_lookup(char *provider_id) + return (NULL); + } + ++int pkcs11_del_provider_by_uri(struct pkcs11_uri *); ++ + /* unregister provider by name */ + int + pkcs11_del_provider(char *provider_id) ++{ ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug_f("called, provider_id = %s", provider_id); ++ ++ if (provider_id == NULL) ++ return 0; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_del_provider_by_uri(uri); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++/* unregister provider by PKCS#11 URI */ ++int ++pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) + { + struct pkcs11_provider *p; ++ int rv = -1; ++ char *provider_uri = pkcs11_uri_get(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); + pkcs11_provider_unref(p); +- return (0); ++ rv = 0; + } +- return (-1); ++ free(provider_uri); ++ return rv; + } + + static RSA_METHOD *rsa_method; +@@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; + static int ec_key_idx = 0; + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + ++/* ++ * This can't be in the ssh-pkcs11-uri, becase we can not depend on ++ * PKCS#11 structures in ssh-agent (using client-helper communication) ++ */ ++int ++pkcs11_uri_write(const struct sshkey *key, FILE *f) ++{ ++ char *p = NULL; ++ struct pkcs11_uri uri; ++ struct pkcs11_key *k11; ++ ++ /* sanity - is it a RSA key with associated app_data? */ ++ switch (key->type) { ++ case KEY_RSA: ++ k11 = RSA_get_ex_data(key->rsa, rsa_idx); ++ break; ++#ifdef HAVE_EC_KEY_METHOD_NEW ++ case KEY_ECDSA: ++ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); ++ break; ++#endif ++ default: ++ error("Unknown key type %d", key->type); ++ return -1; ++ } ++ if (k11 == NULL) { ++ error("Failed to get ex_data for key type %d", key->type); ++ return (-1); ++ } ++ ++ /* omit type -- we are looking for private-public or private-certificate pairs */ ++ uri.id = k11->keyid; ++ uri.id_len = k11->keyid_len; ++ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; ++ uri.object = k11->label; ++ 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; ++ ++ p = pkcs11_uri_get(&uri); + /* do not cleanup -- we do not allocate here, only reference */ + if (p == NULL) + return -1; @@ -1598,7 +1899,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 +348,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); @@ -1606,7 +1907,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 +363,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, CK_RV rv; int ret = -1; @@ -1617,7 +1918,7 @@ 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 +@@ -262,12 +403,12 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, else { snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", si->token.label); @@ -1632,7 +1933,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 +438,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, static int pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) { @@ -1649,7 +1950,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 +461,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, *val = 0; @@ -1667,7 +1968,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 +499,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) int always_auth = 0; int did_login = 0; @@ -1685,7 +1986,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 +583,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, return (-1); } @@ -1705,7 +2006,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 +646,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -1718,7 +2019,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 +682,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, return (NULL); } @@ -1738,10 +2039,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 - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - +@@ -615,6 +765,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, + 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); @@ -1751,7 +2052,7 @@ 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 +@@ -651,8 +807,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, CK_SESSION_HANDLE session; int login_required, ret; @@ -1762,7 +2063,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 +@@ -662,9 +818,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -1774,7 +2075,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 * +@@ -700,7 +856,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1782,202 +2083,17 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + CK_ATTRIBUTE key_attr[4]; + int nattr = 4; CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -713,14 +870,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - - memset(&key_attr, 0, sizeof(key_attr)); - key_attr[0].type = CKA_ID; -- key_attr[1].type = CKA_EC_POINT; -- key_attr[2].type = CKA_EC_PARAMS; -+ key_attr[1].type = CKA_LABEL; -+ key_attr[2].type = CKA_EC_POINT; -+ key_attr[3].type = CKA_EC_PARAMS; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -731,19 +889,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - * ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (key_attr[1].ulValueLen == 0 || -- key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || -+ key_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return (NULL); - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (key_attr[i].ulValueLen > 0) - key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - - /* retrieve ID, public point and curve parameters of EC key */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -755,8 +913,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - goto fail; - } - -- attrp = key_attr[2].pValue; -- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); -+ attrp = key_attr[3].pValue; -+ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); - if (group == NULL) { - ossl_error("d2i_ECPKParameters failed"); - goto fail; -@@ -767,13 +925,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - goto fail; - } - -- if (key_attr[1].ulValueLen <= 2) { -+ if (key_attr[2].ulValueLen <= 2) { - error("CKA_EC_POINT too small"); - goto fail; - } - -- attrp = key_attr[1].pValue; -- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); -+ attrp = key_attr[2].pValue; -+ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); - if (octet == NULL) { - ossl_error("d2i_ASN1_OCTET_STRING failed"); - goto fail; -@@ -790,7 +948,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - goto fail; - } - -- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) - goto fail; - - key = sshkey_new(KEY_UNSPEC); -@@ -806,7 +964,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ - ec = NULL; /* now owned by key */ - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - if (ec) - EC_KEY_free(ec); -@@ -823,7 +981,8 @@ static struct sshkey * - pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj) - { -- CK_ATTRIBUTE key_attr[3]; -+ CK_ATTRIBUTE key_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -834,14 +993,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - - memset(&key_attr, 0, sizeof(key_attr)); - key_attr[0].type = CKA_ID; -- key_attr[1].type = CKA_MODULUS; -- key_attr[2].type = CKA_PUBLIC_EXPONENT; -+ key_attr[1].type = CKA_LABEL; -+ key_attr[2].type = CKA_MODULUS; -+ key_attr[3].type = CKA_PUBLIC_EXPONENT; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -852,19 +1012,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - * ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (key_attr[1].ulValueLen == 0 || -- key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || -+ key_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return (NULL); - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (key_attr[i].ulValueLen > 0) - key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - - /* retrieve ID, modulus and public exponent of RSA key */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -876,8 +1036,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - goto fail; - } - -- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); -- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); -+ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); -+ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); - if (rsa_n == NULL || rsa_e == NULL) { - error("BN_bin2bn failed"); - goto fail; -@@ -886,7 +1046,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - fatal_f("set key"); - rsa_n = rsa_e = NULL; /* transferred */ - -- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) - goto fail; - - key = sshkey_new(KEY_UNSPEC); -@@ -901,7 +1061,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr - rsa = NULL; /* now owned by key */ - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - RSA_free(rsa); - -@@ -912,7 +1072,8 @@ static int - pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) - { -- CK_ATTRIBUTE cert_attr[3]; -+ CK_ATTRIBUTE cert_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -936,14 +1097,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - - memset(&cert_attr, 0, sizeof(cert_attr)); - cert_attr[0].type = CKA_ID; -- cert_attr[1].type = CKA_SUBJECT; -- cert_attr[2].type = CKA_VALUE; -+ cert_attr[1].type = CKA_LABEL; -+ cert_attr[2].type = CKA_SUBJECT; -+ cert_attr[3].type = CKA_VALUE; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -714,14 +871,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_EC_POINT; +- key_attr[2].type = CKA_EC_PARAMS; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_EC_POINT; ++ key_attr[3].type = CKA_EC_PARAMS; - session = p->slotinfo[slotidx].session; - f = p->function_list; @@ -1985,1072 +2101,971 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + f = p->module->function_list; /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); - return -1; -@@ -955,18 +1117,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + return (NULL); +@@ -732,19 +890,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ - if (cert_attr[1].ulValueLen == 0 || -- cert_attr[2].ulValueLen == 0) { -+ cert_attr[2].ulValueLen == 0 || -+ cert_attr[3].ulValueLen == 0) { +- if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ if (key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { error("invalid attribute length"); - return -1; + return (NULL); } /* allocate buffers for attributes */ - for (i = 0; i < 3; i++) + for (i = 0; i < nattr; i++) - if (cert_attr[i].ulValueLen > 0) - cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - /* retrieve ID, subject and value of certificate */ -- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + /* retrieve ID, public point and curve parameters of EC key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); - goto out; -@@ -980,8 +1143,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - subject = xstrdup("invalid subject"); - X509_NAME_free(x509_name); - -- cp = cert_attr[2].pValue; -- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { -+ cp = cert_attr[3].pValue; -+ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { - error("d2i_x509 failed"); - goto out; - } -@@ -1001,7 +1164,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - goto out; - } - -- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1031,7 +1194,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - goto out; - } - -- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1051,7 +1214,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p - goto out; - } - out: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(cert_attr[i].pValue); - X509_free(x509); - RSA_free(rsa); -@@ -1102,11 +1265,12 @@ note_key(struct pkcs11_provider *p, CK_U - */ - static int - pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[1]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1123,10 +1287,23 @@ pkcs11_fetch_certs(struct pkcs11_provide - key_attr[0].pValue = &key_class; - key_attr[0].ulValueLen = sizeof(key_class); - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ if (uri->id != NULL) { -+ key_attr[nattr].type = CKA_ID; -+ key_attr[nattr].pValue = uri->id; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ 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); -+ 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: - */ - static int - pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[2]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1227,10 +1405,23 @@ pkcs11_fetch_keys(struct pkcs11_provider - key_attr[0].pValue = &key_class; - key_attr[0].ulValueLen = sizeof(key_class); - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ if (uri->id != NULL) { -+ key_attr[nattr].type = CKA_ID; -+ key_attr[nattr].pValue = uri->id; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ 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, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); +@@ -756,8 +914,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; -@@ -1499,16 +1690,10 @@ pkcs11_ecdsa_generate_private_key(struct - } - #endif /* WITH_PKCS11_KEYGEN */ - --/* -- * register a new provider, fails if provider already exists. if -- * keyp is provided, fetch keys. -- */ - static int --pkcs11_register_provider(char *provider_id, char *pin, -- struct sshkey ***keyp, char ***labelsp, -- struct pkcs11_provider **providerp, CK_ULONG user) -+pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) - { -- int nkeys, need_finalize = 0; -+ int need_finalize = 0; - int ret = -1; - struct pkcs11_provider *p = NULL; - void *handle = NULL; -@@ -1517,164 +1702,298 @@ pkcs11_register_provider(char *provider_ - CK_FUNCTION_LIST *f = NULL; - CK_TOKEN_INFO *token; - CK_ULONG i; -+ char *provider_module = NULL; -+ struct pkcs11_module *m = NULL; + } -- if (providerp == 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"); +- attrp = key_attr[2].pValue; +- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); ++ attrp = key_attr[3].pValue; ++ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); + if (group == NULL) { + ossl_error("d2i_ECPKParameters failed"); goto fail; -- *providerp = NULL; -+#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); -- goto fail; -+ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL -+ && m->valid) { -+ debug_f("provider module already initialized: %s", provider_module); -+ free(provider_module); -+ /* Skip the initialization of PKCS#11 module */ -+ m->refcount++; -+ p->module = m; -+ p->valid = 1; -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; -+ } else { -+ m = xcalloc(1, sizeof(*m)); -+ p->module = m; -+ m->refcount++; - } -+ - /* open shared pkcs11-library */ -- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { -- error("dlopen %s failed: %s", provider_id, dlerror()); -+ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { -+ error("dlopen %s failed: %s", provider_module, dlerror()); +@@ -768,13 +926,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { - error("dlsym(C_GetFunctionList) failed: %s", dlerror()); + +- if (key_attr[1].ulValueLen <= 2) { ++ if (key_attr[2].ulValueLen <= 2) { + error("CKA_EC_POINT too small"); goto fail; } -- 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) { - error("C_GetFunctionList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); + +- attrp = key_attr[1].pValue; +- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); ++ attrp = key_attr[2].pValue; ++ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); + if (octet == NULL) { + ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; - } -- p->function_list = f; -+ m->function_list = f; - if ((rv = f->C_Initialize(NULL)) != CKR_OK) { - error("C_Initialize for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); +@@ -791,7 +949,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } - need_finalize = 1; -- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { -+ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { - 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); + +- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -807,7 +965,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + ec = NULL; /* now owned by key */ + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + if (ec) + EC_KEY_free(ec); +@@ -824,7 +982,8 @@ static struct sshkey * + pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -835,14 +994,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_MODULUS; +- key_attr[2].type = CKA_PUBLIC_EXPONENT; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_MODULUS; ++ key_attr[3].type = CKA_PUBLIC_EXPONENT; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -853,19 +1013,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ if (key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); } -- 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", -- provider_id, -- p->info.manufacturerID, -- p->info.cryptokiVersion.major, -- p->info.cryptokiVersion.minor, -- p->info.libraryDescription, -- p->info.libraryVersion.major, -- p->info.libraryVersion.minor); -- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { -+ provider_module, -+ m->info.manufacturerID, -+ m->info.cryptokiVersion.major, -+ m->info.cryptokiVersion.minor, -+ m->info.libraryDescription, -+ m->info.libraryVersion.major, -+ m->info.libraryVersion.minor); -+ -+ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { - error("C_GetSlotList failed: %lu", rv); + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, modulus and public exponent of RSA key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); goto fail; - } -- if (p->nslots == 0) { -- debug_f("provider %s returned no slots", provider_id); -+ if (m->nslots == 0) { -+ debug_f("provider %s returned no slots", provider_module); - ret = -SSH_PKCS11_ERR_NO_SLOTS; +@@ -877,8 +1037,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } -- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); -- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) -+ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); -+ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) - != CKR_OK) { - error("C_GetSlotList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); + +- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); +- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); + if (rsa_n == NULL || rsa_e == NULL) { + error("BN_bin2bn failed"); goto fail; +@@ -887,7 +1047,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + fatal_f("set key"); + rsa_n = rsa_e = NULL; /* transferred */ + +- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -902,7 +1062,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + rsa = NULL; /* now owned by key */ + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + RSA_free(rsa); + +@@ -913,7 +1073,8 @@ static int + pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) + { +- CK_ATTRIBUTE cert_attr[3]; ++ CK_ATTRIBUTE cert_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -937,14 +1098,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + + memset(&cert_attr, 0, sizeof(cert_attr)); + cert_attr[0].type = CKA_ID; +- cert_attr[1].type = CKA_SUBJECT; +- cert_attr[2].type = CKA_VALUE; ++ cert_attr[1].type = CKA_LABEL; ++ cert_attr[2].type = CKA_SUBJECT; ++ cert_attr[3].type = CKA_VALUE; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return -1; +@@ -956,18 +1118,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * XXX assumes CKA_ID is always first. + */ + if (cert_attr[1].ulValueLen == 0 || +- cert_attr[2].ulValueLen == 0) { ++ cert_attr[2].ulValueLen == 0 || ++ cert_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return -1; } -- p->slotinfo = xcalloc(p->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; -+ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) - != CKR_OK) { - error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (u_long)i, rv); -- continue; -- } -- if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { -- debug2_f("ignoring uninitialised token in " -- "provider %s slot %lu", provider_id, (u_long)i); -+ "failed: %lu", provider_module, (u_long)i, rv); -+ token->flags = 0; - continue; + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (cert_attr[i].ulValueLen > 0) + cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); + + /* retrieve ID, subject and value of certificate */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto out; +@@ -981,8 +1144,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + subject = xstrdup("invalid subject"); + X509_NAME_free(x509_name); + +- cp = cert_attr[2].pValue; +- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { ++ cp = cert_attr[3].pValue; ++ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { + error("d2i_x509 failed"); + goto out; + } +@@ -1002,7 +1165,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; } - rmspace(token->label, sizeof(token->label)); - rmspace(token->manufacturerID, sizeof(token->manufacturerID)); - rmspace(token->model, sizeof(token->model)); - rmspace(token->serialNumber, sizeof(token->serialNumber)); -+ } -+ m->module_path = provider_module; -+ provider_module = NULL; -+ -+ /* insert unconditionally -- remove if there will be no keys later */ -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; -+ -+fail: -+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -+ error("C_Finalize for provider %s failed: %lu", -+ provider_module, rv); -+ free(provider_module); -+ if (m) { -+ free(m->slotlist); -+ free(m); + +- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1032,7 +1195,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1052,7 +1215,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; + } + out: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(cert_attr[i].pValue); + X509_free(x509); + RSA_free(rsa); +@@ -1103,11 +1266,12 @@ note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, + */ + static int + pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[1]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1124,10 +1288,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; + } -+ if (p) { -+ free(p->name); -+ free(p); ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; + } -+ if (handle) -+ dlclose(handle); -+ return ret; -+} -+ -+/* -+ * register a new provider, fails if provider already exists. if -+ * keyp is provided, fetch keys. -+ */ -+static int -+pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, -+ CK_ULONG user) -+{ -+ int nkeys; -+ int ret = -1; -+ struct pkcs11_provider *p = NULL; -+ CK_ULONG i; -+ CK_TOKEN_INFO *token; -+ char *provider_uri = NULL; -+ -+ if (providerp == NULL) -+ goto fail; -+ *providerp = NULL; -+ -+ if (keyp != NULL) -+ *keyp = NULL; + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + -+ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { -+ goto fail; ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1208,11 +1385,12 @@ fail: + */ + static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[2]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1228,10 +1406,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; + } -+ -+ provider_uri = pkcs11_uri_get(uri); -+ if (pin == NULL && uri->pin != NULL) { -+ pin = uri->pin; ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; + } -+ nkeys = 0; -+ for (i = 0; i < p->module->nslots; i++) { -+ token = &p->module->slotinfo[i].token; -+ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { -+ debug2_f("ignoring uninitialised token in " -+ "provider %s slot %lu", provider_uri, (u_long)i); -+ continue; -+ } -+ if (uri->token != NULL && -+ strcmp(token->label, uri->token) != 0) { -+ debug2_f("ignoring token not matching label (%s) " -+ "specified by PKCS#11 URI in slot %lu", -+ token->label, (unsigned long)i); -+ continue; -+ } -+ if (uri->manuf != NULL && -+ strcmp(token->manufacturerID, uri->manuf) != 0) { -+ debug2_f("ignoring token not matching requrested " -+ "manufacturerID (%s) 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, -+ provider_uri, (unsigned long)i, - 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 -+ * retrieve public keys (if keyp is provided) - */ -- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || -+ if ((p->module->slotinfo[i].session != 0 || -+ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ - keyp == NULL) - continue; -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -- if (nkeys == 0 && !p->slotinfo[i].logged_in && -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && - pkcs11_interactive) { - /* - * Some tokens require login before they will - * expose keys. - */ -- if (pkcs11_login_slot(p, &p->slotinfo[i], -+ debug3_f("Trying to login as there were no keys found"); -+ if (pkcs11_login_slot(p, &p->module->slotinfo[i], - CKU_USER) < 0) { - error("login failed"); - continue; - } -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ } -+ if (nkeys == 0 && uri->object != NULL) { -+ debug3_f("No keys found. Retrying without label (%s) ", -+ uri->object); -+ /* Try once more without the label filter */ -+ char *label = uri->object; -+ uri->object = NULL; /* XXX clone uri? */ -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ uri->object = label; - } - } -+ pin = NULL; /* Will be cleaned up with URI */ - - /* now owned by caller */ - *providerp = p; -- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -- p->refcount++; /* add to provider list */ -- -+ free(provider_uri); - return (nkeys); - fail: -- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -- error("C_Finalize for provider %s failed: %lu", -- provider_id, rv); - if (p) { -- free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -- free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); - } -- if (handle) -- dlclose(handle); - if (ret > 0) - ret = -1; - return (ret); +- 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; +@@ -1500,16 +1691,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, } + #endif /* WITH_PKCS11_KEYGEN */ -/* -- * register a new provider and get number of keys hold by the token, -- * fails if provider already exists +- * register a new provider, fails if provider already exists. if +- * keyp is provided, fetch keys. - */ -+static int -+pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, -+ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) -+{ -+ struct pkcs11_uri *uri = NULL; -+ int r; -+ -+ debug_f("called, provider_id = %s", provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); -+ pkcs11_uri_cleanup(uri); -+ -+ return r; -+} -+ - int --pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, -- char ***labelsp) -+pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp) + static int +-pkcs11_register_provider(char *provider_id, char *pin, +- struct sshkey ***keyp, char ***labelsp, +- struct pkcs11_provider **providerp, CK_ULONG user) ++pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) { +- int nkeys, need_finalize = 0; ++ int need_finalize = 0; + int ret = -1; struct pkcs11_provider *p = NULL; - int nkeys; -+ char *provider_uri = pkcs11_uri_get(uri); -+ -+ debug_f("called, provider_uri = %s", provider_uri); - -- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, -- &p, CKU_USER); -+ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); - - /* 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 - pkcs11_provider_unref(p); - } - if (nkeys == 0) -- debug_f("provider %s returned no keys", provider_id); -+ debug_f("provider %s returned no keys", provider_uri); -+ -+ free(provider_uri); -+ return nkeys; -+} -+ -+/* -+ * register a new provider and get number of keys hold by the token, -+ * fails if provider already exists -+ */ -+int -+pkcs11_add_provider(char *provider_id, char *pin, -+ struct sshkey ***keyp, char ***labelsp) -+{ -+ struct pkcs11_uri *uri; -+ int nkeys; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); + void *handle = NULL; +@@ -1518,164 +1703,298 @@ pkcs11_register_provider(char *provider_id, char *pin, + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; +- +- if (providerp == NULL) ++ char *provider_module = NULL; ++ struct pkcs11_module *m = NULL; + -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); ++ /* 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; +- +- if (keyp != NULL) +- *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; ++#endif + } else { -+ uri->module_path = strdup(provider_id); ++ provider_module = strdup(uri->module_path); + } -+ -+ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); -+ pkcs11_uri_cleanup(uri); - - 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 -@@ -22,10 +22,14 @@ - #define SSH_PKCS11_ERR_PIN_REQUIRED 4 - #define SSH_PKCS11_ERR_PIN_LOCKED 5 -+#include "ssh-pkcs11-uri.h" -+ - int pkcs11_init(int); - void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); -+int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); - int pkcs11_del_provider(char *); -+int pkcs11_uri_write(const struct sshkey *, FILE *); - #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 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include "includes.h" -+ -+#ifdef ENABLE_PKCS11 -+ -+#include -+#include -+ -+#include "sshkey.h" -+#include "sshbuf.h" -+#include "log.h" -+ -+#define CRYPTOKI_COMPAT -+#include "pkcs11.h" -+ -+#include "ssh-pkcs11-uri.h" -+ -+#define PKCS11_URI_PATH_SEPARATOR ";" -+#define PKCS11_URI_QUERY_SEPARATOR "&" -+#define PKCS11_URI_VALUE_SEPARATOR "=" -+#define PKCS11_URI_ID "id" -+#define PKCS11_URI_TOKEN "token" -+#define PKCS11_URI_OBJECT "object" -+#define PKCS11_URI_LIB_MANUF "library-manufacturer" -+#define PKCS11_URI_MANUF "manufacturer" -+#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 -+} pkcs11uriOpCodes; -+ -+/* Textual representation of the tokens. */ -+static struct { -+ const char *name; -+ pkcs11uriOpCodes opcode; -+} keywords[] = { -+ { PKCS11_URI_ID, pId }, -+ { PKCS11_URI_TOKEN, pToken }, -+ { PKCS11_URI_OBJECT, pObject }, -+ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, -+ { PKCS11_URI_MANUF, pManufacturer }, -+ { PKCS11_URI_MODULE_PATH, pModulePath }, -+ { PKCS11_URI_PIN_VALUE, pPinValue }, -+ { NULL, pBadOption } -+}; -+ -+static pkcs11uriOpCodes -+parse_token(const char *cp) -+{ -+ u_int i; -+ -+ for (i = 0; keywords[i].name; i++) -+ if (strncasecmp(cp, keywords[i].name, -+ strlen(keywords[i].name)) == 0) -+ return keywords[i].opcode; +- if (pkcs11_provider_lookup(provider_id) != NULL) { +- debug_f("provider already registered: %s", provider_id); +- goto fail; ++ p = xcalloc(1, sizeof(*p)); ++ p->name = pkcs11_uri_get(uri); + -+ return pBadOption; -+} ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ debug_f("provider module already initialized: %s", provider_module); ++ free(provider_module); ++ /* Skip the initialization of PKCS#11 module */ ++ m->refcount++; ++ p->module = m; ++ p->valid = 1; ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ } else { ++ m = xcalloc(1, sizeof(*m)); ++ p->module = m; ++ m->refcount++; + } + -+int -+percent_decode(char *data, char **outp) -+{ -+ char tmp[3]; -+ char *out, *tmp_end; -+ char *p = data; -+ long value; -+ size_t outlen = 0; + /* open shared pkcs11-library */ +- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { +- error("dlopen %s failed: %s", provider_id, dlerror()); ++ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { ++ error("dlopen %s failed: %s", provider_module, dlerror()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { + error("dlsym(C_GetFunctionList) failed: %s", dlerror()); + goto fail; + } +- p = xcalloc(1, sizeof(*p)); +- p->name = xstrdup(provider_id); +- p->handle = handle; + -+ out = malloc(strlen(data)+1); /* upper bound */ -+ if (out == NULL) -+ return -1; -+ while (*p != '\0') { -+ switch (*p) { -+ case '%': -+ p++; -+ if (*p == '\0') -+ goto fail; -+ tmp[0] = *p++; -+ if (*p == '\0') -+ goto fail; -+ tmp[1] = *p++; -+ tmp[2] = '\0'; -+ tmp_end = NULL; -+ value = strtol(tmp, &tmp_end, 16); -+ if (tmp_end != tmp+2) -+ goto fail; -+ else -+ out[outlen++] = (char) value; -+ break; -+ default: -+ out[outlen++] = *p++; -+ break; -+ } ++ p->module->handle = handle; + /* setup the pkcs11 callbacks */ + if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { + error("C_GetFunctionList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->function_list = f; ++ m->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } + need_finalize = 1; +- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { ++ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { + 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", +- provider_id, +- p->info.manufacturerID, +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- p->info.libraryDescription, +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ m->info.cryptokiVersion.minor, ++ m->info.libraryDescription, ++ m->info.libraryVersion.major, ++ m->info.libraryVersion.minor); + -+ /* zero terminate */ -+ out[outlen] = '\0'; -+ *outp = out; -+ return outlen; -+fail: -+ free(out); -+ return -1; -+} ++ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } +- if (p->nslots == 0) { +- debug_f("provider %s returned no slots", provider_id); ++ if (m->nslots == 0) { ++ debug_f("provider %s returned no slots", provider_module); + ret = -SSH_PKCS11_ERR_NO_SLOTS; + goto fail; + } +- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); +- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) ++ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); ++ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) + != CKR_OK) { + error("C_GetSlotList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->slotinfo = xcalloc(p->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; ++ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo for provider %s slot %lu " +- "failed: %lu", provider_id, (u_long)i, rv); +- continue; +- } +- if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { +- debug2_f("ignoring uninitialised token in " +- "provider %s slot %lu", provider_id, (u_long)i); ++ "failed: %lu", provider_module, (u_long)i, rv); ++ 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)); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; + -+struct sshbuf * -+percent_encode(const char *data, size_t length, const char *allow_list) -+{ -+ struct sshbuf *b = NULL; -+ char tmp[4], *cp; -+ size_t i; ++ /* insert unconditionally -- remove if there will be no keys later */ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; + -+ if ((b = sshbuf_new()) == NULL) -+ return NULL; -+ for (i = 0; i < length; i++) { -+ cp = strchr(allow_list, data[i]); -+ /* if c is specified as '\0' pointer to terminator is returned !! */ -+ if (cp != NULL && *cp != '\0') { -+ if (sshbuf_put(b, &data[i], 1) != 0) -+ goto err; -+ } else -+ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 -+ || sshbuf_put(b, tmp, 3) != 0) -+ goto err; ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", ++ provider_module, rv); ++ free(provider_module); ++ if (m) { ++ free(m->slotlist); ++ free(m); + } -+ if (sshbuf_put(b, "\0", 1) == 0) -+ return b; -+err: -+ sshbuf_free(b); -+ return NULL; ++ if (p) { ++ free(p->name); ++ free(p); ++ } ++ if (handle) ++ dlclose(handle); ++ return ret; +} + -+char * -+pkcs11_uri_append(char *part, const char *separator, const char *key, -+ struct sshbuf *value) ++/* ++ * register a new provider, fails if provider already exists. if ++ * keyp is provided, fetch keys. ++ */ ++static int ++pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, ++ CK_ULONG user) +{ -+ char *new_part; -+ size_t size = 0; ++ int nkeys; ++ int ret = -1; ++ struct pkcs11_provider *p = NULL; ++ CK_ULONG i; ++ CK_TOKEN_INFO *token; ++ char *provider_uri = NULL; + -+ if (value == NULL) -+ return NULL; ++ if (providerp == NULL) ++ goto fail; ++ *providerp = NULL; + -+ size = asprintf(&new_part, -+ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", -+ (part != NULL ? part : ""), -+ (part != NULL ? separator : ""), -+ key, sshbuf_ptr(value)); -+ sshbuf_free(value); -+ free(part); ++ if (keyp != NULL) ++ *keyp = NULL; + -+ if (size <= 0) -+ return NULL; -+ return new_part; -+} ++ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { ++ goto fail; ++ } + -+char * -+pkcs11_uri_get(struct pkcs11_uri *uri) ++ provider_uri = pkcs11_uri_get(uri); ++ if (pin == NULL && uri->pin != NULL) { ++ pin = uri->pin; ++ } ++ nkeys = 0; ++ for (i = 0; i < p->module->nslots; i++) { ++ token = &p->module->slotinfo[i].token; ++ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { ++ debug2_f("ignoring uninitialised token in " ++ "provider %s slot %lu", provider_uri, (u_long)i); ++ continue; ++ } ++ if (uri->token != NULL && ++ strcmp(token->label, uri->token) != 0) { ++ debug2_f("ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "manufacturerID (%s) 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, ++ provider_uri, (unsigned long)i, + 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 ++ * retrieve public keys (if keyp is provided) + */ +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || ++ if ((p->module->slotinfo[i].session != 0 || ++ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ + keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +- if (nkeys == 0 && !p->slotinfo[i].logged_in && ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], ++ debug3_f("Trying to login as there were no keys found"); ++ if (pkcs11_login_slot(p, &p->module->slotinfo[i], + CKU_USER) < 0) { + error("login failed"); + continue; + } +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ } ++ if (nkeys == 0 && uri->object != NULL) { ++ debug3_f("No keys found. Retrying without label (%s) ", ++ uri->object); ++ /* Try once more without the label filter */ ++ char *label = uri->object; ++ uri->object = NULL; /* XXX clone uri? */ ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ uri->object = label; + } + } ++ pin = NULL; /* Will be cleaned up with URI */ + + /* now owned by caller */ + *providerp = p; + +- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); +- p->refcount++; /* add to provider list */ +- ++ free(provider_uri); + return (nkeys); + fail: +- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->name); +- free(p->slotlist); +- free(p->slotinfo); +- free(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); + } +- if (handle) +- dlclose(handle); + if (ret > 0) + ret = -1; + return (ret); + } + +-/* +- * register a new provider and get number of keys hold by the token, +- * fails if provider already exists +- */ ++static int ++pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, ++ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) +{ -+ size_t size = 0; -+ char *p = NULL, *path = NULL, *query = NULL; -+ -+ /* compose a percent-encoded ID */ -+ if (uri->id_len > 0) { -+ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_ID, key_id); -+ if (path == NULL) -+ goto err; -+ } ++ struct pkcs11_uri *uri = NULL; ++ int r; + -+ /* Write object label */ -+ if (uri->object) { -+ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), -+ PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_OBJECT, label); -+ if (path == NULL) -+ goto err; -+ } ++ debug_f("called, provider_id = %s", provider_id); + -+ /* Write token label */ -+ if (uri->token) { -+ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), -+ PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_TOKEN, label); -+ if (path == NULL) -+ goto err; -+ } ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("failed to init PKCS#11 URI"); + -+ /* Write manufacturer */ -+ if (uri->manuf) { -+ struct sshbuf *manuf = percent_encode(uri->manuf, -+ strlen(uri->manuf), PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_MANUF, manuf); -+ if (path == NULL) -+ goto err; ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); + } + -+ /* Write module_path */ -+ if (uri->module_path) { -+ struct sshbuf *module = percent_encode(uri->module_path, -+ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); -+ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, -+ PKCS11_URI_MODULE_PATH, module); -+ if (query == NULL) -+ goto err; -+ } ++ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); ++ pkcs11_uri_cleanup(uri); + -+ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", -+ path != NULL ? path : "", -+ query != NULL ? "?" : "", -+ query != NULL ? query : ""); -+err: -+ free(query); -+ free(path); -+ if (size <= 0) -+ return NULL; -+ return p; ++ return r; +} + -+struct pkcs11_uri * -+pkcs11_uri_init() -+{ -+ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); -+ return d; -+} + int +-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, +- char ***labelsp) ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp) + { + struct pkcs11_provider *p = NULL; + int nkeys; ++ char *provider_uri = pkcs11_uri_get(uri); + +- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, +- &p, CKU_USER); ++ debug_f("called, provider_uri = %s", provider_uri); + -+void -+pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) -+{ -+ if (pkcs11 == NULL) { -+ return; -+ } ++ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); + + /* no keys found or some other error, de-register provider */ + if (nkeys <= 0 && p != NULL) { +@@ -1684,7 +2003,37 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, + pkcs11_provider_unref(p); + } + if (nkeys == 0) +- debug_f("provider %s returned no keys", provider_id); ++ debug_f("provider %s returned no keys", provider_uri); + -+ free(pkcs11->id); -+ free(pkcs11->module_path); -+ free(pkcs11->token); -+ free(pkcs11->object); -+ free(pkcs11->lib_manuf); -+ free(pkcs11->manuf); -+ if (pkcs11->pin) -+ freezero(pkcs11->pin, strlen(pkcs11->pin)); -+ free(pkcs11); ++ free(provider_uri); ++ return nkeys; +} + ++/* ++ * register a new provider and get number of keys hold by the token, ++ * fails if provider already exists ++ */ +int -+pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) ++pkcs11_add_provider(char *provider_id, char *pin, ++ struct sshkey ***keyp, char ***labelsp) +{ -+ char *saveptr1, *saveptr2, *str1, *str2, *tok; -+ int rv = 0, len; -+ char *p = NULL; -+ -+ size_t scheme_len = strlen(PKCS11_URI_SCHEME); -+ if (strlen(uri) < scheme_len || /* empty URI matches everything */ -+ strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { -+ error_f("The '%s' does not look like PKCS#11 URI", uri); -+ return -1; -+ } -+ -+ if (pkcs11 == NULL) { -+ error_f("Bad arguments. The pkcs11 can't be null"); -+ return -1; -+ } -+ -+ /* skip URI schema name */ -+ p = strdup(uri); -+ str1 = p; -+ -+ /* everything before ? */ -+ tok = strtok_r(str1, "?", &saveptr1); -+ if (tok == NULL) { -+ error_f("pk11-path expected, got EOF"); -+ rv = -1; -+ goto out; -+ } -+ -+ /* skip URI schema name: -+ * the scheme ensures that there is at least something before "?" -+ * allowing empty pk11-path. Resulting token at worst pointing to -+ * \0 byte */ -+ tok = tok + scheme_len; -+ -+ /* parse pk11-path */ -+ for (str2 = tok; ; str2 = NULL) { -+ char **charptr, *arg = NULL; -+ pkcs11uriOpCodes opcode; -+ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); -+ if (tok == NULL) -+ break; -+ opcode = parse_token(tok); -+ if (opcode != pBadOption) -+ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ -+ -+ switch (opcode) { -+ case pId: -+ /* CKA_ID */ -+ if (pkcs11->id != NULL) { -+ verbose_f("The id already set in the PKCS#11 URI"); -+ rv = -1; -+ goto out; -+ } -+ len = percent_decode(arg, &pkcs11->id); -+ if (len <= 0) { -+ verbose_f("Failed to percent-decode CKA_ID: %s", arg); -+ rv = -1; -+ goto out; -+ } else -+ pkcs11->id_len = len; -+ debug3_f("Setting CKA_ID = %s from PKCS#11 URI", arg); -+ break; -+ case pToken: -+ /* CK_TOKEN_INFO -> label */ -+ charptr = &pkcs11->token; -+ parse_string: -+ if (*charptr != NULL) { -+ verbose_f("The %s already set in the PKCS#11 URI", -+ keywords[opcode].name); -+ rv = -1; -+ goto out; -+ } -+ percent_decode(arg, charptr); -+ debug3_f("Setting %s = %s from PKCS#11 URI", -+ keywords[opcode].name, *charptr); -+ break; -+ -+ case pObject: -+ /* CK_TOKEN_INFO -> manufacturerID */ -+ charptr = &pkcs11->object; -+ goto parse_string; -+ -+ case pManufacturer: -+ /* CK_TOKEN_INFO -> manufacturerID */ -+ charptr = &pkcs11->manuf; -+ goto parse_string; ++ struct pkcs11_uri *uri; ++ int nkeys; + -+ case pLibraryManufacturer: -+ /* CK_INFO -> manufacturerID */ -+ charptr = &pkcs11->lib_manuf; -+ goto parse_string; ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); + -+ default: -+ /* Unrecognized attribute in the URI path SHOULD be error */ -+ verbose_f("Unknown part of path in PKCS#11 URI: %s", tok); -+ } ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); + } + -+ tok = strtok_r(NULL, "?", &saveptr1); -+ if (tok == NULL) { -+ goto out; -+ } -+ /* parse pk11-query (optional) */ -+ for (str2 = tok; ; str2 = NULL) { -+ char *arg; -+ pkcs11uriOpCodes opcode; -+ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); -+ if (tok == NULL) -+ break; -+ opcode = parse_token(tok); -+ if (opcode != pBadOption) -+ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ ++ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); ++ pkcs11_uri_cleanup(uri); + + return (nkeys); + } +diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h +index 81f1d7c..feaf74d 100644 +--- a/ssh-pkcs11.h ++++ b/ssh-pkcs11.h +@@ -22,10 +22,14 @@ + #define SSH_PKCS11_ERR_PIN_REQUIRED 4 + #define SSH_PKCS11_ERR_PIN_LOCKED 5 + ++#include "ssh-pkcs11-uri.h" + -+ switch (opcode) { -+ case pModulePath: -+ /* module-path is PKCS11Provider */ -+ if (pkcs11->module_path != NULL) { -+ verbose_f("Multiple module-path attributes are" -+ "not supported the PKCS#11 URI"); -+ rv = -1; -+ goto out; + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); + int pkcs11_del_provider(char *); ++int pkcs11_uri_write(const struct sshkey *, FILE *); + #ifdef WITH_PKCS11_KEYGEN + struct sshkey * + pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, +diff --git a/ssh.c b/ssh.c +index 244b7f3..fff421a 100644 +--- a/ssh.c ++++ b/ssh.c +@@ -835,6 +835,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#ifdef ENABLE_PKCS11 ++ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(optarg, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ add_identity_file(&options, NULL, optarg, 1); ++ break; + } -+ percent_decode(arg, &pkcs11->module_path); -+ debug3_f("Setting PKCS11Provider = %s from PKCS#11 URI", -+ pkcs11->module_path); -+ break; ++#endif + p = tilde_expand_filename(optarg, getuid()); + if (stat(p, &st) == -1) + fprintf(stderr, "Warning: Identity file %s " +@@ -1699,6 +1707,7 @@ main(int ac, char **av) + #ifdef ENABLE_PKCS11 + (void)pkcs11_del_provider(options.pkcs11_provider); + #endif ++ pkcs11_terminate(); + + skip_connect: + exit_status = ssh_session2(ssh, cinfo); +@@ -2215,6 +2224,45 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) + options.escape_char : SSH_ESCAPECHAR_NONE, id); + } + ++#ifdef ENABLE_PKCS11 ++static void ++load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], ++ struct sshkey *identity_keys[], int *n_ids) ++{ ++ int nkeys, i; ++ struct sshkey **keys; ++ struct pkcs11_uri *uri; + -+ case pPinValue: -+ /* pin-value */ -+ if (pkcs11->pin != NULL) { -+ verbose_f("Multiple pin-value attributes are" -+ "not supported the PKCS#11 URI"); -+ rv = -1; -+ goto out; -+ } -+ percent_decode(arg, &pkcs11->pin); -+ debug3_f("Setting PIN from PKCS#11 URI"); -+ break; ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); + -+ default: -+ /* Unrecognized attribute in the URI query SHOULD be ignored */ -+ verbose_f("Unknown part of query in PKCS#11 URI: %s", tok); ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { ++ for (i = 0; i < nkeys; i++) { ++ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { ++ sshkey_free(keys[i]); ++ continue; ++ } ++ identity_keys[*n_ids] = keys[i]; ++ identity_files[*n_ids] = pkcs11_uri_get(uri); ++ (*n_ids)++; + } ++ free(keys); + } -+out: -+ free(p); -+ return rv; -+} + ++ pkcs11_uri_cleanup(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 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ + -+#define PKCS11_URI_SCHEME "pkcs11:" -+#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ -+ "0123456789_-.()" + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2229,11 +2277,6 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; +-#ifdef ENABLE_PKCS11 +- struct sshkey **keys = NULL; +- char **comments = NULL; +- int nkeys; +-#endif /* PKCS11 */ + + n_ids = n_certs = 0; + memset(identity_files, 0, sizeof(identity_files)); +@@ -2246,33 +2289,46 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) + sizeof(certificate_file_userprovided)); + + #ifdef ENABLE_PKCS11 +- if (options.pkcs11_provider != NULL && +- options.num_identity_files < SSH_MAX_IDENTITY_FILES && +- (pkcs11_init(!options.batch_mode) == 0) && +- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, +- &keys, &comments)) > 0) { +- for (i = 0; i < nkeys; i++) { +- if (n_ids >= SSH_MAX_IDENTITY_FILES) { +- sshkey_free(keys[i]); +- free(comments[i]); +- continue; +- } +- identity_keys[n_ids] = keys[i]; +- identity_files[n_ids] = comments[i]; /* transferred */ +- n_ids++; +- } +- free(keys); +- free(comments); ++ /* handle fallback from PKCS11Provider option */ ++ pkcs11_init(!options.batch_mode); + -+struct pkcs11_uri { -+ /* path */ -+ char *id; -+ size_t id_len; -+ char *token; -+ char *object; -+ char *lib_manuf; -+ char *manuf; -+ /* query */ -+ char *module_path; -+ char *pin; /* Only parsed, but not printed */ -+}; ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; + -+struct pkcs11_uri *pkcs11_uri_init(); -+void pkcs11_uri_cleanup(struct pkcs11_uri *); -+int pkcs11_uri_parse(const char *, struct pkcs11_uri *); -+struct pkcs11_uri *pkcs11_uri_init(); -+char *pkcs11_uri_get(struct pkcs11_uri *uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); + ++ pkcs11_uri_cleanup(uri); + } + #endif /* ENABLE_PKCS11 */ + for (i = 0; i < options.num_identity_files; i++) { ++ char *name = options.identity_files[i]; + if (n_ids >= SSH_MAX_IDENTITY_FILES || +- strcasecmp(options.identity_files[i], "none") == 0) { ++ strcasecmp(name, "none") == 0) { + free(options.identity_files[i]); + options.identity_files[i] = NULL; + continue; + } +- cp = tilde_expand_filename(options.identity_files[i], getuid()); ++#ifdef ENABLE_PKCS11 ++ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(name, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ load_pkcs11_identity(name, identity_files, ++ identity_keys, &n_ids); ++ free(options.identity_files[i]); ++ continue; ++ } ++#endif /* ENABLE_PKCS11 */ ++ cp = tilde_expand_filename(name, getuid()); + filename = default_client_percent_dollar_expand(cp, cinfo); + free(cp); + check_load(sshkey_load_public(filename, &public, NULL), +diff --git a/ssh_config.5 b/ssh_config.5 +index 0a6c4a6..4bacaf9 100644 +--- a/ssh_config.5 ++++ b/ssh_config.5 +@@ -1114,6 +1114,21 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.Pp ++The authentication identity can be also specified in a form of PKCS#11 URI ++starting with a string ++.Cm pkcs11: . ++There is supported a subset of the PKCS#11 URI as defined ++in RFC 7512 (implemented path arguments ++.Cm id , ++.Cm manufacturer , ++.Cm object , ++.Cm token ++and query arguments ++.Cm module-path ++and ++.Cm pin-value ++). The URI can not be in quotes. + .It Cm IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they are + encountered in configuration parsing. +-- +2.27.0 + diff --git a/openssh-8.8p1.tar.gz b/openssh-8.8p1.tar.gz deleted file mode 100644 index 85ba061dad5479b066f6e2164edc600f8aa0f6dd..0000000000000000000000000000000000000000 Binary files a/openssh-8.8p1.tar.gz and /dev/null differ diff --git a/openssh-8.8p1.tar.gz.asc b/openssh-8.8p1.tar.gz.asc deleted file mode 100644 index 9a1fd8e67da5cdb68c5401e903465b223a06b067..0000000000000000000000000000000000000000 --- a/openssh-8.8p1.tar.gz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmFQfp8ACgkQKj9BTnNg -YLq2SQ/8C3iOHTkyqX82FYt0SKkybebe9b2iBPr91HQOUmx+U3I+vgrSWArXabWJ -uSu0b685RQKlcr7UjEtPk6g0cm45NoJFjju9ljvnOFfZw73V3a5qX15Lx4xRnkRx -v1LJn6Yh12PKLWL4/A1qPQnfAObVwq/BF0BR01FfXLAOt5+lFwYvg79HpE+69b0r -KtcIEpsyTEn2lSKSWD7q4lpe6Z/iR+XzBKfnB6JJXhKyHiDV63hlAJk9Pt3mIvS6 -tnE9/7GDawvi+Tsl018kw3wsf6aHVSQ+O+vzcDgfy0vDJVGjD6Ec9it9FvikXJh6 -3pSTBYuUJdt+CAQYvmEui73v4nrkfouHXsxqgzEDZaTwIZC4wPrvNYxUaIyirWlc -l4/YSnxSxSiYbvPa5eYRBvXvoWbnQXjPOkuhjETxz/KTcHirQpWE9eldi0jHcKUa -FVu9YqMPAjIUd1Jj4vC5bgH7v5cLeEMm/AetMvKsJs+rhY9NZaKpiqOqU2m6Geb+ -sQSXHNTeA8uOlrHim4SmYHtmfglVbH5lIroiUqtRzjbOhMhqUb+yN9+aAxe0bwmN -VcFMSThlbmYokb9bkQryY2I/FfXb997vxgF6v15Z8d9e8HH2zc2Irj1HYXG4Bf3o -WCiSvd8+Tr/FxS2Gn8qj/vgSPWXT0d0Hy4zHW9JeT/jn3RtIYhU= -=EnoG ------END PGP SIGNATURE----- diff --git a/openssh-9.1p1.tar.gz b/openssh-9.1p1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a8c5b89bb1a721a0563ae7379490d3f40010390f Binary files /dev/null and b/openssh-9.1p1.tar.gz differ diff --git a/openssh-9.1p1.tar.gz.asc b/openssh-9.1p1.tar.gz.asc new file mode 100644 index 0000000000000000000000000000000000000000..0237718e410b6eb49e3dba898b89e13fd9093894 --- /dev/null +++ b/openssh-9.1p1.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmM6+qUACgkQKj9BTnNg +YLqLSxAAi+hmachTcy9O2GNbCq4uPFlFqQ8hjZ697nhNvkIJtrtc2WSIg17ImN4E +3ucWQLEqbytwsj67J1UFC4NyOmGo2mfsZ3BEDsgkkd0Tp2YO7UhkrVzTD0l0Wl7/ +qe0biPaYOLFptL+88wC3OdamNkWgHAtSYBizgHK4k2uEtLYsEXuC+0nnfqykL2vq +UEB3MZ7C00JYmBVHFfMjtmGmt+Z3ahv5LSzFsj//c6hwkhdJHtv/V4UlCIVrrMdG +XyTumREl+y5zuP5oGxsRU/LZNo7ncXYDUg2qE/FpR4o8giF9d1fm/aHuAmr+g03E +Ev3uUcrgA+Kq95bbv7ubtO2JxFnuzUmJkUy6SNIcE1o4naxGejxlEw7nvtvf7auV +BPqomw1yOWyQzbhXtD18OiSi1IJMXyDCei9HcsO+oM3aq8YQc9Bsed7UPhA36e6b +GjuAIOPtee+JqxDj3psN39G+y4YUcxSPqC4gKL8cKfImbP2DlSoHPmZ1fDf/pKPj +hWdNiA+a+KzsXR2fjBWMeUIkSvx2BYZC9NKFS/zN4X86jEdyOJtQJ4WQcIvekLIA +Z/yP6UrzM+2jYYqix4PBocP1utEakFDYfLPJu0G2pK9meU4dz6EzNUT7J3daF2h7 +eaibQUZ0+wg+sI+MPys3INcqcKwv/5OVDl6wi7g2iNOdOII49VM= +=xfW+ +-----END PGP SIGNATURE----- diff --git a/openssh.spec b/openssh.spec index 0c4716edcbb6cf403272e10ebb814664f1177c54..97fe576b245ae17cbd58b283ffb88151a2e6af67 100644 --- a/openssh.spec +++ b/openssh.spec @@ -6,10 +6,10 @@ %{?no_gtk2:%global gtk2 0} %global sshd_uid 74 -%global openssh_release 17 +%global openssh_release 1 Name: openssh -Version: 8.8p1 +Version: 9.1p1 Release: %{openssh_release} URL: http://www.openssh.com/portable.html License: BSD @@ -18,19 +18,19 @@ Summary: An open source implementation of SSH protocol version 2 Source0: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz Source1: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc Source2: sshd.pam -Source4: http://prdownloads.sourceforge.net/pamsshagentauth/pam_ssh_agent_auth/pam_ssh_agent_auth-0.10.4.tar.gz -Source5: pam_ssh_agent-rmheaders -Source6: ssh-keycat.pam -Source7: sshd.sysconfig -Source9: sshd@.service -Source10: sshd.socket -Source11: sshd.service -Source12: sshd-keygen@.service -Source13: sshd-keygen -Source14: sshd.tmpfiles -Source15: sshd-keygen.target -Source16: ssh-agent.service -Source17: ssh-keygen-bash-completion.sh +Source3: http://prdownloads.sourceforge.net/pamsshagentauth/pam_ssh_agent_auth/pam_ssh_agent_auth-0.10.4.tar.gz +Source4: pam_ssh_agent-rmheaders +Source5: ssh-keycat.pam +Source6: sshd.sysconfig +Source7: sshd@.service +Source8: sshd.socket +Source9: sshd.service +Source10: sshd-keygen@.service +Source11: sshd-keygen +Source12: sshd.tmpfiles +Source13: sshd-keygen.target +Source14: ssh-agent.service +Source15: ssh-keygen-bash-completion.sh Patch0: openssh-6.7p1-coverity.patch Patch1: openssh-7.6p1-audit.patch Patch2: openssh-7.1p2-audit-race-condition.patch @@ -48,12 +48,10 @@ Patch14: openssh-6.6p1-keyperm.patch Patch15: openssh-5.9p1-ipv6man.patch Patch16: openssh-5.8p2-sigpipe.patch Patch17: openssh-7.2p2-x11.patch -Patch18: openssh-7.7p1-fips.patch Patch19: openssh-5.1p1-askpass-progress.patch Patch20: openssh-4.3p2-askpass-grab-info.patch Patch21: openssh-7.7p1.patch Patch22: openssh-7.8p1-UsePAM-warning.patch -Patch23: openssh-6.3p1-ctr-evp-fast.patch Patch26: openssh-8.0p1-gssapi-keyex.patch Patch27: openssh-6.6p1-force_krb.patch Patch28: openssh-6.6p1-GSSAPIEnablek5users.patch @@ -82,31 +80,16 @@ Patch51: openssh-8.0p1-keygen-strip-doseol.patch Patch52: openssh-8.0p1-preserve-pam-errors.patch Patch53: openssh-8.7p1-scp-kill-switch.patch Patch54: bugfix-sftp-when-parse_user_host_path-empty-path-should-be-allowed.patch -Patch55: bugfix-openssh-6.6p1-log-usepam-no.patch Patch56: bugfix-openssh-add-option-check-username-splash.patch Patch57: feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch Patch58: bugfix-openssh-fix-sftpserver.patch Patch59: set-sshd-config.patch Patch60: feature-add-SMx-support.patch -Patch61: backport-upstream-a-little-extra-debugging.patch -Patch62: backport-upstream-better-debugging-for-connect_next.patch Patch63: add-loongarch.patch -Patch64: backport-upstream-ssh-keygen-Y-check-novalidate-requires-name.patch Patch65: openssh-Add-sw64-architecture.patch -Patch66: backport-upstream-if-sshpkt-functions-fail-then-password-is-n.patch -Patch67: backport-upstream-Make-sure-not-to-fclose-the-same-fd-twice-i.patch -Patch68: backport-upstream-Donot-attempt-to-fprintf-a-null-identity-co.patch -Patch69: backport-upstream-ignore-SIGPIPE-earlier-in-main-specifically.patch -Patch70: backport-upstream-Always-return-allocated-strings-from-the-ke.patch -Patch71: backport-Don-t-leak-the-strings-allocated-by-order_h.patch -Patch72: backport-Return-ERANGE-from-getcwd-if-buffer-size-is-1.patch -Patch73: backport-upstream-double-free-in-error-path-from-Eusgor-via-G.patch Patch74: add-strict-scp-check-for-CVE-2020-15778.patch -Patch75: backport-upstream-avoid-integer-overflow-of-auth-attempts-har.patch -Patch76: backport-Skip-scp3-test-if-there-s-no-scp-on-remote-path.patch Patch77: skip-scp-test-if-there-is-no-scp-on-remote-path-as-s.patch Patch78: skip-tests-for-C-if-there-is-no-openssl-on-local-pat.patch -Patch79: backport-fix-possible-NULL-deref-when-built-without-FIDO.patch Requires: /sbin/nologin Requires: libselinux >= 2.3-5 audit-libs >= 1.0.8 @@ -180,7 +163,7 @@ instance. The module is most useful for su and sudo service stacks. %package_help %prep -%setup -q -a 4 +%setup -q -a 3 pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 %patch3 -p2 -b .psaa-build @@ -190,14 +173,13 @@ pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 %patch6 -p2 -b .psaa-agent %patch8 -p2 -b .psaa-deref # Remove duplicate headers and library files -rm -f $(cat %{SOURCE5}) +rm -f $(cat %{SOURCE4}) popd %patch9 -p1 -b .role-mls %patch10 -p1 -b .privsep-selinux %patch12 -p1 -b .keycat %patch13 -p1 -b .ip-opts -%patch14 -p1 -b .keyperm %patch15 -p1 -b .ipv6man %patch16 -p1 -b .sigpipe %patch17 -p1 -b .x11 @@ -205,7 +187,6 @@ popd %patch20 -p1 -b .grab-info %patch21 -p1 %patch22 -p1 -b .log-usepam-no -%patch23 -p1 -b .evp-ctr %patch26 -p1 -b .gsskex %patch27 -p1 -b .force_krb %patch29 -p1 -b .ccache_name @@ -235,35 +216,18 @@ popd %patch53 -p1 -b .kill-scp %patch1 -p1 -b .audit %patch2 -p1 -b .audit-race -%patch18 -p1 -b .fips %patch0 -p1 -b .coverity - %patch54 -p1 -%patch55 -p1 %patch56 -p1 %patch57 -p1 %patch58 -p1 %patch59 -p1 %patch60 -p1 -%patch61 -p1 -%patch62 -p1 %patch63 -p1 -%patch64 -p1 %patch65 -p1 -%patch66 -p1 -%patch67 -p1 -%patch68 -p1 -%patch69 -p1 -%patch70 -p1 -%patch71 -p1 -%patch72 -p1 -%patch73 -p1 %patch74 -p1 -%patch75 -p1 -%patch76 -p1 %patch77 -p1 %patch78 -p1 -%patch79 -p1 autoreconf pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 @@ -350,23 +314,23 @@ install -d $RPM_BUILD_ROOT/etc/pam.d/ install -d $RPM_BUILD_ROOT/etc/sysconfig/ install -d $RPM_BUILD_ROOT%{_libexecdir}/openssh install -m644 %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/sshd -install -m644 %{SOURCE6} $RPM_BUILD_ROOT/etc/pam.d/ssh-keycat -install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/sysconfig/sshd +install -m644 %{SOURCE5} $RPM_BUILD_ROOT/etc/pam.d/ssh-keycat +install -m644 %{SOURCE6} $RPM_BUILD_ROOT/etc/sysconfig/sshd install -m644 ssh_config_redhat $RPM_BUILD_ROOT/etc/ssh/ssh_config.d/05-redhat.conf install -d -m755 $RPM_BUILD_ROOT/%{_unitdir} -install -m644 %{SOURCE9} $RPM_BUILD_ROOT/%{_unitdir}/sshd@.service -install -m644 %{SOURCE10} $RPM_BUILD_ROOT/%{_unitdir}/sshd.socket -install -m644 %{SOURCE11} $RPM_BUILD_ROOT/%{_unitdir}/sshd.service -install -m644 %{SOURCE12} $RPM_BUILD_ROOT/%{_unitdir}/sshd-keygen@.service -install -m644 %{SOURCE15} $RPM_BUILD_ROOT/%{_unitdir}/sshd-keygen.target +install -m644 %{SOURCE7} $RPM_BUILD_ROOT/%{_unitdir}/sshd@.service +install -m644 %{SOURCE8} $RPM_BUILD_ROOT/%{_unitdir}/sshd.socket +install -m644 %{SOURCE9} $RPM_BUILD_ROOT/%{_unitdir}/sshd.service +install -m644 %{SOURCE10} $RPM_BUILD_ROOT/%{_unitdir}/sshd-keygen@.service +install -m644 %{SOURCE13} $RPM_BUILD_ROOT/%{_unitdir}/sshd-keygen.target install -d -m755 $RPM_BUILD_ROOT/%{_userunitdir} -install -m644 %{SOURCE16} $RPM_BUILD_ROOT/%{_userunitdir}/ssh-agent.service -install -m744 %{SOURCE13} $RPM_BUILD_ROOT/%{_libexecdir}/openssh/sshd-keygen +install -m644 %{SOURCE14} $RPM_BUILD_ROOT/%{_userunitdir}/ssh-agent.service +install -m744 %{SOURCE11} $RPM_BUILD_ROOT/%{_libexecdir}/openssh/sshd-keygen install -m755 contrib/ssh-copy-id $RPM_BUILD_ROOT%{_bindir}/ install contrib/ssh-copy-id.1 $RPM_BUILD_ROOT%{_mandir}/man1/ -install -m644 -D %{SOURCE14} $RPM_BUILD_ROOT%{_tmpfilesdir}/%{name}.conf +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 %{SOURCE17} $RPM_BUILD_ROOT/etc/bash_completion.d/ssh-keygen-bash-completion.sh +install -m644 %{SOURCE15} $RPM_BUILD_ROOT/etc/bash_completion.d/ssh-keygen-bash-completion.sh ln -s gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass install -m 755 -d $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ @@ -462,6 +426,12 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_mandir}/man8/sftp-server.8* %changelog +* Mon Jan 30 2023 renmingshuai - 9.1p1-1 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:update to openssh-9.1p1 + * Mon Jan 9 2023 renmingshuai - 8.8p1-17 - Type:bugfix - CVE:NA