diff --git a/0006-openssh-5.8p2-sigpipe.patch b/0006-openssh-5.8p2-sigpipe.patch deleted file mode 100644 index 5bf31bc..0000000 --- a/0006-openssh-5.8p2-sigpipe.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 80359feb76fd8061b5ce18f73451d7b9db0c2477 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 06/50] openssh-5.8p2-sigpipe - ---- - ssh-keyscan.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/ssh-keyscan.c b/ssh-keyscan.c -index 3436c0b5..9f76ad22 100644 ---- a/ssh-keyscan.c -+++ b/ssh-keyscan.c -@@ -798,6 +798,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 = xcalloc(maxfd, sizeof(struct pollfd)); - for (j = 0; j < maxfd; j++) - read_wait[j].fd = -1; --- -2.49.0 - diff --git a/0017-openssh-6.4p1-fromto-remote.patch b/0017-openssh-6.4p1-fromto-remote.patch deleted file mode 100644 index 5e8309d..0000000 --- a/0017-openssh-6.4p1-fromto-remote.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 20aabb2c445e29d211266ce7434bb0273edf88b9 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 17/50] openssh-6.4p1-fromto-remote - ---- - scp.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/scp.c b/scp.c -index 57c242ff..716ae386 100644 ---- a/scp.c -+++ b/scp.c -@@ -1162,7 +1162,10 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) - addargs(&alist, "%s", ssh_program); - addargs(&alist, "-x"); - addargs(&alist, "-oClearAllForwardings=yes"); -- addargs(&alist, "-n"); -+ if (isatty(fileno(stdin))) -+ addargs(&alist, "-t"); -+ else -+ addargs(&alist, "-n"); - for (j = 0; j < remote_remote_args.num; j++) { - addargs(&alist, "%s", - remote_remote_args.list[j]); --- -2.49.0 - diff --git a/0020-openssh-6.6.1p1-scp-non-existing-directory.patch b/0020-openssh-6.6.1p1-scp-non-existing-directory.patch deleted file mode 100644 index 94c43ef..0000000 --- a/0020-openssh-6.6.1p1-scp-non-existing-directory.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 007ee98fa9100f7241985ac2a7eed71e17d89a9f Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 20/50] openssh-6.6.1p1-scp-non-existing-directory - ---- - scp.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/scp.c b/scp.c -index 716ae386..9554b188 100644 ---- a/scp.c -+++ b/scp.c -@@ -1876,6 +1876,10 @@ sink(int argc, char **argv, const char *src) - free(vect[0]); - continue; - } -+ if (buf[0] == 'C' && ! exists && np[strlen(np)-1] == '/') { -+ errno = ENOTDIR; -+ goto bad; -+ } - omode = mode; - mode |= S_IWUSR; - if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { --- -2.49.0 - diff --git a/0022-openssh-6.8p1-sshdT-output.patch b/0022-openssh-6.8p1-sshdT-output.patch deleted file mode 100644 index 4e4766e..0000000 --- a/0022-openssh-6.8p1-sshdT-output.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 05b09904f431333e19cd24528ef66d1fd15e9efe Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 22/50] openssh-6.8p1-sshdT-output - ---- - servconf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/servconf.c b/servconf.c -index c0de7110..105e301d 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -3366,7 +3366,7 @@ dump_config(ServerOptions *o) - dump_cfg_string(sXAuthLocation, o->xauth_location); - dump_cfg_string(sCiphers, o->ciphers); - dump_cfg_string(sMacs, o->macs); -- dump_cfg_string(sBanner, o->banner); -+ dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none"); - dump_cfg_string(sForceCommand, o->adm_forced_command); - dump_cfg_string(sChrootDirectory, o->chroot_directory); - dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); --- -2.49.0 - diff --git a/0027-openssh-7.5p1-sandbox.patch b/0027-openssh-7.5p1-sandbox.patch deleted file mode 100644 index 435d029..0000000 --- a/0027-openssh-7.5p1-sandbox.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 35205319dd71d8e61c1596b8f9479df91aff7756 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 27/50] openssh-7.5p1-sandbox - ---- - sandbox-seccomp-filter.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index b31062c2..1fabf99d 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -277,6 +277,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_exit_group - SC_ALLOW(__NR_exit_group), - #endif -+#if defined(__NR_flock) && defined(__s390__) -+ SC_ALLOW(__NR_flock), -+#endif - #ifdef __NR_futex - SC_FUTEX(__NR_futex), - #endif -@@ -295,6 +298,21 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_getpid - SC_ALLOW(__NR_getpid), - #endif -+#ifdef __NR_getuid -+ SC_ALLOW(__NR_getuid), -+#endif -+#ifdef __NR_getuid32 -+ SC_ALLOW(__NR_getuid32), -+#endif -+#ifdef __NR_geteuid -+ SC_ALLOW(__NR_geteuid), -+#endif -+#ifdef __NR_geteuid32 -+ SC_ALLOW(__NR_geteuid32), -+#endif -+#ifdef __NR_gettid -+ SC_ALLOW(__NR_gettid), -+#endif - #ifdef __NR_getrandom - SC_ALLOW(__NR_getrandom), - #endif -@@ -304,6 +322,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_gettimeofday - SC_ALLOW(__NR_gettimeofday), - #endif -+#if defined(__NR_ipc) && defined(__s390__) -+ SC_ALLOW(__NR_ipc), -+#endif - #ifdef __NR_getuid - SC_ALLOW(__NR_getuid), - #endif --- -2.49.0 - diff --git a/0038-openssh-8.7p1-ibmca.patch b/0038-openssh-8.7p1-ibmca.patch deleted file mode 100644 index 74dd5b5..0000000 --- a/0038-openssh-8.7p1-ibmca.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 26af04432f6404eb03780265a5cce948ecfec8dc Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 38/50] openssh-8.7p1-ibmca - ---- - openbsd-compat/bsd-closefrom.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c -index f6112458..417c2048 100644 ---- a/openbsd-compat/bsd-closefrom.c -+++ b/openbsd-compat/bsd-closefrom.c -@@ -16,7 +16,7 @@ - - #include "includes.h" - --#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) -+#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__) - - #include - #include --- -2.49.0 - diff --git a/0043-openssh-8.7p1-ssh-manpage.patch b/0043-openssh-8.7p1-ssh-manpage.patch deleted file mode 100644 index 89c6ea1..0000000 --- a/0043-openssh-8.7p1-ssh-manpage.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 299a602802d7c7d121306eb2aeae1502871a35cb Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 43/50] openssh-8.7p1-ssh-manpage - ---- - ssh.1 | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/ssh.1 b/ssh.1 -index 6a9fbdc5..755cdef2 100644 ---- a/ssh.1 -+++ b/ssh.1 -@@ -510,12 +510,12 @@ For full details of the options listed below, and their possible values, see - .It BatchMode - .It BindAddress - .It BindInterface --.It CASignatureAlgorithms - .It CanonicalDomains - .It CanonicalizeFallbackLocal - .It CanonicalizeHostname - .It CanonicalizeMaxDots - .It CanonicalizePermittedCNAMEs -+.It CASignatureAlgorithms - .It CertificateFile - .It ChannelTimeout - .It CheckHostIP -@@ -528,6 +528,7 @@ For full details of the options listed below, and their possible values, see - .It ControlPath - .It ControlPersist - .It DynamicForward -+.It EnableSSHKeysign - .It EnableEscapeCommandline - .It EnableSSHKeysign - .It EscapeChar -@@ -588,6 +589,8 @@ For full details of the options listed below, and their possible values, see - .It RemoteCommand - .It RemoteForward - .It RequestTTY -+.It RevokedHostKeys -+.It SecurityKeyProvider - .It RequiredRSASize - .It RevokedHostKeys - .It SecurityKeyProvider --- -2.49.0 - diff --git a/0047-openssh-9.6p1-pam-rhost.patch b/0047-openssh-9.6p1-pam-rhost.patch deleted file mode 100644 index 968e60a..0000000 --- a/0047-openssh-9.6p1-pam-rhost.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 497de886faaddec60b7ad1013396c7d4f3145968 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 47/50] openssh-9.6p1-pam-rhost - ---- - auth-pam.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/auth-pam.c b/auth-pam.c -index a042c3c8..a321e0d3 100644 ---- a/auth-pam.c -+++ b/auth-pam.c -@@ -741,7 +741,7 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt) - sshpam_laddr = get_local_ipaddr( - ssh_packet_get_connection_in(ssh)); - } -- if (sshpam_rhost != NULL) { -+ if (sshpam_rhost != NULL && strcmp(sshpam_rhost, "UNKNOWN") != 0) { - debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); - sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, - sshpam_rhost); --- -2.49.0 - diff --git a/0048-openssh-9.9p1-separate-keysign.patch b/0048-openssh-9.9p1-separate-keysign.patch deleted file mode 100644 index 8d0f691..0000000 --- a/0048-openssh-9.9p1-separate-keysign.patch +++ /dev/null @@ -1,25 +0,0 @@ -From b97b1040bc0918fe9be89cdb482d046270e92d9c Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 48/50] openssh-9.9p1-separate-keysign - ---- - ssh_config.5 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ssh_config.5 b/ssh_config.5 -index a43b2a27..9d5da2a6 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -797,7 +797,7 @@ or - This option should be placed in the non-hostspecific section. - See - .Xr ssh-keysign 8 --for more information. -+for more information. ssh-keysign should be installed explicitly. - .It Cm EscapeChar - Sets the escape character (default: - .Ql ~ ) . --- -2.49.0 - diff --git a/0049-openssh-9.9p1-openssl-mlkem.patch b/0049-openssh-9.9p1-openssl-mlkem.patch deleted file mode 100644 index e04d194..0000000 --- a/0049-openssh-9.9p1-openssl-mlkem.patch +++ /dev/null @@ -1,398 +0,0 @@ -From 0a621a2ccb8444e4c6da906b0e112e0522658122 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 49/50] openssh-9.9p1-openssl-mlkem - ---- - kex-names.c | 20 +++ - kexmlkem768x25519.c | 291 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 311 insertions(+) - -diff --git a/kex-names.c b/kex-names.c -index cd3902ad..36a953ab 100644 ---- a/kex-names.c -+++ b/kex-names.c -@@ -108,6 +108,19 @@ static const struct kexalg gss_kexalgs[] = { - { NULL, 0, -1, -1}, - }; - -+static int is_mlkem768_available() -+{ -+ static int is_fetched = -1; -+ -+ if (is_fetched == -1) { -+ EVP_KEM *mlkem768 = EVP_KEM_fetch(NULL, "mlkem768", NULL); -+ is_fetched = mlkem768 != NULL ? 1 : 0; -+ EVP_KEM_free(mlkem768); -+ } -+ -+ return is_fetched; -+} -+ - static char * - kex_alg_list_internal(char sep, const struct kexalg *algs) - { -@@ -116,6 +129,9 @@ kex_alg_list_internal(char sep, const struct kexalg *algs) - const struct kexalg *k; - - for (k = algs; k->name != NULL; k++) { -+ if (strcmp(k->name, KEX_MLKEM768X25519_SHA256) == 0 -+ && !is_mlkem768_available()) -+ continue; - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(k->name); -@@ -147,6 +163,10 @@ kex_alg_by_name(const char *name) - { - const struct kexalg *k; - -+ if (strcmp(name, KEX_MLKEM768X25519_SHA256) == 0 -+ && !is_mlkem768_available()) -+ return NULL; -+ - for (k = kexalgs; k->name != NULL; k++) { - if (strcmp(k->name, name) == 0) - return k; -diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c -index 2b5d3960..670049dc 100644 ---- a/kexmlkem768x25519.c -+++ b/kexmlkem768x25519.c -@@ -48,10 +48,127 @@ - #ifdef USE_MLKEM768X25519 - - #include "libcrux_mlkem768_sha3.h" -+#include -+#include -+#include -+ -+static int -+mlkem768_keypair_gen(unsigned char *pubkeybuf, unsigned char *privkeybuf) -+{ -+ EVP_PKEY_CTX *ctx = NULL; -+ EVP_PKEY *pkey = NULL; -+ int ret = SSH_ERR_INTERNAL_ERROR; -+ size_t pubkey_size = crypto_kem_mlkem768_PUBLICKEYBYTES, privkey_size = crypto_kem_mlkem768_SECRETKEYBYTES; -+ -+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "mlkem768", NULL); -+ if (ctx == NULL) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto err; -+ } -+ -+ if (EVP_PKEY_keygen_init(ctx) <= 0 -+ || EVP_PKEY_keygen(ctx, &pkey) <= 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto err; -+ } -+ -+ if (EVP_PKEY_get_raw_public_key(pkey, pubkeybuf, &pubkey_size) <= 0 -+ || EVP_PKEY_get_raw_private_key(pkey, privkeybuf, &privkey_size) <= 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto err; -+ } -+ -+ if (privkey_size != crypto_kem_mlkem768_SECRETKEYBYTES -+ || pubkey_size != crypto_kem_mlkem768_PUBLICKEYBYTES) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto err; -+ } -+ ret = 0; -+ -+ err: -+ EVP_PKEY_free(pkey); -+ EVP_PKEY_CTX_free(ctx); -+ if (ret == SSH_ERR_LIBCRYPTO_ERROR) -+ ERR_print_errors_fp(stderr); -+ return ret; -+} -+ -+static int -+mlkem768_encap_secret(const u_char *pubkeybuf, u_char *secret, u_char *out) -+{ -+ EVP_PKEY *pkey = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ int r = SSH_ERR_INTERNAL_ERROR; -+ size_t outlen = crypto_kem_mlkem768_CIPHERTEXTBYTES, -+ secretlen = crypto_kem_mlkem768_BYTES; -+ -+ pkey = EVP_PKEY_new_raw_public_key_ex(NULL, "mlkem768", NULL, -+ pubkeybuf, crypto_kem_mlkem768_PUBLICKEYBYTES); -+ if (pkey == NULL) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto err; -+ } -+ -+ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); -+ if (ctx == NULL -+ || EVP_PKEY_encapsulate_init(ctx, NULL) <= 0 -+ || EVP_PKEY_encapsulate(ctx, out, &outlen, secret, &secretlen) <= 0 -+ || secretlen != crypto_kem_mlkem768_BYTES -+ || outlen != crypto_kem_mlkem768_CIPHERTEXTBYTES) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto err; -+ } -+ r = 0; -+ -+ err: -+ EVP_PKEY_free(pkey); -+ EVP_PKEY_CTX_free(ctx); -+ if (r == SSH_ERR_LIBCRYPTO_ERROR) -+ ERR_print_errors_fp(stderr); -+ -+ return r; -+} -+ -+static int -+mlkem768_decap_secret(const u_char *privkeybuf, const u_char *wrapped, u_char *secret) -+{ -+ EVP_PKEY *pkey = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ int r = SSH_ERR_INTERNAL_ERROR; -+ size_t wrappedlen = crypto_kem_mlkem768_CIPHERTEXTBYTES, -+ secretlen = crypto_kem_mlkem768_BYTES; -+ -+ pkey = EVP_PKEY_new_raw_private_key_ex(NULL, "mlkem768", NULL, -+ privkeybuf, crypto_kem_mlkem768_SECRETKEYBYTES); -+ if (pkey == NULL) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto err; -+ } -+ -+ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); -+ if (ctx == NULL -+ || EVP_PKEY_decapsulate_init(ctx, NULL) <= 0 -+ || EVP_PKEY_decapsulate(ctx, secret, &secretlen, wrapped, wrappedlen) <= 0 -+ || secretlen != crypto_kem_mlkem768_BYTES) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto err; -+ } -+ r = 0; -+ -+ err: -+ EVP_PKEY_free(pkey); -+ EVP_PKEY_CTX_free(ctx); -+ -+ if (r == SSH_ERR_LIBCRYPTO_ERROR) -+ ERR_print_errors_fp(stderr); -+ -+ return r; -+} - - int - kex_kem_mlkem768x25519_keypair(struct kex *kex) - { -+#if 0 - struct sshbuf *buf = NULL; - u_char rnd[LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN], *cp = NULL; - size_t need; -@@ -86,6 +203,36 @@ kex_kem_mlkem768x25519_keypair(struct kex *kex) - explicit_bzero(rnd, sizeof(rnd)); - sshbuf_free(buf); - return r; -+#else -+ struct sshbuf *buf = NULL; -+ u_char *cp = NULL; -+ size_t need; -+ int r = SSH_ERR_INTERNAL_ERROR; -+ -+ if ((buf = sshbuf_new()) == NULL) -+ return SSH_ERR_ALLOC_FAIL; -+ need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE; -+ if ((r = sshbuf_reserve(buf, need, &cp)) != 0) -+ goto out; -+ if ((r = mlkem768_keypair_gen(cp, kex->mlkem768_client_key)) != 0) -+ goto out; -+#ifdef DEBUG_KEXECDH -+ dump_digest("client public key mlkem768:", cp, -+ crypto_kem_mlkem768_PUBLICKEYBYTES); -+#endif -+ cp += crypto_kem_mlkem768_PUBLICKEYBYTES; -+ kexc25519_keygen(kex->c25519_client_key, cp); -+#ifdef DEBUG_KEXECDH -+ dump_digest("client public key c25519:", cp, CURVE25519_SIZE); -+#endif -+ /* success */ -+ r = 0; -+ kex->client_pub = buf; -+ buf = NULL; -+ out: -+ sshbuf_free(buf); -+ return r; -+#endif - } - - int -@@ -93,6 +240,7 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, - const struct sshbuf *client_blob, struct sshbuf **server_blobp, - struct sshbuf **shared_secretp) - { -+#if 0 - struct sshbuf *server_blob = NULL; - struct sshbuf *buf = NULL; - const u_char *client_pub; -@@ -185,12 +333,97 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, - sshbuf_free(server_blob); - sshbuf_free(buf); - return r; -+#else -+ struct sshbuf *server_blob = NULL; -+ struct sshbuf *buf = NULL; -+ const u_char *client_pub; -+ u_char server_pub[CURVE25519_SIZE], server_key[CURVE25519_SIZE]; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ size_t need; -+ int r = SSH_ERR_INTERNAL_ERROR; -+ struct libcrux_mlkem768_enc_result enc; /* FIXME */ -+ -+ *server_blobp = NULL; -+ *shared_secretp = NULL; -+ -+ /* client_blob contains both KEM and ECDH client pubkeys */ -+ need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE; -+ if (sshbuf_len(client_blob) != need) { -+ r = SSH_ERR_SIGNATURE_INVALID; -+ goto out; -+ } -+ client_pub = sshbuf_ptr(client_blob); -+#ifdef DEBUG_KEXECDH -+ dump_digest("client public key mlkem768:", client_pub, -+ crypto_kem_mlkem768_PUBLICKEYBYTES); -+ dump_digest("client public key 25519:", -+ client_pub + crypto_kem_mlkem768_PUBLICKEYBYTES, -+ CURVE25519_SIZE); -+#endif -+ -+ /* allocate buffer for concatenation of KEM key and ECDH shared key */ -+ /* the buffer will be hashed and the result is the shared secret */ -+ if ((buf = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ /* allocate space for encrypted KEM key and ECDH pub key */ -+ if ((server_blob = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if (mlkem768_encap_secret(client_pub, enc.snd, enc.fst.value) != 0) -+ goto out; -+ -+ /* generate ECDH key pair, store server pubkey after ciphertext */ -+ kexc25519_keygen(server_key, server_pub); -+ if ((r = sshbuf_put(buf, enc.snd, sizeof(enc.snd))) != 0 || -+ (r = sshbuf_put(server_blob, enc.fst.value, sizeof(enc.fst.value))) != 0 || -+ (r = sshbuf_put(server_blob, server_pub, sizeof(server_pub))) != 0) -+ goto out; -+ /* append ECDH shared key */ -+ client_pub += crypto_kem_mlkem768_PUBLICKEYBYTES; -+ if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 1)) < 0) -+ goto out; -+ if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0) -+ goto out; -+#ifdef DEBUG_KEXECDH -+ dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE); -+ dump_digest("server cipher text:", -+ enc.fst.value, sizeof(enc.fst.value)); -+ dump_digest("server kem key:", enc.snd, sizeof(enc.snd)); -+ dump_digest("concatenation of KEM key and ECDH shared key:", -+ sshbuf_ptr(buf), sshbuf_len(buf)); -+#endif -+ /* string-encoded hash is resulting shared secret */ -+ sshbuf_reset(buf); -+ if ((r = sshbuf_put_string(buf, hash, -+ ssh_digest_bytes(kex->hash_alg))) != 0) -+ goto out; -+#ifdef DEBUG_KEXECDH -+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf)); -+#endif -+ /* success */ -+ r = 0; -+ *server_blobp = server_blob; -+ *shared_secretp = buf; -+ server_blob = NULL; -+ buf = NULL; -+ out: -+ explicit_bzero(hash, sizeof(hash)); -+ explicit_bzero(server_key, sizeof(server_key)); -+ explicit_bzero(&enc, sizeof(enc)); -+ sshbuf_free(server_blob); -+ sshbuf_free(buf); -+ return r; -+#endif - } - - int - kex_kem_mlkem768x25519_dec(struct kex *kex, - const struct sshbuf *server_blob, struct sshbuf **shared_secretp) - { -+#if 0 - struct sshbuf *buf = NULL; - u_char mlkem_key[crypto_kem_mlkem768_BYTES]; - const u_char *ciphertext, *server_pub; -@@ -258,6 +491,64 @@ kex_kem_mlkem768x25519_dec(struct kex *kex, - explicit_bzero(mlkem_key, sizeof(mlkem_key)); - sshbuf_free(buf); - return r; -+#else -+ struct sshbuf *buf = NULL; -+ const u_char *ciphertext, *server_pub; -+ u_char hash[SSH_DIGEST_MAX_LENGTH]; -+ u_char decap[crypto_kem_mlkem768_BYTES]; -+ size_t need; -+ int r; -+ -+ *shared_secretp = NULL; -+ -+ need = crypto_kem_mlkem768_CIPHERTEXTBYTES + CURVE25519_SIZE; -+ if (sshbuf_len(server_blob) != need) { -+ r = SSH_ERR_SIGNATURE_INVALID; -+ goto out; -+ } -+ ciphertext = sshbuf_ptr(server_blob); -+ server_pub = ciphertext + crypto_kem_mlkem768_CIPHERTEXTBYTES; -+ /* hash concatenation of KEM key and ECDH shared key */ -+ if ((buf = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+#ifdef DEBUG_KEXECDH -+ dump_digest("server cipher text:", ciphertext, crypto_kem_mlkem768_CIPHERTEXTBYTES); -+ dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE); -+#endif -+ if ((r = mlkem768_decap_secret(kex->mlkem768_client_key, ciphertext, decap)) != 0) -+ goto out; -+ if ((r = sshbuf_put(buf, decap, sizeof(decap))) != 0) -+ goto out; -+ if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub, -+ buf, 1)) < 0) -+ goto out; -+ if ((r = ssh_digest_buffer(kex->hash_alg, buf, -+ hash, sizeof(hash))) != 0) -+ goto out; -+#ifdef DEBUG_KEXECDH -+ dump_digest("client kem key:", decap, sizeof(decap)); -+ dump_digest("concatenation of KEM key and ECDH shared key:", -+ sshbuf_ptr(buf), sshbuf_len(buf)); -+#endif -+ sshbuf_reset(buf); -+ if ((r = sshbuf_put_string(buf, hash, -+ ssh_digest_bytes(kex->hash_alg))) != 0) -+ goto out; -+#ifdef DEBUG_KEXECDH -+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf)); -+#endif -+ /* success */ -+ r = 0; -+ *shared_secretp = buf; -+ buf = NULL; -+ out: -+ explicit_bzero(hash, sizeof(hash)); -+ explicit_bzero(decap, sizeof(decap)); -+ sshbuf_free(buf); -+ return r; -+#endif - } - #else /* USE_MLKEM768X25519 */ - int --- -2.49.0 - diff --git a/0050-openssh-9.9p2-error_processing.patch b/0050-openssh-9.9p2-error_processing.patch deleted file mode 100644 index aed1c30..0000000 --- a/0050-openssh-9.9p2-error_processing.patch +++ /dev/null @@ -1,25 +0,0 @@ -From fd32e753ae7f3b314712e6aa8b2bed3c1fca1ef5 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Fri, 16 May 2025 14:53:54 +0200 -Subject: [PATCH 50/51] openssh-9.9p2-error_processing - ---- - ssh-agent.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/ssh-agent.c b/ssh-agent.c -index 798bf9b6..dfb6ac72 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -1377,6 +1377,8 @@ process_add_identity(SocketEntry *e) - if ((r = sshkey_private_deserialize(e->request, &k)) != 0 || - k == NULL || - (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { -+ if (!r) /* k == NULL */ -+ r = SSH_ERR_INTERNAL_ERROR; - error_fr(r, "parse"); - goto out; - } --- -2.49.0 - diff --git a/0051-Provide-better-error-for-non-supported-private-keys.patch b/0051-Provide-better-error-for-non-supported-private-keys.patch deleted file mode 100644 index 9c1aa4d..0000000 --- a/0051-Provide-better-error-for-non-supported-private-keys.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 4965cdbc1ee1e6a0c665797bb8b944d96d3d411f Mon Sep 17 00:00:00 2001 -From: Zoltan Fridrich -Date: Wed, 16 Apr 2025 15:11:59 +0200 -Subject: [PATCH 51/53] Provide better error for non-supported private keys - -Signed-off-by: Zoltan Fridrich ---- - sshkey.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/sshkey.c b/sshkey.c -index ca1cdb642..aada474e0 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -3582,6 +3582,9 @@ translate_libcrypto_error(unsigned long pem_err) - return SSH_ERR_LIBCRYPTO_ERROR; - } - case ERR_LIB_ASN1: -+#ifdef ERR_LIB_OSSL_DECODER -+ case ERR_LIB_OSSL_DECODER: -+#endif - return SSH_ERR_INVALID_FORMAT; - } - return SSH_ERR_LIBCRYPTO_ERROR; --- -2.49.0 - diff --git a/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch b/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch deleted file mode 100644 index f071225..0000000 --- a/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 9ed09ef158a113e21be7b3fefa7c5f932632749b Mon Sep 17 00:00:00 2001 -From: Zoltan Fridrich -Date: Mon, 5 May 2025 11:52:25 +0200 -Subject: [PATCH 52/53] Ignore bad hostkeys in known_hosts file - -Signed-off-by: Zoltan Fridrich ---- - hostfile.c | 15 +++++++++++++++ - hostfile.h | 1 + - ssh.c | 2 ++ - 3 files changed, 18 insertions(+) - -diff --git a/hostfile.c b/hostfile.c -index c5669c703..5c402f501 100644 ---- a/hostfile.c -+++ b/hostfile.c -@@ -63,6 +63,14 @@ - #include "hmac.h" - #include "sshbuf.h" - -+static int required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; -+ -+void -+hostfile_set_minimum_rsa_size(int size) -+{ -+ required_rsa_size = size; -+} -+ - /* XXX hmac is too easy to dictionary attack; use bcrypt? */ - - static int -@@ -233,6 +241,7 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx) - struct load_callback_ctx *ctx = (struct load_callback_ctx *)_ctx; - struct hostkeys *hostkeys = ctx->hostkeys; - struct hostkey_entry *tmp; -+ int r = 0; - - if (l->status == HKF_STATUS_INVALID) { - /* XXX make this verbose() in the future */ -@@ -241,6 +250,12 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx) - return 0; - } - -+ if ((r = sshkey_check_rsa_length(l->key, required_rsa_size)) != 0) { -+ debug2_f("%s:%ld: ignoring hostkey: %s", -+ l->path, l->linenum, ssh_err(r)); -+ return 0; -+ } -+ - debug3_f("found %skey type %s in file %s:%lu", - l->marker == MRK_NONE ? "" : - (l->marker == MRK_CA ? "ca " : "revoked "), -diff --git a/hostfile.h b/hostfile.h -index a24a4e329..0e9b1a19a 100644 ---- a/hostfile.h -+++ b/hostfile.h -@@ -119,5 +119,6 @@ int hostkeys_foreach_file(const char *path, FILE *f, - const char *host, const char *ip, u_int options, u_int note); - - void hostfile_create_user_ssh_dir(const char *, int); -+void hostfile_set_minimum_rsa_size(int); - - #endif -diff --git a/ssh.c b/ssh.c -index abc8b8439..33787a8d4 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -110,6 +110,7 @@ - #include "ssherr.h" - #include "myproposal.h" - #include "utf8.h" -+#include "hostfile.h" - - #ifdef ENABLE_PKCS11 - #include "ssh-pkcs11.h" -@@ -1397,6 +1398,7 @@ main(int ac, char **av) - options.update_hostkeys = 0; - } - } -+ hostfile_set_minimum_rsa_size(options.required_rsa_size); - if (options.connection_attempts <= 0) - fatal("Invalid number of ConnectionAttempts"); - --- -2.49.0 - diff --git a/0053-support-authentication-indicators-in-GSSAPI.patch b/0053-support-authentication-indicators-in-GSSAPI.patch deleted file mode 100644 index 237e45d..0000000 --- a/0053-support-authentication-indicators-in-GSSAPI.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 5d5a66e96ad03132f65371070f4fa475f10207d9 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Mon, 10 Jun 2024 23:00:03 +0300 -Subject: [PATCH] support authentication indicators in GSSAPI - -RFC 6680 defines a set of GSSAPI extensions to handle attributes -associated with the GSSAPI names. MIT Kerberos and FreeIPA use -name attributes to add information about pre-authentication methods used -to acquire the initial Kerberos ticket. The attribute 'auth-indicators' -may contain list of strings that KDC has associated with the ticket -issuance process. - -Use authentication indicators to authorise or deny access to SSH server. -GSSAPIIndicators setting allows to specify a list of possible indicators -that a Kerberos ticket presented must or must not contain. More details -on the syntax are provided in sshd_config(5) man page. - -Fixes: https://bugzilla.mindrot.org/show_bug.cgi?id=2696 - -Signed-off-by: Alexander Bokovoy ---- - configure.ac | 1 + - gss-serv-krb5.c | 64 +++++++++++++++++++++++++++--- - gss-serv.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++- - servconf.c | 15 ++++++- - servconf.h | 2 + - ssh-gss.h | 7 ++++ - sshd_config.5 | 44 +++++++++++++++++++++ - 7 files changed, 228 insertions(+), 8 deletions(-) - -diff --git a/configure.ac b/configure.ac -index d92a85809..2cbe20bf3 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -5004,6 +5004,7 @@ AC_ARG_WITH([kerberos5], - AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h]) - AC_CHECK_HEADERS([gssapi_krb5.h gssapi/gssapi_krb5.h]) - AC_CHECK_HEADERS([gssapi_generic.h gssapi/gssapi_generic.h]) -+ AC_CHECK_HEADERS([gssapi_ext.h gssapi/gssapi_ext.h]) - - AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1], - [Define this if you want to use libkafs' AFS support])]) -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 03188d9b3..2c786ef14 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -43,6 +43,7 @@ - #include "log.h" - #include "misc.h" - #include "servconf.h" -+#include "match.h" - - #include "ssh-gss.h" - -@@ -87,6 +88,32 @@ ssh_gssapi_krb5_init(void) - return 1; - } - -+/* Check if any of the indicators in the Kerberos ticket match -+ * one of indicators in the list of allowed/denied rules. -+ * In case of the match, apply the decision from the rule. -+ * In case of no indicator from the ticket matching the rule, deny -+ */ -+ -+static int -+ssh_gssapi_check_indicators(ssh_gssapi_client *client, int *matched) -+{ -+ int ret; -+ u_int i; -+ -+ /* Check indicators */ -+ for (i = 0; client->indicators[i] != NULL; i++) { -+ ret = match_pattern_list(client->indicators[i], -+ options.gss_indicators, 1); -+ /* negative or positive match */ -+ if (ret != 0) { -+ *matched = i; -+ return ret; -+ } -+ } -+ /* No rule matched */ -+ return 0; -+} -+ - /* Check if this user is OK to login. This only works with krb5 - other - * GSSAPI mechanisms will need their own. - * Returns true if the user is OK to log in, otherwise returns 0 -@@ -193,7 +220,7 @@ static int - ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) - { - krb5_principal princ; -- int retval; -+ int retval, matched; - const char *errmsg; - int k5login_exists; - -@@ -216,17 +243,42 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) - if (k5login_exists && - ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)) { - retval = 1; -- logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", -- name, (char *)client->displayname.value); -+ errmsg = "krb5_kuserok"; - } else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value, - name, k5login_exists)) { - retval = 1; -- logit("Authorized to %s, krb5 principal %s " -- "(ssh_gssapi_krb5_cmdok)", -- name, (char *)client->displayname.value); -+ errmsg = "ssh_gssapi_krb5_cmdok"; - } else - retval = 0; - -+ if ((retval == 1) && (options.gss_indicators != NULL)) { -+ /* At this point the configuration enforces presence of indicators -+ * so we drop the authorization result again */ -+ retval = 0; -+ if (client->indicators) { -+ matched = -1; -+ retval = ssh_gssapi_check_indicators(client, &matched); -+ if (retval != 0) { -+ retval = (retval == 1); -+ logit("Ticket contains indicator %s, " -+ "krb5 principal %s is %s", -+ client->indicators[matched], -+ (char *)client->displayname.value, -+ retval ? "allowed" : "denied"); -+ goto cont; -+ } -+ } -+ if (retval == 0) { -+ logit("GSSAPI authentication indicators enforced " -+ "but not matched. krb5 principal %s denied", -+ (char *)client->displayname.value); -+ } -+ } -+cont: -+ if (retval == 1) { -+ logit("Authorized to %s, krb5 principal %s (%s)", -+ name, (char *)client->displayname.value, errmsg); -+ } - krb5_free_principal(krb_context, princ); - return retval; - } -diff --git a/gss-serv.c b/gss-serv.c -index 9d5435eda..5c0491cf1 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -54,7 +54,7 @@ extern ServerOptions options; - - static ssh_gssapi_client gssapi_client = - { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, -- GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0}; -+ GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0, NULL}; - - ssh_gssapi_mech gssapi_null_mech = - { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -296,6 +296,92 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) - return GSS_S_COMPLETE; - } - -+ -+/* Extract authentication indicators from the Kerberos ticket. Authentication -+ * indicators are GSSAPI name attributes for the name "auth-indicators". -+ * Multiple indicators might be present in the ticket. -+ * Each indicator is a utf8 string. */ -+ -+#define AUTH_INDICATORS_TAG "auth-indicators" -+ -+/* Privileged (called from accept_secure_ctx) */ -+static OM_uint32 -+ssh_gssapi_getindicators(Gssctxt *ctx, gss_name_t gss_name, ssh_gssapi_client *client) -+{ -+ gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET; -+ gss_buffer_desc value = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc display_value = GSS_C_EMPTY_BUFFER; -+ int is_mechname, authenticated, complete, more; -+ size_t count, i; -+ -+ ctx->major = gss_inquire_name(&ctx->minor, gss_name, -+ &is_mechname, NULL, &attrs); -+ if (ctx->major != GSS_S_COMPLETE) { -+ return (ctx->major); -+ } -+ -+ if (attrs == GSS_C_NO_BUFFER_SET) { -+ /* No indicators in the ticket */ -+ return (0); -+ } -+ -+ count = 0; -+ for (i = 0; i < attrs->count; i++) { -+ /* skip anything but auth-indicators */ -+ if (((sizeof(AUTH_INDICATORS_TAG) - 1) != attrs->elements[i].length) || -+ strncmp(AUTH_INDICATORS_TAG, -+ attrs->elements[i].value, -+ sizeof(AUTH_INDICATORS_TAG) - 1) != 0) -+ continue; -+ count++; -+ } -+ -+ if (count == 0) { -+ /* No auth-indicators in the ticket */ -+ (void) gss_release_buffer_set(&ctx->minor, &attrs); -+ return (0); -+ } -+ -+ client->indicators = recallocarray(NULL, 0, count + 1, sizeof(char*)); -+ count = 0; -+ for (i = 0; i < attrs->count; i++) { -+ authenticated = 0; -+ complete = 0; -+ more = -1; -+ /* skip anything but auth-indicators */ -+ if (((sizeof(AUTH_INDICATORS_TAG) - 1) != attrs->elements[i].length) || -+ strncmp(AUTH_INDICATORS_TAG, -+ attrs->elements[i].value, -+ sizeof(AUTH_INDICATORS_TAG) - 1) != 0) -+ continue; -+ /* retrieve all indicators */ -+ while (more != 0) { -+ value.value = NULL; -+ display_value.value = NULL; -+ ctx->major = gss_get_name_attribute(&ctx->minor, gss_name, -+ &attrs->elements[i], &authenticated, -+ &complete, &value, &display_value, &more); -+ if (ctx->major != GSS_S_COMPLETE) { -+ goto out; -+ } -+ -+ if ((value.value != NULL) && authenticated) { -+ client->indicators[count] = xmalloc(value.length + 1); -+ memcpy(client->indicators[count], value.value, value.length); -+ client->indicators[count][value.length] = '\0'; -+ count++; -+ } -+ } -+ } -+ -+out: -+ (void) gss_release_buffer(&ctx->minor, &value); -+ (void) gss_release_buffer(&ctx->minor, &display_value); -+ (void) gss_release_buffer_set(&ctx->minor, &attrs); -+ return (ctx->major); -+} -+ -+ - /* Extract the client details from a given context. This can only reliably - * be called once for a context */ - -@@ -385,6 +471,12 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - } - - gss_release_buffer(&ctx->minor, &ename); -+ /* Retrieve authentication indicators, if they exist */ -+ if ((ctx->major = ssh_gssapi_getindicators(ctx, -+ ctx->client, client))) { -+ ssh_gssapi_error(ctx); -+ return (ctx->major); -+ } - - /* We can't copy this structure, so we just move the pointer to it */ - client->creds = ctx->client_creds; -@@ -447,6 +539,7 @@ int - ssh_gssapi_userok(char *user, struct passwd *pw, int kex) - { - OM_uint32 lmin; -+ size_t i; - - (void) kex; /* used in privilege separation */ - -@@ -465,6 +558,14 @@ ssh_gssapi_userok(char *user, struct passwd *pw, int kex) - gss_release_buffer(&lmin, &gssapi_client.displayname); - gss_release_buffer(&lmin, &gssapi_client.exportedname); - gss_release_cred(&lmin, &gssapi_client.creds); -+ -+ if (gssapi_client.indicators != NULL) { -+ for(i = 0; gssapi_client.indicators[i] != NULL; i++) { -+ free(gssapi_client.indicators[i]); -+ } -+ free(gssapi_client.indicators); -+ } -+ - explicit_bzero(&gssapi_client, - sizeof(ssh_gssapi_client)); - return 0; -diff --git a/servconf.c b/servconf.c -index e7e4ad046..aab653244 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -147,6 +147,7 @@ initialize_server_options(ServerOptions *options) - options->gss_strict_acceptor = -1; - options->gss_store_rekey = -1; - options->gss_kex_algorithms = NULL; -+ options->gss_indicators = NULL; - options->use_kuserok = -1; - options->enable_k5users = -1; - options->password_authentication = -1; -@@ -598,7 +599,7 @@ typedef enum { - sPerSourcePenalties, sPerSourcePenaltyExemptList, - sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, -- sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, -+ sGssKeyEx, sGssIndicators, sGssKexAlgorithms, sGssStoreRekey, - sAcceptEnv, sSetEnv, sPermitTunnel, - sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, - sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -694,6 +695,7 @@ static struct { - { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, - { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, - { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, -+ { "gssapiindicators", sGssIndicators, SSHCFG_ALL }, - #else - { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, - { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -703,6 +705,7 @@ static struct { - { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, - { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, - { "gssapienablek5users", sUnsupported, SSHCFG_ALL }, -+ { "gssapiindicators", sUnsupported, SSHCFG_ALL }, - #endif - { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, - { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1730,6 +1733,15 @@ process_server_config_line_depth(ServerOptions *options, char *line, - options->gss_kex_algorithms = xstrdup(arg); - break; - -+ case sGssIndicators: -+ arg = argv_next(&ac, &av); -+ if (!arg || *arg == '\0') -+ fatal("%s line %d: %s missing argument.", -+ filename, linenum, keyword); -+ if (options->gss_indicators == NULL) -+ options->gss_indicators = xstrdup(arg); -+ break; -+ - case sPasswordAuthentication: - intptr = &options->password_authentication; - goto parse_flag; -@@ -3351,6 +3363,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); - dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); - dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); -+ dump_cfg_string(sGssIndicators, o->gss_indicators); - #endif - dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); - dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff --git a/servconf.h b/servconf.h -index 7c7e5d434..7c41df417 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -181,6 +181,7 @@ typedef struct { - char **allow_groups; - u_int num_deny_groups; - char **deny_groups; -+ char *gss_indicators; - - u_int num_subsystems; - char **subsystem_name; -@@ -310,6 +311,7 @@ TAILQ_HEAD(include_list, include_item); - M_CP_STROPT(routing_domain); \ - M_CP_STROPT(permit_user_env_allowlist); \ - M_CP_STROPT(pam_service_name); \ -+ M_CP_STROPT(gss_indicators); \ - M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ - M_CP_STRARRAYOPT(allow_users, num_allow_users); \ - M_CP_STRARRAYOPT(deny_users, num_deny_users); \ -diff --git a/ssh-gss.h b/ssh-gss.h -index a894e23c9..59cf46d47 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -34,6 +34,12 @@ - #include - #endif - -+#ifdef HAVE_GSSAPI_EXT_H -+#include -+#elif defined(HAVE_GSSAPI_GSSAPI_EXT_H) -+#include -+#endif -+ - #ifdef KRB5 - # ifndef HEIMDAL - # ifdef HAVE_GSSAPI_GENERIC_H -@@ -107,6 +113,7 @@ typedef struct { - ssh_gssapi_ccache store; - int used; - int updated; -+ char **indicators; /* auth indicators */ - } ssh_gssapi_client; - - typedef struct ssh_gssapi_mech_struct { -diff --git a/sshd_config.5 b/sshd_config.5 -index 583a01cdb..90ab87edd 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -785,6 +785,50 @@ gss-nistp256-sha256- - gss-curve25519-sha256- - .Ed - This option only applies to connections using GSSAPI. -+.It Cm GSSAPIIndicators -+Specifies whether to accept or deny GSSAPI authenticated access if Kerberos -+mechanism is used and Kerberos ticket contains a particular set of -+authentication indicators. The values can be specified as a comma-separated list -+.Cm [!]name1,[!]name2,... . -+When indicator's name is prefixed with !, the authentication indicator 'name' -+will deny access to the system. Otherwise, one of non-negated authentication -+indicators must be present in the Kerberos ticket to allow access. If -+.Cm GSSAPIIndicators -+is defined, a Kerberos ticket that has indicators but does not match the -+policy will get denial. If at least one indicator is configured, whether for -+access or denial, tickets without authentication indicators will be explicitly -+rejected. -+.Pp -+By default systems using MIT Kerberos 1.17 or later will not assign any -+indicators. SPAKE and PKINIT methods add authentication indicators -+to all successful authentications. The SPAKE pre-authentication method is -+preferred over an encrypted timestamp pre-authentication when passwords used to -+authenticate user principals. Kerberos KDCs built with Heimdal Kerberos -+(including Samba AD DC built with Heimdal) do not add authentication -+indicators. However, OpenSSH built against Heimdal Kerberos library is able to -+inquire authentication indicators and thus can be used to check for their presence. -+.Pp -+Indicator name is case-sensitive and depends on the configuration of a -+particular Kerberos deployment. Indicators available in MIT Kerberos and -+FreeIPA environments: -+.Pp -+.Bl -tag -width XXXX -offset indent -compact -+.It Cm hardened -+SPAKE or encrypted timestamp pre-authentication mechanisms in MIT Kerberos and FreeIPA -+.It Cm pkinit -+smartcard or PKCS11 token-based pre-authentication in MIT Kerberos and FreeIPA -+.It Cm radius -+pre-authentication based on a RADIUS server in MIT Kerberos and FreeIPA -+.It Cm otp -+TOTP/HOTP-based two-factor pre-authentication in FreeIPA -+.It Cm idp -+OAuth2-based pre-authentication in FreeIPA using an external identity provider -+and device authorization grant flow -+.It Cm passkey -+FIDO2-based pre-authentication in FreeIPA, using FIDO2 USB and NFC tokens -+.El -+.Pp -+The default is to not use GSSAPI authentication indicators for access decisions. - .It Cm HostbasedAcceptedAlgorithms - The default is handled system-wide by - .Xr crypto-policies 7 . --- -2.49.0 - diff --git a/1000-openssh-coverity.patch b/1000-openssh-coverity.patch deleted file mode 100644 index 88362eb..0000000 --- a/1000-openssh-coverity.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 24c411970682dc67873c36bac05b4b460d68a628 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 50/50] openssh-6.7p1-coverity - ---- - auth-krb5.c | 2 ++ - gss-genr.c | 3 ++- - krl.c | 3 +++ - loginrec.c | 2 ++ - misc.c | 3 +++ - monitor.c | 4 ++-- - openbsd-compat/bindresvport.c | 2 +- - openbsd-compat/bsd-pselect.c | 8 ++++---- - readconf.c | 1 + - servconf.c | 5 +++-- - serverloop.c | 2 +- - ssh-agent.c | 1 + - ssh-keygen.c | 3 +++ - 13 files changed, 28 insertions(+), 11 deletions(-) - -diff --git a/auth-krb5.c b/auth-krb5.c -index bae153c9..209a3265 100644 ---- a/auth-krb5.c -+++ b/auth-krb5.c -@@ -427,6 +427,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)); -+ free(ccname); - return oerrno; - } - -@@ -434,6 +435,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm - oerrno = errno; - logit("fchmod(): %.100s", strerror(oerrno)); - close(tmpfd); -+ free(ccname); - return oerrno; - } - /* make sure the KRB5CCNAME is set for non-standard location */ -diff --git a/gss-genr.c b/gss-genr.c -index 3034370c..c357e973 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); -- -+#pragma GCC diagnostic ignored "-Wstringop-overflow" - cp = strncpy(s, kex, strlen(kex)); -+#pragma GCC diagnostic pop - for ((p = strsep(&cp, ",")); p && *p != '\0'; - (p = strsep(&cp, ","))) { - if (sshbuf_len(buf) != 0 && -diff --git a/krl.c b/krl.c -index 0d0f6953..d8517f12 100644 ---- a/krl.c -+++ b/krl.c -@@ -1202,6 +1202,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); -+ rb.blob = NULL; /* make coverity happy */ - if (erb != NULL) { - KRL_DBG(("revoked by key SHA1")); - return SSH_ERR_KEY_REVOKED; -@@ -1212,6 +1213,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); -+ rb.blob = NULL; /* make coverity happy */ - if (erb != NULL) { - KRL_DBG(("revoked by key SHA256")); - return SSH_ERR_KEY_REVOKED; -@@ -1223,6 +1225,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); -+ rb.blob = NULL; /* make coverity happy */ - if (erb != NULL) { - KRL_DBG(("revoked by explicit key")); - return SSH_ERR_KEY_REVOKED; -diff --git a/loginrec.c b/loginrec.c -index c4a9bd48..2583612c 100644 ---- a/loginrec.c -+++ b/loginrec.c -@@ -683,9 +683,11 @@ construct_utmp(struct logininfo *li, - */ - - /* Use strncpy because we don't necessarily want null termination */ -+ /* coverity[buffer_size_warning : FALSE] */ - strncpy(ut->ut_name, li->username, - MIN_SIZEOF(ut->ut_name, li->username)); - # ifdef HAVE_HOST_IN_UTMP -+ /* coverity[buffer_size_warning : FALSE] */ - strncpy(ut->ut_host, li->hostname, - MIN_SIZEOF(ut->ut_host, li->hostname)); - # endif -diff --git a/misc.c b/misc.c -index 09722962..cd71c1b2 100644 ---- a/misc.c -+++ b/misc.c -@@ -1556,6 +1556,8 @@ sanitise_stdfd(void) - } - if (nullfd > STDERR_FILENO) - close(nullfd); -+ /* coverity[leaked_handle : FALSE]*/ -+ /* coverity[leaked_handle : FALSE]*/ - } - - char * -@@ -2749,6 +2751,7 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) - } - if (devnull > STDERR_FILENO) - close(devnull); -+ /* coverity[leaked_handle : FALSE]*/ - return ret; - } - -diff --git a/monitor.c b/monitor.c -index 19cb058e..58fbac9d 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -415,7 +415,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) - mm_get_keystate(ssh, pmonitor); - - /* Drain any buffered messages from the child */ -- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) -+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) - ; - - if (pmonitor->m_recvfd >= 0) -@@ -1813,7 +1813,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); -- -+ /* coverity[leaked_handle : FALSE] */ - return (0); - - error: -diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c -index 346c7fe5..f42792fd 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; -- socklen_t salen; -+ socklen_t salen = sizeof(struct sockaddr_storage); - int i; - - if (sa == NULL) { -diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c -index 26bdc3e0..8e2939b9 100644 ---- a/openbsd-compat/bsd-pselect.c -+++ b/openbsd-compat/bsd-pselect.c -@@ -85,13 +85,13 @@ pselect_notify_setup(void) - static void - pselect_notify_parent(void) - { -- if (notify_pipe[1] != -1) -+ if (notify_pipe[1] >= 0) - (void)write(notify_pipe[1], "", 1); - } - static void - pselect_notify_prepare(fd_set *readset) - { -- if (notify_pipe[0] != -1) -+ if (notify_pipe[0] >= 0) - FD_SET(notify_pipe[0], readset); - } - static void -@@ -99,8 +99,8 @@ pselect_notify_done(fd_set *readset) - { - char c; - -- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) { -- while (read(notify_pipe[0], &c, 1) != -1) -+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) { -+ while (read(notify_pipe[0], &c, 1) >= 0) - debug2_f("reading"); - FD_CLR(notify_pipe[0], readset); - } -diff --git a/readconf.c b/readconf.c -index ea9d293c..9680c38c 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -2164,6 +2164,7 @@ parse_pubkey_algos: - } else if (r != 0) { - error("%.200s line %d: glob failed for %s.", - filename, linenum, arg2); -+ free(arg2); - goto out; - } - free(arg2); -diff --git a/servconf.c b/servconf.c -index 8b708cbf..e7e4ad04 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -2293,8 +2293,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, - if (*activep && *charptr == NULL) { - *charptr = tilde_expand_filename(arg, getuid()); - /* increase optional counter */ -- if (intptr != NULL) -- *intptr = *intptr + 1; -+ /* DEAD CODE intptr is still NULL ;) -+ if (intptr != NULL) -+ *intptr = *intptr + 1; */ - } - break; - -diff --git a/serverloop.c b/serverloop.c -index 9c5b1567..768ee9fa 100644 ---- a/serverloop.c -+++ b/serverloop.c -@@ -511,7 +511,7 @@ server_request_tun(struct ssh *ssh) - debug_f("invalid tun"); - goto done; - } -- if (auth_opts->force_tun_device != -1) { -+ if (auth_opts->force_tun_device >= 0) { - if (tun != SSH_TUNID_ANY && - auth_opts->force_tun_device != (int)tun) - goto done; -diff --git a/ssh-agent.c b/ssh-agent.c -index 798bf9b6..0e39dff7 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -1593,6 +1593,7 @@ sanitize_pkcs11_provider(const char *provider) - - if (pkcs11_uri_parse(provider, uri) != 0) { - error("Failed to parse PKCS#11 URI"); -+ pkcs11_uri_cleanup(uri); - return NULL; - } - /* validate also provider from URI */ -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 792aafde..96b3474d 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -2424,6 +2424,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; --- -2.49.0 - diff --git a/gsi-openssh.spec b/gsi-openssh.spec index ef847b1..0943d8c 100644 --- a/gsi-openssh.spec +++ b/gsi-openssh.spec @@ -23,12 +23,12 @@ # Do we want libedit support %global libedit 1 -%global openssh_ver 10.0p1 +%global openssh_ver 9.9p1 Summary: An implementation of the SSH protocol with GSI authentication Name: gsi-openssh Version: %{openssh_ver} -Release: 4%{?dist} +Release: 6%{?dist} Provides: gsissh = %{version}-%{release} Obsoletes: gsissh < 5.8p2-2 URL: http://www.openssh.com/portable.html @@ -48,144 +48,159 @@ Source20: gsissh-host-keys-migration.sh Source21: gsissh-host-keys-migration.service Source99: README.sshd-and-gsisshd +#https://bugzilla.mindrot.org/show_bug.cgi?id=2581 +Patch100: openssh-6.7p1-coverity.patch + +#https://bugzilla.mindrot.org/show_bug.cgi?id=1402 +# https://bugzilla.redhat.com/show_bug.cgi?id=1171248 +# record pfs= field in CRYPTO_SESSION audit event +Patch200: openssh-7.6p1-audit.patch +# Audit race condition in forked child (#1310684) +Patch201: openssh-7.1p2-audit-race-condition.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2049947 +Patch202: openssh-9.0p1-audit-log.patch + #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) -Patch0001: 0001-openssh-7.8p1-role-mls.patch +Patch400: openssh-7.8p1-role-mls.patch #https://bugzilla.redhat.com/show_bug.cgi?id=781634 -Patch0002: 0002-openssh-6.6p1-privsep-selinux.patch -Patch0003: 0003-openssh-6.6p1-keycat.patch +Patch404: openssh-6.6p1-privsep-selinux.patch +#? +Patch502: openssh-6.6p1-keycat.patch + #https://bugzilla.mindrot.org/show_bug.cgi?id=1644 -Patch0004: 0004-openssh-6.6p1-allow-ip-opts.patch +Patch601: openssh-6.6p1-allow-ip-opts.patch #(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925 -Patch0005: 0005-openssh-5.9p1-ipv6man.patch -Patch0006: 0006-openssh-5.8p2-sigpipe.patch +Patch606: openssh-5.9p1-ipv6man.patch +#? +Patch607: openssh-5.8p2-sigpipe.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1789 -Patch0007: 0007-openssh-7.2p2-x11.patch -Patch0008: 0008-openssh-5.1p1-askpass-progress.patch +Patch609: openssh-7.2p2-x11.patch + +#? +Patch700: openssh-7.7p1-fips.patch +#? +Patch702: openssh-5.1p1-askpass-progress.patch #https://bugzilla.redhat.com/show_bug.cgi?id=198332 -Patch0009: 0009-openssh-4.3p2-askpass-grab-info.patch +Patch703: openssh-4.3p2-askpass-grab-info.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) -Patch0010: 0010-openssh-8.7p1-redhat.patch +Patch707: openssh-8.7p1-redhat.patch # warn users for unsupported UsePAM=no (#757545) -Patch0011: 0011-openssh-7.8p1-UsePAM-warning.patch +Patch711: openssh-7.8p1-UsePAM-warning.patch + # GSSAPI Key Exchange (RFC 4462 + RFC 8732) # from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master # and # Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures # upstream MR: # https://github.com/openssh-gsskex/openssh-gsskex/pull/21 -Patch0012: 0012-openssh-9.6p1-gssapi-keyex.patch +Patch800: openssh-9.6p1-gssapi-keyex.patch #http://www.mail-archive.com/kerberos@mit.edu/msg17591.html -Patch0013: 0013-openssh-6.6p1-force_krb.patch -# Improve ccache handling in openssh (#991186, #1199363, #1566494) -# https://bugzilla.mindrot.org/show_bug.cgi?id=2775 -Patch0014: 0014-openssh-7.7p1-gssapi-new-unique.patch -# Respect k5login_directory option in krk5.conf (#1328243) -Patch0015: 0015-openssh-7.2p2-k5login_directory.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1780 -Patch0016: 0016-openssh-6.6p1-kuserok.patch -# Use tty allocation for a remote scp (#985650) -Patch0017: 0017-openssh-6.4p1-fromto-remote.patch -# privsep_preauth: use SELinux context from selinux-policy (#1008580) -Patch0018: 0018-openssh-6.6.1p1-selinux-contexts.patch -# log via monitor in chroots without /dev/log (#2681) -Patch0019: 0019-openssh-6.6.1p1-log-in-chroot.patch -# scp file into non-existing directory (#1142223) -Patch0020: 0020-openssh-6.6.1p1-scp-non-existing-directory.patch +Patch801: openssh-6.6p1-force_krb.patch # add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843) # CVE-2014-9278 -Patch0021: 0021-openssh-6.6p1-GSSAPIEnablek5users.patch +Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch +# Improve ccache handling in openssh (#991186, #1199363, #1566494) +# https://bugzilla.mindrot.org/show_bug.cgi?id=2775 +Patch804: openssh-7.7p1-gssapi-new-unique.patch +# Respect k5login_directory option in krk5.conf (#1328243) +Patch805: openssh-7.2p2-k5login_directory.patch + +#https://bugzilla.mindrot.org/show_bug.cgi?id=1780 +Patch901: openssh-6.6p1-kuserok.patch +# Use tty allocation for a remote scp (#985650) +Patch906: openssh-6.4p1-fromto-remote.patch +# privsep_preauth: use SELinux context from selinux-policy (#1008580) +Patch916: openssh-6.6.1p1-selinux-contexts.patch +# log via monitor in chroots without /dev/log (#2681) +Patch918: openssh-6.6.1p1-log-in-chroot.patch +# scp file into non-existing directory (#1142223) +Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch # apply upstream patch and make sshd -T more consistent (#1187521) -Patch0022: 0022-openssh-6.8p1-sshdT-output.patch +Patch922: openssh-6.8p1-sshdT-output.patch # Add sftp option to force mode of created files (#1191055) -Patch0023: 0023-openssh-6.7p1-sftp-force-permission.patch +Patch926: openssh-6.7p1-sftp-force-permission.patch # make s390 use /dev/ crypto devices -- ignore closefrom -Patch0024: 0024-openssh-7.2p2-s390-closefrom.patch +Patch939: openssh-7.2p2-s390-closefrom.patch # Move MAX_DISPLAYS to a configuration option (#1341302) -Patch0025: 0025-openssh-7.3p1-x11-max-displays.patch +Patch944: openssh-7.3p1-x11-max-displays.patch # Pass inetd flags for SELinux down to openbsd compat level -Patch0026: 0026-openssh-7.6p1-cleanup-selinux.patch +Patch949: openssh-7.6p1-cleanup-selinux.patch # Sandbox adjustments for s390 and audit -Patch0027: 0027-openssh-7.5p1-sandbox.patch +Patch950: openssh-7.5p1-sandbox.patch # PKCS#11 URIs (upstream #2817, 2nd iteration) # https://github.com/Jakuje/openssh-portable/commits/jjelen-pkcs11 # git show > ~/devel/fedora/openssh/openssh-8.0p1-pkcs11-uri.patch -Patch0028: 0028-openssh-8.0p1-pkcs11-uri.patch +Patch951: openssh-8.0p1-pkcs11-uri.patch # Unbreak scp between two IPv6 hosts (#1620333) -Patch0029: 0029-openssh-7.8p1-scp-ipv6.patch +Patch953: openssh-7.8p1-scp-ipv6.patch # Mention crypto-policies in manual pages (#1668325) # clarify rhbz#2068423 on the man page of ssh_config -Patch0030: 0030-openssh-8.0p1-crypto-policies.patch +Patch962: openssh-8.0p1-crypto-policies.patch # Use OpenSSL KDF (#1631761) -Patch0031: 0031-openssh-8.0p1-openssl-kdf.patch +Patch964: openssh-8.0p1-openssl-kdf.patch # sk-dummy.so built with -fvisibility=hidden does not work -Patch0032: 0032-openssh-8.2p1-visibility.patch +Patch965: openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 -Patch0033: 0033-openssh-8.2p1-x11-without-ipv6.patch +Patch966: openssh-8.2p1-x11-without-ipv6.patch +# ssh-keygen printing fingerprint issue with Windows keys (#1901518) +Patch974: openssh-8.0p1-keygen-strip-doseol.patch # sshd provides PAM an incorrect error code (#1879503) -Patch0034: 0034-openssh-8.0p1-preserve-pam-errors.patch +Patch975: openssh-8.0p1-preserve-pam-errors.patch # Implement kill switch for SCP protocol -Patch0035: 0035-openssh-8.7p1-scp-kill-switch.patch +Patch977: openssh-8.7p1-scp-kill-switch.patch # Workaround for lack of sftp_realpath in older versions of RHEL # https://bugzilla.redhat.com/show_bug.cgi?id=2038854 # https://github.com/openssh/openssh-portable/pull/299 # downstream only -Patch0036: 0036-openssh-8.7p1-recursive-scp.patch -# Downstream alias for MinRSABits -Patch0037: 0037-openssh-8.7p1-minrsabits.patch +Patch981: openssh-8.7p1-recursive-scp.patch +# https://github.com/djmdjm/openssh-wip/pull/13 +Patch982: openssh-8.7p1-minrsabits.patch # downstream only, IBMCA tentative fix # From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14 -Patch0038: 0038-openssh-8.7p1-ibmca.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=1402 -# https://bugzilla.redhat.com/show_bug.cgi?id=1171248 -# record pfs= field in CRYPTO_SESSION audit event -Patch0039: 0039-openssh-7.6p1-audit.patch -# Audit race condition in forked child (#1310684) -Patch0040: 0040-openssh-7.1p2-audit-race-condition.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=2049947 -Patch0041: 0041-openssh-9.0p1-audit-log.patch -Patch0042: 0042-openssh-7.7p1-fips.patch +Patch984: openssh-8.7p1-ibmca.patch + # Add missing options from ssh_config into ssh manpage # upstream bug: # https://bugzilla.mindrot.org/show_bug.cgi?id=3455 -Patch0043: 0043-openssh-8.7p1-ssh-manpage.patch +Patch1002: openssh-8.7p1-ssh-manpage.patch # Don't propose disallowed algorithms during hostkey negotiation # upstream MR: # https://github.com/openssh/openssh-portable/pull/323 -Patch0044: 0044-openssh-8.7p1-negotiate-supported-algs.patch -Patch0045: 0045-openssh-9.0p1-evp-fips-kex.patch -Patch0046: 0046-openssh-8.7p1-nohostsha1proof.patch -Patch0047: 0047-openssh-9.6p1-pam-rhost.patch -Patch0048: 0048-openssh-9.9p1-separate-keysign.patch -Patch0049: 0049-openssh-9.9p1-openssl-mlkem.patch -# https://www.openwall.com/lists/oss-security/2025/02/22/1 -Patch0050: 0050-openssh-9.9p2-error_processing.patch -# https://github.com/openssh/openssh-portable/pull/564 -Patch0051: 0051-Provide-better-error-for-non-supported-private-keys.patch -# https://github.com/openssh/openssh-portable/pull/567 -Patch0052: 0052-Ignore-bad-hostkeys-in-known_hosts-file.patch -# https://github.com/openssh/openssh-portable/pull/500 -Patch0053: 0053-support-authentication-indicators-in-GSSAPI.patch +Patch1006: openssh-8.7p1-negotiate-supported-algs.patch -#https://bugzilla.mindrot.org/show_bug.cgi?id=2581 -Patch1000: 1000-openssh-coverity.patch +Patch1012: openssh-9.0p1-evp-fips-kex.patch +Patch1014: openssh-8.7p1-nohostsha1proof.patch + +Patch1015: openssh-9.6p1-pam-rhost.patch +Patch1016: openssh-9.9p1-separate-keysign.patch +# upstream cf3e48ee8ba1beeccddd2f203b558fa102be67a2 +# upstream 0c3927c45f8a57b511c874c4d51a8c89414f74ef +Patch1017: openssh-9.9p1-mlkembe.patch +# upstream 3f02368e8e9121847727c46b280efc280e5eb615 +# upstream 67a115e7a56dbdc3f5a58c64b29231151f3670f5 +Patch1020: openssh-9.9p1-match-regression.patch +# upstream 6ce00f0c2ecbb9f75023dbe627ee6460bcec78c2 +# upstream 0832aac79517611dd4de93ad0a83577994d9c907 +Patch1021: openssh-9.9p2-error_processing.patch +# upstream fc86875e6acb36401dfc1dfb6b628a9d1460f367 +Patch1022: openssh-9.9p1-disable-forwarding.patch # This is the patch that adds GSI support # Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream -Patch2000: 2000-openssh-10.0p1-gsissh.patch +Patch98: openssh-9.9p1-gsissh.patch # This is the HPN patch -# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.7.0 -Patch2001: 2001-openssh-10.0p1-hpn-18.7.0.patch +# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.6.0 +Patch99: openssh-9.9p1-hpn-18.6.0.patch License: BSD-3-Clause AND BSD-2-Clause AND ISC AND SSH-OpenSSH AND ssh-keyscan AND sprintf AND LicenseRef-Fedora-Public-Domain AND X11-distribute-modifications-variant Requires: /sbin/nologin -Requires: openssl-libs >= 3.5.0 BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel BuildRequires: audit-libs-devel >= 2.0.5 BuildRequires: util-linux, groff BuildRequires: pam-devel -BuildRequires: openssl-devel >= 3.5.0 +BuildRequires: openssl-devel >= 0.9.8j BuildRequires: systemd-devel BuildRequires: systemd-rpm-macros BuildRequires: gcc make @@ -280,7 +295,72 @@ This version of OpenSSH has been modified to support GSI authentication. %prep gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} -%autosetup -T -b 0 -p1 -n openssh-%{version} +%setup -q -n openssh-%{version} + +%patch -P 400 -p1 -b .role-mls +%patch -P 404 -p1 -b .privsep-selinux + +%patch -P 502 -p1 -b .keycat + +%patch -P 601 -p1 -b .ip-opts +%patch -P 606 -p1 -b .ipv6man +%patch -P 607 -p1 -b .sigpipe +%patch -P 609 -p1 -b .x11 + +%patch -P 702 -p1 -b .progress +%patch -P 703 -p1 -b .grab-info +%patch -P 707 -p1 -b .redhat +%patch -P 711 -p1 -b .log-usepam-no + +%patch -P 800 -p1 -b .gsskex +%patch -P 801 -p1 -b .force_krb +%patch -P 804 -p1 -b .ccache_name +%patch -P 805 -p1 -b .k5login + +%patch -P 901 -p1 -b .kuserok +%patch -P 906 -p1 -b .fromto-remote +%patch -P 916 -p1 -b .contexts +%patch -P 918 -p1 -b .log-in-chroot +%patch -P 919 -p1 -b .scp +%patch -P 802 -p1 -b .GSSAPIEnablek5users +%patch -P 922 -p1 -b .sshdt +%patch -P 926 -p1 -b .sftp-force-mode +%patch -P 939 -p1 -b .s390-dev +%patch -P 944 -p1 -b .x11max +%patch -P 949 -p1 -b .refactor +%patch -P 950 -p1 -b .sandbox +%patch -P 951 -p1 -b .pkcs11-uri +%patch -P 953 -p1 -b .scp-ipv6 +%patch -P 962 -p1 -b .crypto-policies +%patch -P 964 -p1 -b .openssl-kdf +%patch -P 965 -p1 -b .visibility +%patch -P 966 -p1 -b .x11-ipv6 +%patch -P 974 -p1 -b .keygen-strip-doseol +%patch -P 975 -p1 -b .preserve-pam-errors +%patch -P 977 -p1 -b .kill-scp +%patch -P 981 -p1 -b .scp-sftpdirs +%patch -P 982 -p1 -b .minrsabits +%patch -P 984 -p1 -b .ibmca + +%patch -P 200 -p1 -b .audit +%patch -P 201 -p1 -b .audit-race +%patch -P 202 -p1 -b .audit-log +%patch -P 700 -p1 -b .fips + +%patch -P 1002 -p1 -b .ssh-manpage +%patch -P 1006 -p1 -b .negotiate-supported-algs +%patch -P 1012 -p1 -b .evp-fips-dh +%patch -P 1014 -p1 -b .nosha1hostproof +%patch -P 1015 -p1 -b .pam-rhost +%patch -P 1016 -p1 -b .sep-keysign +%patch -P 1017 -p1 -b .mlkembe +%patch -P 1020 -p1 -b .match +%patch -P 1021 -p1 -b .errcode_set +%patch -P 1022 -p1 -b .disable-forwarding + +%patch -P 100 -p1 -b .coverity +%patch -P 98 -p1 -b .gsi +%patch -P 99 -p1 -b .hpn sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in @@ -478,7 +558,6 @@ fi %dir %attr(0711,root,root) %{_datadir}/empty.sshd %attr(0755,root,root) %{_sbindir}/gsisshd %attr(0755,root,root) %{_libexecdir}/gsissh/sshd-session -%attr(0755,root,root) %{_libexecdir}/gsissh/sshd-auth %attr(0755,root,root) %{_libexecdir}/gsissh/sftp-server %attr(0755,root,root) %{_libexecdir}/gsissh/sshd-keygen %attr(0644,root,root) %{_mandir}/man5/gsisshd_config.5* @@ -502,23 +581,11 @@ fi %ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration %changelog -* Mon Sep 01 2025 Mattias Ellert - 10.0p1-4 -- Based on openssh-10.0p1-6.fc44 +* Thu Jun 12 2025 Mattias Ellert - 9.9p1-6 +- Based on openssh-9.9p1-11.fc42 -* Mon Sep 01 2025 Mattias Ellert - 10.0p1-3 -- Based on openssh-10.0p1-4.fc43 - -* Thu Jul 24 2025 Fedora Release Engineering - 10.0p1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Mon Jun 16 2025 Mattias Ellert - 10.0p1-1 -- Based on openssh-10.0p1-3.fc43 - -* Sun Apr 20 2025 Mattias Ellert - 9.9p1-6 -- Based on openssh-9.9p1-15.fc43 - -* Wed Mar 05 2025 Mattias Ellert - 9.9p1-5 -- Based on openssh-9.9p1-11.fc43 +* Sun Apr 20 2025 Mattias Ellert - 9.9p1-5 +- Based on openssh-9.9p1-10.fc42 * Wed Mar 05 2025 Mattias Ellert - 9.9p1-4 - Based on openssh-9.9p1-9.fc42 diff --git a/gsisshd.sysconfig b/gsisshd.sysconfig index e968b50..7e106f4 100644 --- a/gsisshd.sysconfig +++ b/gsisshd.sysconfig @@ -8,4 +8,3 @@ #SSH_RSA_BITS=3072 #SSH_ECDSA_BITS=256 -OPTIONS="" diff --git a/gsisshd@.service b/gsisshd@.service index 093931e..acc3d85 100644 --- a/gsisshd@.service +++ b/gsisshd@.service @@ -13,6 +13,4 @@ Wants=gsissh-host-keys-migration.service Environment=OPTIONS= EnvironmentFile=-/etc/sysconfig/gsisshd ExecStart=-/usr/sbin/gsisshd -i $OPTIONS -ExecStart=-/usr/sbin/gsisshd -i $OPTIONS -o "AuthorizedKeysFile ${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys" StandardInput=socket -ImportCredential=ssh.ephemeral-authorized_keys-all diff --git a/0009-openssh-4.3p2-askpass-grab-info.patch b/openssh-4.3p2-askpass-grab-info.patch similarity index 53% rename from 0009-openssh-4.3p2-askpass-grab-info.patch rename to openssh-4.3p2-askpass-grab-info.patch index 8a7cf9e..120ed1b 100644 --- a/0009-openssh-4.3p2-askpass-grab-info.patch +++ b/openssh-4.3p2-askpass-grab-info.patch @@ -1,17 +1,7 @@ -From 710ce53fdf1d32a0629fce2e42fb49d407e2b06c Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 09/50] openssh-4.3p2-askpass-grab-info - ---- - contrib/gnome-ssh-askpass2.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c -index cb7152dc..bbe93d83 100644 ---- a/contrib/gnome-ssh-askpass2.c -+++ b/contrib/gnome-ssh-askpass2.c -@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_window, const char *what) +diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/contrib/gnome-ssh-askpass2.c +--- openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info 2021-04-19 13:57:11.720113536 +0200 ++++ openssh-8.6p1/contrib/gnome-ssh-askpass2.c 2021-04-19 13:59:29.842163204 +0200 +@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_wi err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, @@ -26,6 +16,3 @@ index cb7152dc..bbe93d83 100644 gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); gtk_dialog_run(GTK_DIALOG(err)); --- -2.49.0 - diff --git a/0008-openssh-5.1p1-askpass-progress.patch b/openssh-5.1p1-askpass-progress.patch similarity index 66% rename from 0008-openssh-5.1p1-askpass-progress.patch rename to openssh-5.1p1-askpass-progress.patch index f7ca382..ff609da 100644 --- a/0008-openssh-5.1p1-askpass-progress.patch +++ b/openssh-5.1p1-askpass-progress.patch @@ -1,17 +1,7 @@ -From 6b2a33044583e892badb9ac86cd2c6252b1a532f Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 08/50] openssh-5.1p1-askpass-progress - ---- - contrib/gnome-ssh-askpass2.c | 39 +++++++++++++++++++++++++++++++++--- - 1 file changed, 36 insertions(+), 3 deletions(-) - -diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c -index a62f9815..cb7152dc 100644 ---- a/contrib/gnome-ssh-askpass2.c -+++ b/contrib/gnome-ssh-askpass2.c -@@ -58,6 +58,7 @@ +diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contrib/gnome-ssh-askpass2.c +--- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:16.545211926 +0100 +@@ -53,6 +53,7 @@ #include #include @@ -19,7 +9,7 @@ index a62f9815..cb7152dc 100644 #include #include #include -@@ -146,6 +147,17 @@ parse_env_hex_color(const char *env, GdkColor *c) +@@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia return 1; } @@ -37,7 +27,7 @@ index a62f9815..cb7152dc 100644 static int passphrase_dialog(char *message, int prompt_type) { -@@ -153,7 +165,7 @@ passphrase_dialog(char *message, int prompt_type) + const char *failed; char *passphrase, *local; int result, grab_tries, grab_server, grab_pointer; int buttons, default_response; @@ -46,7 +36,7 @@ index a62f9815..cb7152dc 100644 GdkGrabStatus status; GdkColor fg, bg; int fg_set = 0, bg_set = 0; -@@ -199,14 +211,19 @@ passphrase_dialog(char *message, int prompt_type) +@@ -104,14 +116,19 @@ passphrase_dialog(char *message) gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg); if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) { @@ -55,12 +45,12 @@ index a62f9815..cb7152dc 100644 + FALSE, 0); + gtk_widget_show(hbox); + - entry = gtk_entry_new(); - if (fg_set) - gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg); - if (bg_set) - gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg); - gtk_box_pack_start( + entry = gtk_entry_new(); + if (fg_set) + gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg); + if (bg_set) + gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg); + gtk_box_pack_start( - GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), - entry, FALSE, FALSE, 0); + GTK_BOX(hbox), entry, TRUE, FALSE, 0); @@ -68,7 +58,7 @@ index a62f9815..cb7152dc 100644 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_widget_grab_focus(entry); if (prompt_type == PROMPT_ENTRY) { -@@ -225,6 +242,22 @@ passphrase_dialog(char *message, int prompt_type) +@@ -130,6 +145,22 @@ passphrase_dialog(char *message) g_signal_connect(G_OBJECT(entry), "key_press_event", G_CALLBACK(check_none), dialog); } @@ -91,6 +81,3 @@ index a62f9815..cb7152dc 100644 } /* Grab focus */ --- -2.49.0 - diff --git a/openssh-5.8p2-sigpipe.patch b/openssh-5.8p2-sigpipe.patch new file mode 100644 index 0000000..554e346 --- /dev/null +++ b/openssh-5.8p2-sigpipe.patch @@ -0,0 +1,14 @@ +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,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 = xcalloc(maxfd, sizeof(struct pollfd)); + for (j = 0; j < maxfd; j++) + read_wait[j].fd = -1; + diff --git a/0005-openssh-5.9p1-ipv6man.patch b/openssh-5.9p1-ipv6man.patch similarity index 54% rename from 0005-openssh-5.9p1-ipv6man.patch rename to openssh-5.9p1-ipv6man.patch index 909b988..ece1a73 100644 --- a/0005-openssh-5.9p1-ipv6man.patch +++ b/openssh-5.9p1-ipv6man.patch @@ -1,18 +1,7 @@ -From 388be633842a9f3e4b0a76fe40cf7035912a913a Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 05/50] openssh-5.9p1-ipv6man - ---- - ssh.1 | 2 ++ - sshd.8 | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/ssh.1 b/ssh.1 -index 697f4e42..db92ac9a 100644 ---- a/ssh.1 -+++ b/ssh.1 -@@ -1663,6 +1663,8 @@ manual page for more information. +diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1 +--- openssh-5.9p0/ssh.1.ipv6man 2011-08-05 22:17:32.000000000 +0200 ++++ openssh-5.9p0/ssh.1 2011-08-31 13:08:34.880024485 +0200 +@@ -1400,6 +1400,8 @@ manual page for more information. .Nm exits with the exit status of the remote command or with 255 if an error occurred. @@ -21,11 +10,10 @@ index 697f4e42..db92ac9a 100644 .Sh SEE ALSO .Xr scp 1 , .Xr sftp 1 , -diff --git a/sshd.8 b/sshd.8 -index 08ebf53a..2aa73271 100644 ---- a/sshd.8 -+++ b/sshd.8 -@@ -1018,6 +1018,8 @@ concurrently for different ports, this contains the process ID of the one +diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8 +--- openssh-5.9p0/sshd.8.ipv6man 2011-08-05 22:17:32.000000000 +0200 ++++ openssh-5.9p0/sshd.8 2011-08-31 13:10:34.129039094 +0200 +@@ -940,6 +940,8 @@ concurrently for different ports, this c started last). The content of this file is not sensitive; it can be world-readable. .El @@ -34,6 +22,3 @@ index 08ebf53a..2aa73271 100644 .Sh SEE ALSO .Xr scp 1 , .Xr sftp 1 , --- -2.49.0 - diff --git a/openssh-6.4p1-fromto-remote.patch b/openssh-6.4p1-fromto-remote.patch new file mode 100644 index 0000000..4a7d849 --- /dev/null +++ b/openssh-6.4p1-fromto-remote.patch @@ -0,0 +1,16 @@ +diff --git a/scp.c b/scp.c +index d98fa67..25d347b 100644 +--- a/scp.c ++++ b/scp.c +@@ -638,7 +638,10 @@ toremote(char *targ, int argc, char **argv) + addargs(&alist, "%s", ssh_program); + addargs(&alist, "-x"); + addargs(&alist, "-oClearAllForwardings=yes"); +- addargs(&alist, "-n"); ++ if (isatty(fileno(stdin))) ++ addargs(&alist, "-t"); ++ else ++ addargs(&alist, "-n"); + for (j = 0; j < remote_remote_args.num; j++) { + addargs(&alist, "%s", + remote_remote_args.list[j]); diff --git a/0019-openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch similarity index 54% rename from 0019-openssh-6.6.1p1-log-in-chroot.patch rename to openssh-6.6.1p1-log-in-chroot.patch index 3b30f98..0f65279 100644 --- a/0019-openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -1,25 +1,7 @@ -From 825018f5f2d892655f3d63167a0d1f3391cec678 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 19/50] openssh-6.6.1p1-log-in-chroot - ---- - log.c | 11 +++++++++-- - log.h | 1 + - monitor.c | 17 +++++++++++++++-- - monitor.h | 2 +- - session.c | 26 +++++++++++++++----------- - sftp-server-main.c | 2 +- - sftp-server.c | 6 +++--- - sftp.h | 2 +- - sshd-session.c | 7 ++++++- - 9 files changed, 52 insertions(+), 22 deletions(-) - -diff --git a/log.c b/log.c -index 6617f267..9782cfb0 100644 ---- a/log.c -+++ b/log.c -@@ -196,6 +196,11 @@ void +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 +@@ -194,6 +194,11 @@ void log_init(const char *av0, LogLevel level, SyslogFacility facility, int on_stderr) { @@ -31,7 +13,7 @@ index 6617f267..9782cfb0 100644 #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif -@@ -208,8 +213,10 @@ log_init(const char *av0, LogLevel level, SyslogFacility facility, +@@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level exit(1); } @@ -44,10 +26,9 @@ index 6617f267..9782cfb0 100644 log_on_stderr = on_stderr; if (on_stderr) -diff --git a/log.h b/log.h -index 8e8dfc23..70048a8a 100644 ---- a/log.h -+++ b/log.h +diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h +--- openssh-8.6p1/log.h.log-in-chroot 2021-04-19 14:43:08.544843434 +0200 ++++ openssh-8.6p1/log.h 2021-04-19 14:56:46.931042176 +0200 @@ -52,6 +52,7 @@ typedef enum { typedef void (log_handler_fn)(LogLevel, int, const char *, void *); @@ -56,11 +37,43 @@ index 8e8dfc23..70048a8a 100644 LogLevel log_level_get(void); int log_change_level(LogLevel); int log_is_on_stderr(void); -diff --git a/monitor.c b/monitor.c -index 2ef16cc8..43c10a4e 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -2001,9 +2001,22 @@ monitor_init(void) +diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.log-in-chroot 2021-04-19 14:43:08.526843298 +0200 ++++ openssh-8.6p1/monitor.c 2021-04-19 14:55:25.286424043 +0200 +@@ -297,6 +297,8 @@ monitor_child_preauth(struct ssh *ssh, s + close(pmonitor->m_log_sendfd); + pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; + ++ pmonitor->m_state = "preauth"; ++ + authctxt = (Authctxt *)ssh->authctxt; + memset(authctxt, 0, sizeof(*authctxt)); + ssh->authctxt = authctxt; +@@ -408,6 +410,8 @@ monitor_child_postauth(struct ssh *ssh, + close(pmonitor->m_recvfd); + pmonitor->m_recvfd = -1; + ++ pmonitor->m_state = "postauth"; ++ + monitor_set_child_handler(pmonitor->m_pid); + ssh_signal(SIGHUP, &monitor_child_handler); + ssh_signal(SIGTERM, &monitor_child_handler); +@@ -480,7 +484,7 @@ monitor_read_log(struct monitor *pmonito + /* Log it */ + if (log_level_name(level) == NULL) + fatal_f("invalid log level %u (corrupted message?)", level); +- sshlogdirect(level, forced, "%s [preauth]", msg); ++ sshlogdirect(level, forced, "%s [%s]", msg, pmonitor->m_state); + + sshbuf_free(logmsg); + free(msg); +@@ -1868,13 +1872,28 @@ monitor_init(void) + mon = xcalloc(1, sizeof(*mon)); + monitor_openfds(mon, 1); + ++ mon->m_state = ""; ++ + return mon; } void @@ -85,11 +98,14 @@ index 2ef16cc8..43c10a4e 100644 } #ifdef GSSAPI -diff --git a/monitor.h b/monitor.h -index dbc7e003..d4d631dd 100644 ---- a/monitor.h -+++ b/monitor.h -@@ -85,7 +85,7 @@ struct monitor { +diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h +--- openssh-8.6p1/monitor.h.log-in-chroot 2021-04-19 14:43:08.527843305 +0200 ++++ openssh-8.6p1/monitor.h 2021-04-19 14:43:08.545843441 +0200 +@@ -80,10 +80,11 @@ struct monitor { + int m_log_sendfd; + struct kex **m_pkex; + pid_t m_pid; ++ char *m_state; }; struct monitor *monitor_init(void); @@ -98,11 +114,10 @@ index dbc7e003..d4d631dd 100644 struct Authctxt; void monitor_child_preauth(struct ssh *, struct monitor *); -diff --git a/session.c b/session.c -index 2620dd11..54da09d5 100644 ---- a/session.c -+++ b/session.c -@@ -169,6 +169,7 @@ login_cap_t *lc; +diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.log-in-chroot 2021-04-19 14:43:08.534843358 +0200 ++++ openssh-8.6p1/session.c 2021-04-19 14:43:08.545843441 +0200 +@@ -160,6 +160,7 @@ login_cap_t *lc; static int is_child = 0; static int in_chroot = 0; @@ -110,7 +125,7 @@ index 2620dd11..54da09d5 100644 /* File containing userauth info, if ExposeAuthInfo set */ static char *auth_info_file = NULL; -@@ -670,6 +671,7 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con int ret; const char *forced = NULL, *tty = NULL; char session_type[1024]; @@ -118,7 +133,7 @@ index 2620dd11..54da09d5 100644 if (options.adm_forced_command) { original_command = command; -@@ -729,6 +731,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con tty += 5; } @@ -129,7 +144,7 @@ index 2620dd11..54da09d5 100644 verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", -@@ -1512,14 +1518,6 @@ child_close_fds(struct ssh *ssh) +@@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh) /* Stop directing logs to a high-numbered fd before we close it */ log_redirect_stderr_to(NULL); @@ -144,7 +159,7 @@ index 2620dd11..54da09d5 100644 } /* -@@ -1652,8 +1650,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co exit(1); } @@ -153,7 +168,7 @@ index 2620dd11..54da09d5 100644 do_rc_files(ssh, s, shell); /* restore SIGPIPE for child */ -@@ -1678,9 +1674,17 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -172,31 +187,29 @@ index 2620dd11..54da09d5 100644 fflush(NULL); /* Get the last component of the shell name. */ -diff --git a/sftp-server-main.c b/sftp-server-main.c -index 2c70f89b..bbb79f27 100644 ---- a/sftp-server-main.c -+++ b/sftp-server-main.c -@@ -48,5 +48,5 @@ main(int argc, char **argv) - return 1; - } +diff -up openssh-8.6p1/sftp.h.log-in-chroot openssh-8.6p1/sftp.h +--- openssh-8.6p1/sftp.h.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp.h 2021-04-19 14:43:08.545843441 +0200 +@@ -97,5 +97,5 @@ -- return (sftp_server_main(argc, argv, user_pw)); -+ return (sftp_server_main(argc, argv, user_pw, 0)); - } -diff --git a/sftp-server.c b/sftp-server.c -index a4abb9f7..4985da38 100644 ---- a/sftp-server.c -+++ b/sftp-server.c -@@ -1901,7 +1901,7 @@ sftp_server_usage(void) + struct passwd; + +-int sftp_server_main(int, char **, struct passwd *); ++int sftp_server_main(int, char **, struct passwd *, int); + void sftp_server_cleanup_exit(int) __attribute__((noreturn)); +diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c +--- openssh-8.6p1/sftp-server.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-server.c 2021-04-19 14:43:08.545843441 +0200 +@@ -1644,7 +1644,7 @@ sftp_server_usage(void) } int -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) { - int i, r, in, out, ch, skipargs = 0, log_stderr = 0; - ssize_t len, olen; -@@ -1913,7 +1913,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) + 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; __progname = ssh_get_progname(argv[0]); @@ -205,7 +218,7 @@ index a4abb9f7..4985da38 100644 pw = pwcopy(user_pw); -@@ -1986,7 +1986,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) +@@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv, } } @@ -214,22 +227,20 @@ index a4abb9f7..4985da38 100644 /* * On platforms where we can, avoid making /proc/self/{mem,maps} -diff --git a/sftp.h b/sftp.h -index 2bde8bb7..ddf1a396 100644 ---- a/sftp.h -+++ b/sftp.h -@@ -97,5 +97,5 @@ +diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-server-main.c +--- openssh-8.6p1/sftp-server-main.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-server-main.c 2021-04-19 14:43:08.545843441 +0200 +@@ -50,5 +50,5 @@ main(int argc, char **argv) + return 1; + } - struct passwd; - --int sftp_server_main(int, char **, struct passwd *); -+int sftp_server_main(int, char **, struct passwd *, int); - void sftp_server_cleanup_exit(int) __attribute__((noreturn)); -diff --git a/sshd-session.c b/sshd-session.c -index 478381db..9342e416 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -437,7 +437,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +- return (sftp_server_main(argc, argv, user_pw)); ++ return (sftp_server_main(argc, argv, user_pw, 0)); + } +diff -up openssh-8.6p1/sshd-session.c.log-in-chroot openssh-8.6p1/sshd-session.c +--- openssh-8.6p1/sshd-session.c.log-in-chroot 2021-04-19 14:43:08.543843426 +0200 ++++ openssh-8.6p1/sshd-session.c 2021-04-19 14:43:08.545843441 +0200 +@@ -559,7 +559,7 @@ privsep_postauth(struct ssh *ssh, Authct #endif /* New socket pair */ @@ -238,7 +249,7 @@ index 478381db..9342e416 100644 pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) -@@ -456,6 +456,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; @@ -250,6 +261,3 @@ index 478381db..9342e416 100644 /* Demote the private keys to public keys. */ demote_sensitive_data(); --- -2.49.0 - diff --git a/openssh-6.6.1p1-scp-non-existing-directory.patch b/openssh-6.6.1p1-scp-non-existing-directory.patch new file mode 100644 index 0000000..bb55c0b --- /dev/null +++ b/openssh-6.6.1p1-scp-non-existing-directory.patch @@ -0,0 +1,14 @@ +--- a/scp.c ++++ a/scp.c +@@ -1084,6 +1084,10 @@ sink(int argc, char **argv) + free(vect[0]); + continue; + } ++ if (buf[0] == 'C' && ! exists && np[strlen(np)-1] == '/') { ++ errno = ENOTDIR; ++ goto bad; ++ } + omode = mode; + mode |= S_IWUSR; + if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { +-- diff --git a/0018-openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch similarity index 73% rename from 0018-openssh-6.6.1p1-selinux-contexts.patch rename to openssh-6.6.1p1-selinux-contexts.patch index 49f2119..96161cb 100644 --- a/0018-openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -1,20 +1,8 @@ -From 6481ac7fbd0027a7038560e0f51dd0af056cc229 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 18/50] openssh-6.6.1p1-selinux-contexts - ---- - openbsd-compat/port-linux-sshd.c | 69 +++++++++++++++++++++++++++++++- - openbsd-compat/port-linux.c | 2 +- - openbsd-compat/port-linux.h | 1 + - sshd-auth.c | 2 +- - 4 files changed, 71 insertions(+), 3 deletions(-) - diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index 8c5fc1fe..646f0887 100644 +index 8f32464..18a2ca4 100644 --- a/openbsd-compat/port-linux-sshd.c +++ b/openbsd-compat/port-linux-sshd.c -@@ -33,6 +33,7 @@ +@@ -32,6 +32,7 @@ #include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ #include "servconf.h" #include "port-linux.h" @@ -22,7 +10,7 @@ index 8c5fc1fe..646f0887 100644 #include "sshkey.h" #include "hostfile.h" #include "auth.h" -@@ -450,7 +451,7 @@ sshd_selinux_setup_exec_context(char *pwname) +@@ -445,7 +446,7 @@ sshd_selinux_setup_exec_context(char *pwname) void sshd_selinux_copy_context(void) { @@ -31,7 +19,7 @@ index 8c5fc1fe..646f0887 100644 if (!sshd_selinux_enabled()) return; -@@ -469,6 +470,72 @@ sshd_selinux_copy_context(void) +@@ -461,6 +462,72 @@ sshd_selinux_copy_context(void) } } @@ -105,23 +93,22 @@ index 8c5fc1fe..646f0887 100644 #endif diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 7426f6f7..9a6b1d6e 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -188,7 +188,7 @@ ssh_selinux_change_context(const char *newname) +--- a/openbsd-compat/port-linux.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/openbsd-compat/port-linux.c (date 1703108053912) +@@ -207,7 +207,7 @@ xasprintf(&newctx, "%.*s%s%s", (int)(cx - oldctx + 1), oldctx, newname, cx2 == NULL ? "" : cx2); - + - debug3_f("setting context from '%s' to '%s'", oldctx, newctx); + debug_f("setting context from '%s' to '%s'", oldctx, newctx); if (setcon(newctx) < 0) do_log2_f(log_level, "setcon %s from %s failed with %s", newctx, oldctx, strerror(errno)); diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index 1b745a76..7f8ba200 100644 +index cb51f99..8b7cda2 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h -@@ -27,6 +27,7 @@ int sshd_selinux_enabled(void); +@@ -29,6 +29,7 @@ int sshd_selinux_enabled(void); void sshd_selinux_copy_context(void); void sshd_selinux_setup_exec_context(char *); int sshd_selinux_setup_env_variables(void); @@ -129,19 +116,16 @@ index 1b745a76..7f8ba200 100644 #endif #ifdef LINUX_OOM_ADJUST -diff --git a/sshd-auth.c b/sshd-auth.c -index d51e4636..e4a8edfd 100644 ---- a/sshd-auth.c -+++ b/sshd-auth.c -@@ -188,7 +188,7 @@ privsep_child_demote(void) - fatal_f("ssh_sandbox_init failed"); - #endif +diff --git a/sshd-session.c b/sshd-session.c +index 2871fe9..39b9c08 100644 +--- a/sshd-session.c ++++ b/sshd-session.c +@@ -629,7 +629,7 @@ privsep_preauth_child(void) + demote_sensitive_data(); + #ifdef WITH_SELINUX - ssh_selinux_change_context("sshd_net_t"); + sshd_selinux_change_privsep_preauth_context(); #endif /* Demote the child */ --- -2.49.0 - diff --git a/0021-openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch similarity index 61% rename from 0021-openssh-6.6p1-GSSAPIEnablek5users.patch rename to openssh-6.6p1-GSSAPIEnablek5users.patch index eeff02a..7fef831 100644 --- a/0021-openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -1,21 +1,7 @@ -From 9c75c175e3555377328fc5fc9b06e94f129b7cd7 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 21/50] openssh-6.6p1-GSSAPIEnablek5users - ---- - gss-serv-krb5.c | 3 +-- - servconf.c | 13 ++++++++++++- - servconf.h | 1 + - sshd_config | 1 + - sshd_config.5 | 6 ++++++ - 5 files changed, 21 insertions(+), 3 deletions(-) - -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 187faf92..03188d9b 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -278,7 +278,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, +diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-serv-krb5.c +--- openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100 ++++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 15:18:40.628216102 +0100 +@@ -279,7 +279,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri FILE *fp; char file[MAXPATHLEN]; char *line = NULL; @@ -23,7 +9,7 @@ index 187faf92..03188d9b 100644 struct stat st; struct passwd *pw = the_authctxt->pw; int found_principal = 0; -@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, +@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); /* If both .k5login and .k5users DNE, self-login is ok. */ @@ -32,19 +18,18 @@ index 187faf92..03188d9b 100644 return ssh_krb5_kuserok(krb_context, principal, luser, k5login_exists); } -diff --git a/servconf.c b/servconf.c -index 5dd5ca21..c0de7110 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -146,6 +146,7 @@ initialize_server_options(ServerOptions *options) +diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100 ++++ openssh-7.4p1/servconf.c 2016-12-23 15:35:36.354401156 +0100 +@@ -168,6 +168,7 @@ initialize_server_options(ServerOptions options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; + options->enable_k5users = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->permit_empty_passwd = -1; -@@ -402,6 +403,8 @@ fill_default_server_options(ServerOptions *options) + options->permit_empty_passwd = -1; +@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption #endif if (options->use_kuserok == -1) options->use_kuserok = 1; @@ -53,7 +38,7 @@ index 5dd5ca21..c0de7110 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -585,7 +588,7 @@ typedef enum { +@@ -578,7 +578,7 @@ typedef enum { sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -62,7 +47,7 @@ index 5dd5ca21..c0de7110 100644 sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, -@@ -681,6 +684,7 @@ static struct { +@@ -600,14 +600,16 @@ static struct { { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, @@ -70,7 +55,8 @@ index 5dd5ca21..c0de7110 100644 #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -689,6 +693,7 @@ static struct { + { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, @@ -78,7 +64,7 @@ index 5dd5ca21..c0de7110 100644 #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -2450,6 +2455,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1653,6 +1658,10 @@ process_server_config_line(ServerOptions intptr = &options->use_kuserok; goto parse_flag; @@ -86,10 +72,10 @@ index 5dd5ca21..c0de7110 100644 + intptr = &options->enable_k5users; + goto parse_flag; + - case sMatch: - if (cmdline) - fatal("Match directive not supported as a command-line " -@@ -3005,6 +3014,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " +@@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(use_kuserok); @@ -97,7 +83,7 @@ index 5dd5ca21..c0de7110 100644 M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); -@@ -3314,6 +3324,7 @@ dump_config(ServerOptions *o) +@@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o) # endif dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); @@ -105,35 +91,21 @@ index 5dd5ca21..c0de7110 100644 #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff --git a/servconf.h b/servconf.h -index 11de36a2..c08cf6a7 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -152,6 +152,7 @@ typedef struct { - int kerberos_unique_ccache; /* If true, the acquired ticket will - * be stored in per-session ccache */ +diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100 ++++ openssh-7.4p1/servconf.h 2016-12-23 15:18:40.629216102 +0100 +@@ -174,6 +174,7 @@ typedef struct { + int kerberos_unique_ccache; /* If true, the acquired ticket will + * be stored in per-session ccache */ int use_kuserok; + int enable_k5users; int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff --git a/sshd_config b/sshd_config -index ea5a878e..33713c88 100644 ---- a/sshd_config -+++ b/sshd_config -@@ -82,6 +82,7 @@ AuthorizedKeysFile .ssh/authorized_keys - #GSSAPICleanupCredentials yes - #GSSAPIStrictAcceptorCheck yes - #GSSAPIKeyExchange no -+#GSSAPIEnablek5users no - - # 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 0fcb409a..fe246fc2 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -739,6 +739,12 @@ Specifies whether to automatically destroy the user's credentials cache +diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users 2016-12-23 15:18:40.630216103 +0100 ++++ openssh-7.4p1/sshd_config.5 2016-12-23 15:36:21.607408435 +0100 +@@ -628,6 +628,12 @@ Specifies whether to automatically destr on logout. The default is .Cm yes . @@ -146,6 +118,17 @@ index 0fcb409a..fe246fc2 100644 .It Cm GSSAPIKeyExchange Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. --- -2.49.0 - +diff -up openssh-7.4p1/sshd_config.GSSAPIEnablek5users openssh-7.4p1/sshd_config +--- openssh-7.4p1/sshd_config.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100 ++++ openssh-7.4p1/sshd_config 2016-12-23 15:18:40.631216103 +0100 +@@ -80,6 +80,7 @@ GSSAPIAuthentication yes + #GSSAPICleanupCredentials yes + #GSSAPIStrictAcceptorCheck yes + #GSSAPIKeyExchange no ++#GSSAPIEnablek5users no + + # Set this to 'yes' to enable PAM authentication, account processing, + # and session processing. If this is enabled, PAM authentication will +diff -up openssh-9.8p1/servconf.c.xxx openssh-9.8p1/servconf.c +--- openssh-9.8p1/servconf.c.xxx 2024-07-11 13:51:19.969960781 +0200 ++++ openssh-9.8p1/servconf.c 2024-07-11 13:51:30.938231250 +0200 diff --git a/0004-openssh-6.6p1-allow-ip-opts.patch b/openssh-6.6p1-allow-ip-opts.patch similarity index 68% rename from 0004-openssh-6.6p1-allow-ip-opts.patch rename to openssh-6.6p1-allow-ip-opts.patch index ef15fbf..995e04e 100644 --- a/0004-openssh-6.6p1-allow-ip-opts.patch +++ b/openssh-6.6p1-allow-ip-opts.patch @@ -1,17 +1,7 @@ -From 28333f1dfe68b0ffc80c2a4799759587b4c32d3e Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 04/50] openssh-6.6p1-allow-ip-opts - ---- - sshd-session.c | 32 ++++++++++++++++++++++++++------ - 1 file changed, 26 insertions(+), 6 deletions(-) - -diff --git a/sshd-session.c b/sshd-session.c -index 4a148db4..a365f26f 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -778,12 +778,32 @@ check_ip_options(struct ssh *ssh) +diff -up openssh/sshd.c.ip-opts openssh/sshd.c +--- openssh/sshd-session.c.ip-opts 2016-07-25 13:58:48.998507834 +0200 ++++ openssh/sshd-session.c 2016-07-25 14:01:28.346469878 +0200 +@@ -1507,12 +1507,32 @@ check_ip_options(struct ssh *ssh) if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, &option_size) >= 0 && option_size != 0) { @@ -50,6 +40,3 @@ index 4a148db4..a365f26f 100644 } #endif /* IP_OPTIONS */ } --- -2.49.0 - diff --git a/0013-openssh-6.6p1-force_krb.patch b/openssh-6.6p1-force_krb.patch similarity index 88% rename from 0013-openssh-6.6p1-force_krb.patch rename to openssh-6.6p1-force_krb.patch index 74643b5..90f8322 100644 --- a/0013-openssh-6.6p1-force_krb.patch +++ b/openssh-6.6p1-force_krb.patch @@ -1,17 +1,5 @@ -From f5e5ee321def2a3674600714ad98fd1ca9b2cff1 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 13/50] openssh-6.6p1-force_krb - ---- - gss-serv-krb5.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++- - session.c | 23 +++++++ - ssh-gss.h | 4 ++ - sshd.8 | 7 +++ - 4 files changed, 189 insertions(+), 1 deletion(-) - diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 8d2b677f..14502c5a 100644 +index 413b845..54dd383 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -32,7 +32,9 @@ @@ -24,7 +12,7 @@ index 8d2b677f..14502c5a 100644 #include "xmalloc.h" #include "sshkey.h" -@@ -44,6 +46,7 @@ +@@ -45,6 +47,7 @@ #include "ssh-gss.h" @@ -32,7 +20,7 @@ index 8d2b677f..14502c5a 100644 extern ServerOptions options; #ifdef HEIMDAL -@@ -55,6 +58,13 @@ extern ServerOptions options; +@@ -56,6 +59,13 @@ extern ServerOptions options; # include #endif @@ -46,7 +34,7 @@ index 8d2b677f..14502c5a 100644 static krb5_context krb_context = NULL; /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -87,6 +97,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +@@ -88,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) krb5_principal princ; int retval; const char *errmsg; @@ -54,7 +42,7 @@ index 8d2b677f..14502c5a 100644 if (ssh_gssapi_krb5_init() == 0) return 0; -@@ -98,10 +109,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +@@ -99,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) krb5_free_error_message(krb_context, errmsg); return 0; } @@ -78,7 +66,7 @@ index 8d2b677f..14502c5a 100644 } else retval = 0; -@@ -109,6 +132,137 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +@@ -110,6 +133,137 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) return retval; } @@ -217,10 +205,10 @@ index 8d2b677f..14502c5a 100644 /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ diff --git a/session.c b/session.c -index cbfbcee8..89b3a9cf 100644 +index 28659ec..9c94d8e 100644 --- a/session.c +++ b/session.c -@@ -680,6 +680,29 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -789,6 +789,29 @@ do_exec(Session *s, const char *command) command = auth_opts->force_command; forced = "(key-option)"; } @@ -251,7 +239,7 @@ index cbfbcee8..89b3a9cf 100644 if (forced != NULL) { s->forced = 1; diff --git a/ssh-gss.h b/ssh-gss.h -index 8ec45192..db34d77f 100644 +index 0374c88..509109a 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -49,6 +49,10 @@ @@ -266,10 +254,10 @@ index 8ec45192..db34d77f 100644 /* draft-ietf-secsh-gsskeyex-06 */ diff --git a/sshd.8 b/sshd.8 -index 2aa73271..049d0a94 100644 +index adcaaf9..824163b 100644 --- a/sshd.8 +++ b/sshd.8 -@@ -286,6 +286,7 @@ Finally, the server and the client enter an authentication dialog. +@@ -324,6 +324,7 @@ Finally, the server and the client enter an authentication dialog. The client tries to authenticate itself using host-based authentication, public key authentication, @@ -277,7 +265,7 @@ index 2aa73271..049d0a94 100644 challenge-response authentication, or password authentication. .Pp -@@ -874,6 +875,12 @@ This file is used in exactly the same way as +@@ -800,6 +801,12 @@ This file is used in exactly the same way as but allows host-based authentication without permitting login with rlogin/rsh. .Pp @@ -290,6 +278,3 @@ index 2aa73271..049d0a94 100644 .It Pa ~/.ssh/ This directory is the default location for all user-specific configuration and authentication information. --- -2.49.0 - diff --git a/0003-openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch similarity index 77% rename from 0003-openssh-6.6p1-keycat.patch rename to openssh-6.6p1-keycat.patch index b46b378..4eb0998 100644 --- a/0003-openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,129 +1,7 @@ -From 5e35e18a419a5a66b6e1cb2b98beaaf4d9db0dc6 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 03/50] openssh-6.6p1-keycat - ---- - HOWTO.ssh-keycat | 12 ++ - Makefile.in | 8 +- - configure.ac | 6 + - misc.c | 7 + - openbsd-compat/port-linux-sshd.c | 44 +++++- - openbsd-compat/port-linux.h | 2 + - platform.c | 2 +- - ssh-keycat.c | 241 +++++++++++++++++++++++++++++++ - 8 files changed, 314 insertions(+), 8 deletions(-) - create mode 100644 HOWTO.ssh-keycat - create mode 100644 ssh-keycat.c - -diff --git a/HOWTO.ssh-keycat b/HOWTO.ssh-keycat -new file mode 100644 -index 00000000..630ec628 ---- /dev/null -+++ b/HOWTO.ssh-keycat -@@ -0,0 +1,12 @@ -+The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys -+of an user in any environment. This includes environments with -+polyinstantiation of home directories and SELinux MLS policy enabled. -+ -+To use ssh-keycat, set these options in /etc/ssh/sshd_config file: -+ AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat -+ AuthorizedKeysCommandUser root -+ -+Do not forget to enable public key authentication: -+ PubkeyAuthentication yes -+ -+ -diff --git a/Makefile.in b/Makefile.in -index 4617cebc..438efc51 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -23,6 +23,7 @@ SSH_PROGRAM=@bindir@/ssh - ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass - SFTP_SERVER=$(libexecdir)/sftp-server - SSH_KEYSIGN=$(libexecdir)/ssh-keysign -+SSH_KEYCAT=$(libexecdir)/ssh-keycat - SSHD_SESSION=$(libexecdir)/sshd-session - SSHD_AUTH=$(libexecdir)/sshd-auth - SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper -@@ -57,6 +58,7 @@ CHANNELLIBS=@CHANNELLIBS@ - K5LIBS=@K5LIBS@ - GSSLIBS=@GSSLIBS@ - SSHDLIBS=@SSHDLIBS@ -+KEYCATLIBS=@KEYCATLIBS@ - LIBEDIT=@LIBEDIT@ - LIBFIDO2=@LIBFIDO2@ - LIBWTMPDB=@LIBWTMPDB@ -@@ -74,7 +76,7 @@ MKDIR_P=@MKDIR_P@ - - .SUFFIXES: .lo - --TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE) -+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) $(SK_STANDALONE) - - XMSS_OBJS=\ - ssh-xmss.o \ -@@ -260,6 +262,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS) - ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) - $(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) -+ - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) - $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS) - -@@ -447,6 +452,7 @@ install-files: - $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) -+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) - $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -diff --git a/configure.ac b/configure.ac -index ee77a048..d546788c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3566,6 +3566,7 @@ AC_ARG_WITH([pam], - PAM_MSG="yes" - - SSHDLIBS="$SSHDLIBS -lpam" -+ KEYCATLIBS="$KEYCATLIBS -lpam" - AC_DEFINE([USE_PAM], [1], - [Define if you want to enable PAM support]) - -@@ -3576,6 +3577,7 @@ AC_ARG_WITH([pam], - ;; - *) - SSHDLIBS="$SSHDLIBS -ldl" -+ KEYCATLIBS="$KEYCATLIBS -ldl" - ;; - esac - fi -@@ -4801,6 +4803,7 @@ AC_ARG_WITH([selinux], - fi ] - ) - AC_SUBST([SSHDLIBS]) -+AC_SUBST([KEYCATLIBS]) - - # Check whether user wants Kerberos 5 support - KRB5_MSG="no" -@@ -5812,6 +5815,9 @@ fi - if test ! -z "${SSHDLIBS}"; then - echo " +for sshd: ${SSHDLIBS}" - fi -+if test ! -z "${KEYCATLIBS}"; then -+echo " +for ssh-keycat: ${KEYCATLIBS}" -+fi - - echo "" - -diff --git a/misc.c b/misc.c -index c932f9bb..1e31acc9 100644 ---- a/misc.c -+++ b/misc.c -@@ -2897,6 +2897,13 @@ subprocess(const char *tag, const char *command, +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 +@@ -966,6 +966,13 @@ subprocess(const char *tag, struct passw error("%s: dup2: %s", tag, strerror(errno)); _exit(1); } @@ -137,11 +15,86 @@ index c932f9bb..1e31acc9 100644 if (env != NULL) execve(av[0], av, env); else -diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index dfafc622..8c5fc1fe 100644 ---- a/openbsd-compat/port-linux-sshd.c -+++ b/openbsd-compat/port-linux-sshd.c -@@ -52,6 +52,20 @@ extern ServerOptions options; +diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat +--- openssh/HOWTO.ssh-keycat.keycat 2015-06-24 10:57:50.157849608 +0200 ++++ openssh/HOWTO.ssh-keycat 2015-06-24 10:57:50.157849608 +0200 +@@ -0,0 +1,12 @@ ++The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys ++of an user in any environment. This includes environments with ++polyinstantiation of home directories and SELinux MLS policy enabled. ++ ++To use ssh-keycat, set these options in /etc/ssh/sshd_config file: ++ AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat ++ AuthorizedKeysCommandUser root ++ ++Do not forget to enable public key authentication: ++ PubkeyAuthentication yes ++ ++ +diff -up openssh/Makefile.in.keycat openssh/Makefile.in +--- openssh/Makefile.in.keycat 2015-06-24 10:57:50.152849621 +0200 ++++ openssh/Makefile.in 2015-06-24 10:57:50.157849608 +0200 +@@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server + ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass + SFTP_SERVER=$(libexecdir)/sftp-server + SSH_KEYSIGN=$(libexecdir)/ssh-keysign ++SSH_KEYCAT=$(libexecdir)/ssh-keycat + SSHD_SESSION=$(libexecdir)/sshd-session + SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper + SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper +@@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@ + K5LIBS=@K5LIBS@ + GSSLIBS=@GSSLIBS@ + SSHDLIBS=@SSHDLIBS@ ++KEYCATLIBS=@KEYCATLIBS@ + LIBEDIT=@LIBEDIT@ + LIBFIDO2=@LIBFIDO2@ + AR=@AR@ +@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ + + .SUFFIXES: .lo + +-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) + + XMSS_OBJS=\ + 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) $(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) ++ + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) + $(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) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) ++ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) + $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 +diff -up openssh/openbsd-compat/port-linux.h.keycat openssh/openbsd-compat/port-linux.h +--- openssh/openbsd-compat/port-linux.h.keycat 2015-06-24 10:57:50.150849626 +0200 ++++ openssh/openbsd-compat/port-linux.h 2015-06-24 10:57:50.160849601 +0200 +@@ -25,8 +25,10 @@ void ssh_selinux_setup_pty(char *, const + void ssh_selinux_change_context(const char *); + void ssh_selinux_setfscreatecon(const char *); + ++int sshd_selinux_enabled(void); + void sshd_selinux_copy_context(void); + void sshd_selinux_setup_exec_context(char *); ++int sshd_selinux_setup_env_variables(void); + #endif + + #ifdef LINUX_OOM_ADJUST +diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/port-linux-sshd.c +--- openssh/openbsd-compat/port-linux-sshd.c.keycat 2015-06-24 10:57:50.150849626 +0200 ++++ openssh/openbsd-compat/port-linux-sshd.c 2015-06-24 10:57:50.159849603 +0200 +@@ -54,6 +54,20 @@ extern Authctxt *the_authctxt; extern Authctxt *the_authctxt; extern int inetd_flag; @@ -162,7 +115,7 @@ index dfafc622..8c5fc1fe 100644 /* Send audit message */ static int sshd_selinux_send_audit_message(int success, security_context_t default_context, -@@ -317,7 +331,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -308,7 +322,7 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int @@ -171,7 +124,7 @@ index dfafc622..8c5fc1fe 100644 { const char *reqlvl; char *role; -@@ -328,16 +342,16 @@ sshd_selinux_setup_pam_variables(void) +@@ -319,16 +333,16 @@ sshd_selinux_setup_pam_variables(void) ssh_selinux_get_role_level(&role, &reqlvl); @@ -191,7 +144,7 @@ index dfafc622..8c5fc1fe 100644 if (role != NULL) free(role); -@@ -345,6 +359,24 @@ sshd_selinux_setup_pam_variables(void) +@@ -336,6 +350,24 @@ sshd_selinux_setup_pam_variables(void) return rv; } @@ -216,7 +169,7 @@ index dfafc622..8c5fc1fe 100644 /* Set the execution context to the default for the specified user */ void sshd_selinux_setup_exec_context(char *pwname) -@@ -353,7 +385,7 @@ sshd_selinux_setup_exec_context(char *pwname) +@@ -344,7 +376,7 @@ sshd_selinux_setup_exec_context(char *pw int r = 0; security_context_t default_ctx = NULL; @@ -225,7 +178,7 @@ index dfafc622..8c5fc1fe 100644 return; if (options.use_pam) { -@@ -420,7 +452,7 @@ sshd_selinux_copy_context(void) +@@ -415,7 +447,7 @@ sshd_selinux_copy_context(void) { security_context_t *ctx; @@ -234,26 +187,10 @@ index dfafc622..8c5fc1fe 100644 return; if (getexeccon((security_context_t *)&ctx) != 0) { -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index 498d242a..1b745a76 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -23,8 +23,10 @@ void ssh_selinux_setup_pty(char *, const char *); - void ssh_selinux_change_context(const char *); - void ssh_selinux_setfscreatecon(const char *); - -+int sshd_selinux_enabled(void); - void sshd_selinux_copy_context(void); - void sshd_selinux_setup_exec_context(char *); -+int sshd_selinux_setup_env_variables(void); - #endif - - #ifdef LINUX_OOM_ADJUST -diff --git a/platform.c b/platform.c -index 1bfb4bea..0d12f311 100644 ---- a/platform.c -+++ b/platform.c -@@ -55,7 +55,7 @@ platform_setusercontext(struct passwd *pw) +diff -up openssh/platform.c.keycat openssh/platform.c +--- openssh/platform.c.keycat 2015-06-24 10:57:50.147849633 +0200 ++++ openssh/platform.c 2015-06-24 10:57:50.160849601 +0200 +@@ -103,7 +103,7 @@ platform_setusercontext(struct passwd *p { #ifdef WITH_SELINUX /* Cache selinux status for later use */ @@ -262,11 +199,9 @@ index 1bfb4bea..0d12f311 100644 #endif #ifdef USE_SOLARIS_PROJECTS -diff --git a/ssh-keycat.c b/ssh-keycat.c -new file mode 100644 -index 00000000..5678be07 ---- /dev/null -+++ b/ssh-keycat.c +diff -up openssh/ssh-keycat.c.keycat openssh/ssh-keycat.c +--- openssh/ssh-keycat.c.keycat 2015-06-24 10:57:50.161849599 +0200 ++++ openssh/ssh-keycat.c 2015-06-24 10:57:50.161849599 +0200 @@ -0,0 +1,241 @@ +/* + * Redistribution and use in source and binary forms, with or without @@ -509,6 +444,41 @@ index 00000000..5678be07 + } + return ev; +} --- -2.49.0 - +diff --git a/configure.ac b/configure.ac +index 3bbccfd..6481f1f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2952,6 +2952,7 @@ AC_ARG_WITH([pam], + PAM_MSG="yes" + + SSHDLIBS="$SSHDLIBS -lpam" ++ KEYCATLIBS="$KEYCATLIBS -lpam" + AC_DEFINE([USE_PAM], [1], + [Define if you want to enable PAM support]) + +@@ -3105,6 +3106,7 @@ + ;; + *) + SSHDLIBS="$SSHDLIBS -ldl" ++ KEYCATLIBS="$KEYCATLIBS -ldl" + ;; + esac + fi +@@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux], + fi ] + ) + AC_SUBST([SSHDLIBS]) ++AC_SUBST([KEYCATLIBS]) + + # Check whether user wants Kerberos 5 support + KRB5_MSG="no" +@@ -5031,6 +5034,9 @@ fi + if test ! -z "${SSHDLIBS}"; then + echo " +for sshd: ${SSHDLIBS}" + fi ++if test ! -z "${KEYCATLIBS}"; then ++echo " +for ssh-keycat: ${KEYCATLIBS}" ++fi + + echo "" + diff --git a/0016-openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch similarity index 80% rename from 0016-openssh-6.6p1-kuserok.patch rename to openssh-6.6p1-kuserok.patch index 3724b8d..e43128b 100644 --- a/0016-openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -1,22 +1,7 @@ -From bac7a9d1a654c8c2e0c71f979195e300b25d6232 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 16/50] openssh-6.6p1-kuserok - ---- - auth-krb5.c | 20 ++++++++- - gss-serv-krb5.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++-- - servconf.c | 13 +++++- - servconf.h | 1 + - sshd_config | 1 + - sshd_config.5 | 5 +++ - 6 files changed, 139 insertions(+), 7 deletions(-) - -diff --git a/auth-krb5.c b/auth-krb5.c -index 74f56d47..bae153c9 100644 ---- a/auth-krb5.c -+++ b/auth-krb5.c -@@ -55,6 +55,21 @@ +diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c +--- openssh-7.4p1/auth-krb5.c.kuserok 2016-12-23 14:36:07.640465939 +0100 ++++ openssh-7.4p1/auth-krb5.c 2016-12-23 14:36:07.644465936 +0100 +@@ -56,6 +56,21 @@ extern ServerOptions options; @@ -38,7 +23,7 @@ index 74f56d47..bae153c9 100644 static int krb5_init(void *context) { -@@ -158,8 +173,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -160,8 +175,9 @@ auth_krb5_password(Authctxt *authctxt, c if (problem) goto out; @@ -50,11 +35,10 @@ index 74f56d47..bae153c9 100644 problem = -1; goto out; } -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 820f794c..187faf92 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -66,6 +66,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, +diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c +--- openssh-7.4p1/gss-serv-krb5.c.kuserok 2016-12-23 14:36:07.640465939 +0100 ++++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 14:36:07.644465936 +0100 +@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr int); static krb5_context krb_context = NULL; @@ -62,7 +46,7 @@ index 820f794c..187faf92 100644 /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -91,6 +92,103 @@ ssh_gssapi_krb5_init(void) +@@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void) * Returns true if the user is OK to log in, otherwise returns 0 */ @@ -166,7 +150,7 @@ index 820f794c..187faf92 100644 static int ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) { -@@ -115,7 +213,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +@@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client /* NOTE: .k5login and .k5users must opened as root, not the user, * because if they are on a krb5-protected filesystem, user credentials * to access these files aren't available yet. */ @@ -176,7 +160,7 @@ index 820f794c..187faf92 100644 retval = 1; logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", name, (char *)client->displayname.value); -@@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, +@@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); /* If both .k5login and .k5users DNE, self-login is ok. */ if (!k5login_exists && (access(file, F_OK) == -1)) { @@ -188,19 +172,18 @@ index 820f794c..187faf92 100644 } if ((fp = fopen(file, "r")) == NULL) { int saved_errno = errno; -diff --git a/servconf.c b/servconf.c -index 55aa5bf0..5dd5ca21 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -145,6 +145,7 @@ initialize_server_options(ServerOptions *options) +diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c +--- openssh-7.4p1/servconf.c.kuserok 2016-12-23 14:36:07.630465944 +0100 ++++ openssh-7.4p1/servconf.c 2016-12-23 15:11:52.278133344 +0100 +@@ -116,6 +116,7 @@ initialize_server_options(ServerOptions options->gss_strict_acceptor = -1; options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; + options->use_kuserok = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->permit_empty_passwd = -1; -@@ -399,6 +400,8 @@ fill_default_server_options(ServerOptions *options) + options->permit_empty_passwd = -1; +@@ -278,6 +279,8 @@ fill_default_server_options(ServerOption if (options->gss_kex_algorithms == NULL) options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); #endif @@ -209,16 +192,16 @@ index 55aa5bf0..5dd5ca21 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -567,7 +570,7 @@ typedef enum { - sPort, sHostKeyFile, sLoginGraceTime, - sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +@@ -399,7 +402,7 @@ typedef enum { + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication, + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, - sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, -@@ -659,12 +662,14 @@ static struct { + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, +@@ -478,12 +481,14 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif { "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL }, @@ -233,18 +216,18 @@ index 55aa5bf0..5dd5ca21 100644 #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -2441,6 +2446,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, - } - break; - +@@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions + } + break; + + case sKerberosUseKuserok: + intptr = &options->use_kuserok; + goto parse_flag; + - case sMatch: - if (cmdline) - fatal("Match directive not supported as a command-line " -@@ -2995,6 +3004,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " +@@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(client_alive_interval); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); @@ -252,19 +235,18 @@ index 55aa5bf0..5dd5ca21 100644 M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); -@@ -3303,6 +3313,7 @@ dump_config(ServerOptions *o) +@@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); #endif #ifdef GSSAPI - dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff --git a/servconf.h b/servconf.h -index a4a38d6d..11de36a2 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -151,6 +151,7 @@ typedef struct { + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); +diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h +--- openssh-7.4p1/servconf.h.kuserok 2016-12-23 14:36:07.630465944 +0100 ++++ openssh-7.4p1/servconf.h 2016-12-23 14:36:07.645465936 +0100 +@@ -118,6 +118,7 @@ typedef struct { * authenticated with Kerberos. */ int kerberos_unique_ccache; /* If true, the acquired ticket will * be stored in per-session ccache */ @@ -272,23 +254,10 @@ index a4a38d6d..11de36a2 100644 int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff --git a/sshd_config b/sshd_config -index 8db9f0fb..ea5a878e 100644 ---- a/sshd_config -+++ b/sshd_config -@@ -75,6 +75,7 @@ AuthorizedKeysFile .ssh/authorized_keys - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok yes - - # GSSAPI options - #GSSAPIAuthentication no -diff --git a/sshd_config.5 b/sshd_config.5 -index 1251d4d5..0fcb409a 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -1041,6 +1041,10 @@ The default value +diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 +--- openssh-7.4p1/sshd_config.5.kuserok 2016-12-23 14:36:07.637465940 +0100 ++++ openssh-7.4p1/sshd_config.5 2016-12-23 15:14:03.117162222 +0100 +@@ -850,6 +850,10 @@ Specifies whether to automatically destr .Cm no can lead to overwriting previous tickets by subseqent connections to the same user account. @@ -299,7 +268,7 @@ index 1251d4d5..0fcb409a 100644 .It Cm KexAlgorithms Specifies the permitted KEX (Key Exchange) algorithms that the server will offer to clients. -@@ -1355,6 +1359,7 @@ Available keywords are +@@ -1078,6 +1082,7 @@ Available keywords are .Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , @@ -307,6 +276,14 @@ index 1251d4d5..0fcb409a 100644 .Cm LogLevel , .Cm MaxAuthTries , .Cm MaxSessions , --- -2.49.0 - +diff -up openssh-7.4p1/sshd_config.kuserok openssh-7.4p1/sshd_config +--- openssh-7.4p1/sshd_config.kuserok 2016-12-23 14:36:07.631465943 +0100 ++++ openssh-7.4p1/sshd_config 2016-12-23 14:36:07.646465935 +0100 +@@ -73,6 +73,7 @@ ChallengeResponseAuthentication no + #KerberosOrLocalPasswd yes + #KerberosTicketCleanup yes + #KerberosGetAFSToken no ++#KerberosUseKuserok yes + + # GSSAPI options + #GSSAPIAuthentication no diff --git a/0002-openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch similarity index 52% rename from 0002-openssh-6.6p1-privsep-selinux.patch rename to openssh-6.6p1-privsep-selinux.patch index 32d3c64..16d98cd 100644 --- a/0002-openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -1,21 +1,18 @@ -From 99d8e250514023d3b88a1c9eb724c4898aba9827 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 02/50] openssh-6.6p1-privsep-selinux - ---- - openbsd-compat/port-linux-sshd.c | 22 ++++++++++++++++++++++ - openbsd-compat/port-linux.h | 1 + - session.c | 16 +++++++++------- - sshd-auth.c | 4 ++++ - sshd-session.c | 2 +- - 5 files changed, 37 insertions(+), 8 deletions(-) - -diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index b9fbe38b..dfafc622 100644 ---- a/openbsd-compat/port-linux-sshd.c -+++ b/openbsd-compat/port-linux-sshd.c -@@ -415,6 +415,28 @@ sshd_selinux_setup_exec_context(char *pwname) +diff -up openssh-7.4p1/openbsd-compat/port-linux.h.privsep-selinux openssh-7.4p1/openbsd-compat/port-linux.h +--- openssh-7.4p1/openbsd-compat/port-linux.h.privsep-selinux 2016-12-23 18:58:52.972122201 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 18:58:52.974122201 +0100 +@@ -23,6 +23,7 @@ void ssh_selinux_setup_pty(char *, const + void ssh_selinux_change_context(const char *); + void ssh_selinux_setfscreatecon(const char *); + ++void sshd_selinux_copy_context(void); + void sshd_selinux_setup_exec_context(char *); + #endif + +diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh-7.4p1/openbsd-compat/port-linux-sshd.c +--- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux 2016-12-23 18:58:52.973122201 +0100 ++++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2016-12-23 18:58:52.974122201 +0100 +@@ -419,6 +419,28 @@ sshd_selinux_setup_exec_context(char *pw debug3_f("done"); } @@ -44,23 +41,10 @@ index b9fbe38b..dfafc622 100644 #endif #endif -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index 055c825e..498d242a 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -23,6 +23,7 @@ void ssh_selinux_setup_pty(char *, const char *); - void ssh_selinux_change_context(const char *); - void ssh_selinux_setfscreatecon(const char *); - -+void sshd_selinux_copy_context(void); - void sshd_selinux_setup_exec_context(char *); - #endif - -diff --git a/session.c b/session.c -index 6444c77f..e4657cef 100644 ---- a/session.c -+++ b/session.c -@@ -1350,7 +1350,7 @@ do_setusercontext(struct passwd *pw) +diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c +--- openssh-7.4p1/session.c.privsep-selinux 2016-12-19 05:59:41.000000000 +0100 ++++ openssh-7.4p1/session.c 2016-12-23 18:58:52.974122201 +0100 +@@ -1331,7 +1331,7 @@ do_setusercontext(struct passwd *pw) platform_setusercontext(pw); @@ -69,17 +53,17 @@ index 6444c77f..e4657cef 100644 #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { -@@ -1382,6 +1382,9 @@ do_setusercontext(struct passwd *pw) - (unsigned long long)pw->pw_uid); - chroot_path = percent_expand(tmp, "h", pw->pw_dir, - "u", pw->pw_name, "U", uidstr, (char *)NULL); +@@ -1361,6 +1361,9 @@ do_setusercontext(struct passwd *pw) + (unsigned long long)pw->pw_uid); + chroot_path = percent_expand(tmp, "h", pw->pw_dir, + "u", pw->pw_name, "U", uidstr, (char *)NULL); +#ifdef WITH_SELINUX + sshd_selinux_copy_context(); +#endif safely_chroot(chroot_path, pw->pw_uid); free(tmp); free(chroot_path); -@@ -1417,6 +1420,11 @@ do_setusercontext(struct passwd *pw) +@@ -1396,6 +1399,11 @@ do_setusercontext(struct passwd *pw) /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif @@ -91,17 +75,17 @@ index 6444c77f..e4657cef 100644 } else if (options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { fatal("server lacks privileges to chroot to ChrootDirectory"); -@@ -1434,9 +1442,6 @@ do_pwchange(Session *s) +@@ -1413,9 +1421,6 @@ do_pwchange(Session *s) if (s->ttyfd != -1) { fprintf(stderr, - "You must change your password now and log in again!\n"); + "You must change your password now and login again!\n"); -#ifdef WITH_SELINUX - setexeccon(NULL); -#endif #ifdef PASSWD_NEEDS_USERNAME execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name, (char *)NULL); -@@ -1649,9 +1654,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1625,9 +1630,6 @@ do_child(Session *s, const char *command argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -111,14 +95,13 @@ index 6444c77f..e4657cef 100644 exit(sftp_server_main(i, argv, s->pw)); } -diff --git a/sshd-auth.c b/sshd-auth.c -index 30eecd8a..f957dc22 100644 ---- a/sshd-auth.c -+++ b/sshd-auth.c -@@ -187,6 +187,10 @@ privsep_child_demote(void) - if ((box = ssh_sandbox_init(pmonitor)) == NULL) - fatal_f("ssh_sandbox_init failed"); - #endif +diff -up openssh-7.4p1/sshd.c.privsep-selinux openssh-7.4p1/sshd.c +--- openssh-7.4p1/sshd-session.c.privsep-selinux 2016-12-23 18:58:52.973122201 +0100 ++++ openssh-7.4p1/sshd-session.c 2016-12-23 18:59:13.808124269 +0100 +@@ -540,6 +540,10 @@ privsep_preauth_child(void) + /* Demote the private keys to public keys. */ + demote_sensitive_data(); + +#ifdef WITH_SELINUX + ssh_selinux_change_context("sshd_net_t"); +#endif @@ -126,11 +109,7 @@ index 30eecd8a..f957dc22 100644 /* Demote the child */ if (privsep_chroot) { /* Change our root directory */ -diff --git a/sshd-session.c b/sshd-session.c -index 74d2cbc7..4a148db4 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -432,7 +432,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -403,7 +403,7 @@ privsep_postauth(struct ssh *ssh, Authct * fd passing, as AFAIK PTY allocation on this platform doesn't require * special privileges to begin with. */ @@ -139,6 +118,3 @@ index 74d2cbc7..4a148db4 100644 skip_privdrop = 1; #endif --- -2.49.0 - diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch new file mode 100644 index 0000000..ffe0c69 --- /dev/null +++ b/openssh-6.7p1-coverity.patch @@ -0,0 +1,248 @@ +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, + umask(old_umask); + if (tmpfd == -1) { + logit("mkstemp(): %.100s", strerror(oerrno)); ++ free(ccname); + return oerrno; + } + +@@ -433,6 +434,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, + oerrno = errno; + logit("fchmod(): %.100s", strerror(oerrno)); + close(tmpfd); ++ free(ccname); + return oerrno; + } + /* make sure the KRB5CCNAME is set for non-standard location */ +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 + enclen = __b64_ntop(digest, + ssh_digest_bytes(SSH_DIGEST_MD5), encoded, + ssh_digest_bytes(SSH_DIGEST_MD5) * 2); +- ++#pragma GCC diagnostic ignored "-Wstringop-overflow" + cp = strncpy(s, kex, strlen(kex)); ++#pragma GCC diagnostic pop + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + if (sshbuf_len(buf) != 0 && +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 +@@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + 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 + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + 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 + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + 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, + */ + + /* Use strncpy because we don't necessarily want null termination */ ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut->ut_name, li->username, + MIN_SIZEOF(ut->ut_name, li->username)); + # ifdef HAVE_HOST_IN_UTMP ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut->ut_host, li->hostname, + MIN_SIZEOF(ut->ut_host, li->hostname)); + # endif +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) + } + if (nullfd > STDERR_FILENO) + close(nullfd); ++ /* coverity[leaked_handle : FALSE]*/ ++ /* coverity[leaked_handle : FALSE]*/ + } + + char * +@@ -2511,6 +2513,7 @@ stdfd_devnull(int do_stdin, int do_stdou + } + if (devnull > STDERR_FILENO) + close(devnull); ++ /* coverity[leaked_handle : FALSE]*/ + return ret; + } + +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 + mm_get_keystate(ssh, pmonitor); + + /* Drain any buffered messages from the child */ +- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) ++ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) + ; + + if (pmonitor->m_recvfd >= 0) +@@ -1678,7 +1678,7 @@ mm_answer_pty(struct ssh *ssh, int sock, + s->ptymaster = s->ptyfd; + + debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd); +- ++ /* coverity[leaked_handle : FALSE] */ + return (0); + + error: +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 + struct sockaddr_in6 *in6; + u_int16_t *portp; + u_int16_t port; +- socklen_t salen; ++ socklen_t salen = sizeof(struct sockaddr_storage); + 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 +@@ -113,13 +113,13 @@ pselect_notify_setup(void) + static void + pselect_notify_parent(void) + { +- if (notify_pipe[1] != -1) ++ if (notify_pipe[1] >= 0) + (void)write(notify_pipe[1], "", 1); + } + static void + pselect_notify_prepare(fd_set *readset) + { +- if (notify_pipe[0] != -1) ++ if (notify_pipe[0] >= 0) + FD_SET(notify_pipe[0], readset); + } + static void +@@ -127,8 +127,8 @@ pselect_notify_done(fd_set *readset) + { + char c; + +- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) { +- while (read(notify_pipe[0], &c, 1) != -1) ++ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) { ++ while (read(notify_pipe[0], &c, 1) >= 0) + 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: + } else if (r != 0) { + error("%.200s line %d: glob failed for %s.", + filename, linenum, arg2); ++ free(arg2); + goto out; + } + free(arg2); +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 + if (*activep && *charptr == NULL) { + *charptr = tilde_expand_filename(arg, getuid()); + /* increase optional counter */ +- if (intptr != NULL) +- *intptr = *intptr + 1; ++ /* DEAD CODE intptr is still NULL ;) ++ if (intptr != NULL) ++ *intptr = *intptr + 1; */ + } + 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) + debug_f("invalid tun"); + goto done; + } +- if (auth_opts->force_tun_device != -1) { ++ if (auth_opts->force_tun_device >= 0) { + if (tun != SSH_TUNID_ANY && + auth_opts->force_tun_device != (int)tun) + goto done; +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 + + if (pkcs11_uri_parse(provider, uri) != 0) { + error("Failed to parse PKCS#11 URI"); ++ pkcs11_uri_cleanup(uri); + return NULL; + } + /* validate also provider from URI */ +diff -up openssh-7.4p1/sshd-session.c.coverity openssh-7.4p1/sshd-session.c +--- openssh-7.4p1/sshd-session.c.coverity 2016-12-23 16:40:26.897788690 +0100 ++++ openssh-7.4p1/sshd-session.c 2016-12-23 16:40:26.904788692 +0100 +@@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt) + + privsep_preauth_child(ssh); + setproctitle("%s", "[net]"); +- if (box != NULL) ++ if (box != NULL) { + ssh_sandbox_child(box); ++ free(box); ++ } + + return 0; + } +@@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) + + if (newstr) + myproposal[PROPOSAL_KEX_ALGS] = newstr; +- else ++ else { + fatal("No supported key exchange algorithms"); ++ free(gss); ++ } ++ /* coverity[leaked_storage: FALSE]*/ + } + #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; diff --git a/0023-openssh-6.7p1-sftp-force-permission.patch b/openssh-6.7p1-sftp-force-permission.patch similarity index 72% rename from 0023-openssh-6.7p1-sftp-force-permission.patch rename to openssh-6.7p1-sftp-force-permission.patch index 1cdc0df..1cfa309 100644 --- a/0023-openssh-6.7p1-sftp-force-permission.patch +++ b/openssh-6.7p1-sftp-force-permission.patch @@ -1,17 +1,6 @@ -From 34b196198018059bed294fa7a08e70606b4cbc36 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 23/50] openssh-6.7p1-sftp-force-permission - ---- - sftp-server.8 | 7 +++++++ - sftp-server.c | 24 ++++++++++++++++++++++-- - 2 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/sftp-server.8 b/sftp-server.8 -index 5311bf92..5e6e3aa4 100644 ---- a/sftp-server.8 -+++ b/sftp-server.8 +diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8 +--- openssh-7.2p2/sftp-server.8.sftp-force-mode 2016-03-09 19:04:48.000000000 +0100 ++++ openssh-7.2p2/sftp-server.8 2016-06-23 16:18:20.463854117 +0200 @@ -38,6 +38,7 @@ .Op Fl P Ar denied_requests .Op Fl p Ar allowed_requests @@ -33,11 +22,10 @@ index 5311bf92..5e6e3aa4 100644 .El .Pp On some systems, -diff --git a/sftp-server.c b/sftp-server.c -index 4985da38..6ed1c27f 100644 ---- a/sftp-server.c -+++ b/sftp-server.c -@@ -76,6 +76,10 @@ struct sshbuf *oqueue; +diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c +--- openssh-7.2p2/sftp-server.c.sftp-force-mode 2016-06-23 16:18:20.446854128 +0200 ++++ openssh-7.2p2/sftp-server.c 2016-06-23 16:20:37.950766082 +0200 +@@ -69,6 +69,10 @@ struct sshbuf *oqueue; /* Version of client */ static u_int version; @@ -48,7 +36,7 @@ index 4985da38..6ed1c27f 100644 /* SSH2_FXP_INIT received */ static int init_done; -@@ -745,6 +749,7 @@ process_open(u_int32_t id) +@@ -683,6 +687,7 @@ process_open(u_int32_t id) Attrib a; char *name; int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; @@ -56,7 +44,7 @@ index 4985da38..6ed1c27f 100644 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ -@@ -754,6 +759,10 @@ process_open(u_int32_t id) +@@ -692,6 +697,10 @@ process_open(u_int32_t id) debug3("request %u: open flags %d", id, pflags); flags = flags_from_portable(pflags); mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; @@ -67,7 +55,7 @@ index 4985da38..6ed1c27f 100644 logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && -@@ -775,6 +784,8 @@ process_open(u_int32_t id) +@@ -713,6 +722,8 @@ process_open(u_int32_t id) } } } @@ -76,7 +64,7 @@ index 4985da38..6ed1c27f 100644 if (status != SSH2_FX_OK) send_status(id, status); free(name); -@@ -1894,7 +1905,7 @@ sftp_server_usage(void) +@@ -1494,7 +1505,7 @@ sftp_server_usage(void) fprintf(stderr, "usage: %s [-ehR] [-d start_directory] [-f log_facility] " "[-l log_level]\n\t[-P denied_requests] " @@ -85,7 +73,7 @@ index 4985da38..6ed1c27f 100644 " %s -Q protocol_feature\n", __progname, __progname); exit(1); -@@ -1918,7 +1929,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle +@@ -1520,7 +1531,7 @@ sftp_server_main(int argc, char **argv, pw = pwcopy(user_pw); while (!skipargs && (ch = getopt(argc, argv, @@ -94,7 +82,7 @@ index 4985da38..6ed1c27f 100644 switch (ch) { case 'Q': if (strcasecmp(optarg, "requests") != 0) { -@@ -1980,6 +1991,15 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle +@@ -1580,6 +1591,15 @@ sftp_server_main(int argc, char **argv, fatal("Invalid umask \"%s\"", optarg); (void)umask((mode_t)mask); break; @@ -110,6 +98,3 @@ index 4985da38..6ed1c27f 100644 case 'h': default: sftp_server_usage(); --- -2.49.0 - diff --git a/openssh-6.8p1-sshdT-output.patch b/openssh-6.8p1-sshdT-output.patch new file mode 100644 index 0000000..156e66d --- /dev/null +++ b/openssh-6.8p1-sshdT-output.patch @@ -0,0 +1,12 @@ +diff -up openssh/servconf.c.sshdt openssh/servconf.c +--- openssh/servconf.c.sshdt 2015-06-24 11:42:29.041078704 +0200 ++++ openssh/servconf.c 2015-06-24 11:44:39.734745802 +0200 +@@ -2317,7 +2317,7 @@ dump_config(ServerOptions *o) + dump_cfg_string(sXAuthLocation, o->xauth_location); + dump_cfg_string(sCiphers, o->ciphers); + dump_cfg_string(sMacs, o->macs); +- dump_cfg_string(sBanner, o->banner); ++ dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none"); + dump_cfg_string(sForceCommand, o->adm_forced_command); + dump_cfg_string(sChrootDirectory, o->chroot_directory); + dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); diff --git a/0040-openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch similarity index 73% rename from 0040-openssh-7.1p2-audit-race-condition.patch rename to openssh-7.1p2-audit-race-condition.patch index fe732a6..57ad148 100644 --- a/0040-openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -1,19 +1,7 @@ -From c288d4a26ad44dc481c9d18d2920c9d70474833c Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 40/50] openssh-7.1p2-audit-race-condition - ---- - monitor_wrap.c | 46 +++++++++++++++++++++++++++++++++++++ - monitor_wrap.h | 2 ++ - session.c | 61 ++++++++++++++++++++++++++++++++++++++++++++------ - 3 files changed, 102 insertions(+), 7 deletions(-) - -diff --git a/monitor_wrap.c b/monitor_wrap.c -index 1a079c15..768a59f9 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -1415,4 +1415,50 @@ mm_audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_ +diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c +--- openssh-7.4p1/monitor_wrap.c.audit-race 2016-12-23 16:35:52.694685771 +0100 ++++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:35:52.697685772 +0100 +@@ -1107,4 +1107,50 @@ mm_audit_destroy_sensitive_data(const ch mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m); sshbuf_free(m); } @@ -64,11 +52,10 @@ index 1a079c15..768a59f9 100644 + pmonitor->m_recvfd = fd; +} #endif /* SSH_AUDIT_EVENTS */ -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 661ed63b..e957ba6e 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -93,6 +93,8 @@ void mm_audit_unsupported_body(struct ssh *, int); +diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h +--- openssh-7.4p1/monitor_wrap.h.audit-race 2016-12-23 16:35:52.694685771 +0100 ++++ openssh-7.4p1/monitor_wrap.h 2016-12-23 16:35:52.698685772 +0100 +@@ -83,6 +83,8 @@ void mm_audit_unsupported_body(int); void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t); void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); @@ -77,11 +64,10 @@ index 661ed63b..e957ba6e 100644 #endif struct Session; -diff --git a/session.c b/session.c -index 83fc9418..b4753d93 100644 ---- a/session.c -+++ b/session.c -@@ -167,6 +167,10 @@ static Session *sessions = NULL; +diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c +--- openssh-7.4p1/session.c.audit-race 2016-12-23 16:35:52.695685771 +0100 ++++ openssh-7.4p1/session.c 2016-12-23 16:37:26.339730596 +0100 +@@ -162,6 +162,10 @@ static Session *sessions = NULL; login_cap_t *lc; #endif @@ -92,7 +78,7 @@ index 83fc9418..b4753d93 100644 static int is_child = 0; static int in_chroot = 0; static int have_dev_log = 1; -@@ -390,6 +394,8 @@ xauth_valid_string(const char *s) +@@ -289,6 +293,8 @@ xauth_valid_string(const char *s) return 1; } @@ -101,7 +87,7 @@ index 83fc9418..b4753d93 100644 #define USE_PIPES 1 /* * This is called to fork and execute a command when we have no tty. This -@@ -513,6 +519,8 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) +@@ -424,6 +430,8 @@ do_exec_no_pty(Session *s, const char *c close(err[0]); #endif @@ -110,7 +96,7 @@ index 83fc9418..b4753d93 100644 /* Do processing for the child (exec command etc). */ do_child(ssh, s, command); /* NOTREACHED */ -@@ -630,6 +638,9 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) +@@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm /* Close the extra descriptor for the pseudo tty. */ close(ttyfd); @@ -120,7 +106,7 @@ index 83fc9418..b4753d93 100644 /* record login, etc. similar to login(1) */ #ifndef HAVE_OSF_SIA do_login(ssh, s, command); -@@ -766,6 +777,8 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -717,6 +728,8 @@ do_exec(Session *s, const char *command) } if (s->command != NULL && s->ptyfd == -1) s->command_handle = mm_audit_run_command(ssh, s->command); @@ -129,7 +115,7 @@ index 83fc9418..b4753d93 100644 #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -781,6 +794,20 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -732,6 +745,20 @@ do_exec(Session *s, const char *command) */ sshbuf_reset(loginmsg); @@ -150,7 +136,7 @@ index 83fc9418..b4753d93 100644 return ret; } -@@ -1532,6 +1559,33 @@ child_close_fds(struct ssh *ssh) +@@ -1538,6 +1565,33 @@ child_close_fds(void) log_redirect_stderr_to(NULL); } @@ -165,7 +151,7 @@ index 83fc9418..b4753d93 100644 +#endif + + /* remove hostkey from the child's memory */ -+ /* FIXME beldmit destroy_sensitive_data(ssh); */ ++ destroy_sensitive_data(ssh); + /* + * We can audit this, because we hacked the pipe to direct the + * messages over postauth child. But this message requires answer @@ -184,11 +170,11 @@ index 83fc9418..b4753d93 100644 /* * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group -@@ -1549,13 +1603,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); -- /* remove keys from memory */ +- /* remove hostkey from the child's memory */ - destroy_sensitive_data(ssh); - ssh_packet_clear_keys(ssh); - /* Don't audit this - both us and the parent would be talking to the @@ -198,6 +184,3 @@ index 83fc9418..b4753d93 100644 /* Force a password change */ if (s->authctxt->force_pwchange) { do_setusercontext(pw); --- -2.49.0 - diff --git a/0015-openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch similarity index 74% rename from 0015-openssh-7.2p2-k5login_directory.patch rename to openssh-7.2p2-k5login_directory.patch index 5e980c8..80e7678 100644 --- a/0015-openssh-7.2p2-k5login_directory.patch +++ b/openssh-7.2p2-k5login_directory.patch @@ -1,20 +1,8 @@ -From 25540939422660b024b8832f67eab82267aa8df6 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 15/50] openssh-7.2p2-k5login_directory - ---- - auth-krb5.c | 16 ++++++++++++++++ - auth.h | 2 ++ - gss-serv-krb5.c | 21 ++++++++++++++++++++- - sshd.8 | 4 ++++ - 4 files changed, 42 insertions(+), 1 deletion(-) - diff --git a/auth-krb5.c b/auth-krb5.c -index 77714e3d..74f56d47 100644 +index 2b02a04..19b9364 100644 --- a/auth-krb5.c +++ b/auth-krb5.c -@@ -465,5 +465,21 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm +@@ -375,5 +375,21 @@ cleanup: return (krb5_cc_resolve(ctx, ccname, ccache)); } } @@ -37,10 +25,10 @@ index 77714e3d..74f56d47 100644 #endif /* !HEIMDAL */ #endif /* KRB5 */ diff --git a/auth.h b/auth.h -index 10e88e11..39163035 100644 +index f9d191c..c432d2f 100644 --- a/auth.h +++ b/auth.h -@@ -247,6 +247,8 @@ int sys_auth_passwd(struct ssh *, const char *); +@@ -222,6 +222,8 @@ int sys_auth_passwd(Authctxt *, const char *); #if defined(KRB5) && !defined(HEIMDAL) krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); @@ -50,10 +38,10 @@ index 10e88e11..39163035 100644 #endif /* AUTH_H */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index df55512d..820f794c 100644 +index a7c0c5f..df8cc9a 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c -@@ -144,8 +144,27 @@ ssh_gssapi_k5login_exists() +@@ -244,8 +244,27 @@ ssh_gssapi_k5login_exists() { char file[MAXPATHLEN]; struct passwd *pw = the_authctxt->pw; @@ -83,10 +71,10 @@ index df55512d..820f794c 100644 } diff --git a/sshd.8 b/sshd.8 -index 049d0a94..6784286d 100644 +index 5c4f15b..135e290 100644 --- a/sshd.8 +++ b/sshd.8 -@@ -880,6 +880,10 @@ rlogin/rsh. +@@ -806,6 +806,10 @@ rlogin/rsh. These files enforce GSSAPI/Kerberos authentication access control. Further details are described in .Xr ksu 1 . @@ -97,6 +85,3 @@ index 049d0a94..6784286d 100644 .Pp .It Pa ~/.ssh/ This directory is the default location for all user-specific configuration --- -2.49.0 - diff --git a/0024-openssh-7.2p2-s390-closefrom.patch b/openssh-7.2p2-s390-closefrom.patch similarity index 66% rename from 0024-openssh-7.2p2-s390-closefrom.patch rename to openssh-7.2p2-s390-closefrom.patch index 0214781..363538c 100644 --- a/0024-openssh-7.2p2-s390-closefrom.patch +++ b/openssh-7.2p2-s390-closefrom.patch @@ -1,17 +1,21 @@ -From 9bb31b63142adaaf949e20c2d86c97f9b787217b Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 24/50] openssh-7.2p2-s390-closefrom +Zseries only: Leave the hardware filedescriptors open. + +All filedescriptors above 2 are getting closed when a new +sshd process to handle a new client connection is +spawned. As the process also chroot into an empty filesystem +without any device nodes, there is no chance to reopen the +files. This patch filters out the reqired fds in the +closefrom function so these are skipped in the close loop. + +Author: Harald Freudenberger --- - openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++ + openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) -diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c -index 49a4f35f..f6112458 100644 --- a/openbsd-compat/bsd-closefrom.c +++ b/openbsd-compat/bsd-closefrom.c -@@ -140,7 +140,33 @@ closefrom(int lowfd) +@@ -82,7 +82,33 @@ closefrom(int lowfd) fd = strtol(dent->d_name, &endp, 10); if (dent->d_name != endp && *endp == '\0' && fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) @@ -45,6 +49,4 @@ index 49a4f35f..f6112458 100644 } (void) closedir(dirp); return; --- -2.49.0 diff --git a/0007-openssh-7.2p2-x11.patch b/openssh-7.2p2-x11.patch similarity index 71% rename from 0007-openssh-7.2p2-x11.patch rename to openssh-7.2p2-x11.patch index 2f72f9a..6db16be 100644 --- a/0007-openssh-7.2p2-x11.patch +++ b/openssh-7.2p2-x11.patch @@ -1,32 +1,22 @@ -From cf6d48305cf6601448ea7a0d96ae825cbbbf0a2c Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 07/50] openssh-7.2p2-x11 - ---- - channels.c | 25 +++++++++++++++++++------ - 1 file changed, 19 insertions(+), 6 deletions(-) - diff --git a/channels.c b/channels.c -index bfe2e3b2..d46531ce 100644 ---- a/channels.c -+++ b/channels.c -@@ -5098,11 +5098,13 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +--- a/channels.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/channels.c (date 1703026069921) +@@ -5075,11 +5075,13 @@ } - + static int -connect_local_xsocket_path(const char *pathname) +connect_local_xsocket_path(const char *pathname, int len) { int sock; struct sockaddr_un addr; - + + if (len <= 0) + return -1; sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { error("socket: %.100s", strerror(errno)); -@@ -5110,11 +5112,12 @@ connect_local_xsocket_path(const char *pathname) +@@ -5087,11 +5089,12 @@ } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; @@ -41,8 +31,8 @@ index bfe2e3b2..d46531ce 100644 - error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); return -1; } - -@@ -5122,8 +5125,18 @@ static int + +@@ -5099,8 +5102,18 @@ connect_local_xsocket(u_int dnr) { char buf[1024]; @@ -63,6 +53,3 @@ index bfe2e3b2..d46531ce 100644 } #ifdef __APPLE__ --- -2.49.0 - diff --git a/0025-openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch similarity index 53% rename from 0025-openssh-7.3p1-x11-max-displays.patch rename to openssh-7.3p1-x11-max-displays.patch index 68d679c..e28c62e 100644 --- a/0025-openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -1,22 +1,18 @@ -From 36e3430d1f81397d5f40600e075272a81f7effce Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 25/50] openssh-7.3p1-x11-max-displays - ---- - channels.c | 9 ++++++--- - channels.h | 2 +- - servconf.c | 12 +++++++++++- - servconf.h | 2 ++ - session.c | 5 +++-- - sshd_config.5 | 7 +++++++ - 6 files changed, 30 insertions(+), 7 deletions(-) - -diff --git a/channels.c b/channels.c -index d46531ce..7438c1a5 100644 ---- a/channels.c -+++ b/channels.c -@@ -4996,7 +4996,7 @@ rdynamic_connect_finish(struct ssh *ssh, Channel *c) +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; + #define NUM_SOCKS 10 + + /* -- X11 forwarding */ +-/* Maximum number of fake X11 displays to try. */ +-#define MAX_DISPLAYS 1000 ++/* Minimum port number for X11 forwarding */ ++#define X11_PORT_MIN 6000 + + /* Per-channel callback for pre/post IO actions */ + typedef void chan_fn(struct ssh *, Channel *c); +@@ -4228,7 +4228,7 @@ channel_send_window_changes(void) */ int x11_create_display_inet(struct ssh *ssh, int x11_display_offset, @@ -25,8 +21,8 @@ index d46531ce..7438c1a5 100644 u_int *display_numberp, int **chanids) { Channel *nc = NULL; -@@ -5009,8 +5009,11 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, - x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS) +@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_ + if (chanids == NULL) return -1; + /* Try to bind ports starting at 6000+X11DisplayOffset */ @@ -36,22 +32,55 @@ index d46531ce..7438c1a5 100644 - display_number < MAX_DISPLAYS; + display_number < x11_max_displays; display_number++) { - port = X11_BASE_PORT + display_number; +- port = 6000 + display_number; ++ port = X11_PORT_MIN + display_number; ++ if (port < X11_PORT_MIN) /* overflow */ ++ break; memset(&hints, 0, sizeof(hints)); -@@ -5065,7 +5068,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, + 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_ if (num_socks > 0) break; } - if (display_number >= MAX_DISPLAYS) { -+ if (display_number >= x11_max_displays || port < X11_BASE_PORT ) { ++ if (display_number >= x11_max_displays || port < X11_PORT_MIN ) { error("Failed to allocate internet-domain X11 display socket."); return -1; } -diff --git a/channels.h b/channels.h -index 134528d5..8a09a820 100644 ---- a/channels.h -+++ b/channels.h -@@ -379,7 +379,7 @@ int permitopen_port(const char *); +@@ -4441,7 +4447,7 @@ x11_connect_display(void) + memset(&hints, 0, sizeof(hints)); + hints.ai_family = ssh->chanctxt->IPv4or6; + hints.ai_socktype = SOCK_STREAM; +- snprintf(strport, sizeof strport, "%u", 6000 + display_number); ++ snprintf(strport, sizeof strport, "%u", X11_PORT_MIN + display_number); + 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) + /* Connect it to the display. */ + if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { + debug2("connect %.100s port %u: %.100s", buf, +- 6000 + display_number, strerror(errno)); ++ X11_PORT_MIN + display_number, strerror(errno)); + close(sock); + continue; + } +@@ -4466,8 +4472,8 @@ x11_connect_display(void) + } + freeaddrinfo(aitop); + if (!ai) { +- 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 *); void channel_set_x11_refuse_time(struct ssh *, time_t); int x11_connect_display(struct ssh *); @@ -59,12 +88,11 @@ index 134528d5..8a09a820 100644 +int x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **); void x11_request_forwarding_with_spoofing(struct ssh *, int, const char *, const char *, const char *, int); - int x11_channel_used_recently(struct ssh *ssh); -diff --git a/servconf.c b/servconf.c -index 105e301d..15c99b30 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -117,6 +117,7 @@ initialize_server_options(ServerOptions *options) + +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 options->print_lastlog = -1; options->x11_forwarding = -1; options->x11_display_offset = -1; @@ -72,7 +100,7 @@ index 105e301d..15c99b30 100644 options->x11_use_localhost = -1; options->permit_tty = -1; options->permit_user_rc = -1; -@@ -353,6 +354,8 @@ fill_default_server_options(ServerOptions *options) +@@ -243,6 +244,8 @@ fill_default_server_options(ServerOption options->x11_forwarding = 0; if (options->x11_display_offset == -1) options->x11_display_offset = 10; @@ -81,16 +109,16 @@ index 105e301d..15c99b30 100644 if (options->x11_use_localhost == -1) options->x11_use_localhost = 1; if (options->xauth_location == NULL) -@@ -576,7 +579,7 @@ typedef enum { - sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, - sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, +@@ -419,7 +422,7 @@ typedef enum { + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, + sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, -@@ -714,6 +717,7 @@ static struct { +@@ -540,6 +543,7 @@ static struct { { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, @@ -98,7 +126,7 @@ index 105e301d..15c99b30 100644 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, -@@ -1750,6 +1754,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1316,6 +1320,10 @@ process_server_config_line(ServerOptions *intptr = value; break; @@ -109,7 +137,7 @@ index 105e301d..15c99b30 100644 case sX11UseLocalhost: intptr = &options->x11_use_localhost; goto parse_flag; -@@ -3004,6 +3012,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +@@ -2063,6 +2071,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); M_CP_INTOPT(x11_display_offset); M_CP_INTOPT(x11_forwarding); @@ -117,7 +145,7 @@ index 105e301d..15c99b30 100644 M_CP_INTOPT(x11_use_localhost); M_CP_INTOPT(permit_tty); M_CP_INTOPT(permit_user_rc); -@@ -3299,6 +3308,7 @@ dump_config(ServerOptions *o) +@@ -2315,6 +2324,7 @@ dump_config(ServerOptions *o) #endif dump_cfg_int(sLoginGraceTime, o->login_grace_time); dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); @@ -125,11 +153,10 @@ index 105e301d..15c99b30 100644 dump_cfg_int(sMaxAuthTries, o->max_authtries); dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); -diff --git a/servconf.h b/servconf.h -index c08cf6a7..7c7e5d43 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -38,6 +38,7 @@ +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 @@ #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ @@ -137,7 +164,7 @@ index c08cf6a7..7c7e5d43 100644 /* Magic name for internal sftp-server */ #define INTERNAL_SFTP_NAME "internal-sftp" -@@ -114,6 +115,7 @@ typedef struct { +@@ -85,6 +86,7 @@ typedef struct { int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ int x11_display_offset; /* What DISPLAY number to start * searching at */ @@ -145,14 +172,13 @@ index c08cf6a7..7c7e5d43 100644 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 --git a/session.c b/session.c -index 54da09d5..28bbb8a7 100644 ---- a/session.c -+++ b/session.c -@@ -2611,8 +2611,9 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) +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) 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, @@ -161,11 +187,10 @@ index 54da09d5..28bbb8a7 100644 debug("x11_create_display_inet failed."); return 0; } -diff --git a/sshd_config.5 b/sshd_config.5 -index fe246fc2..26fcdc84 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -1391,6 +1391,7 @@ Available keywords are +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 .Cm TrustedUserCAKeys , .Cm UnusedConnectionTimeout , .Cm X11DisplayOffset , @@ -173,7 +198,7 @@ index fe246fc2..26fcdc84 100644 .Cm X11Forwarding and .Cm X11UseLocalhost . -@@ -2111,6 +2112,12 @@ Specifies the first display number available for +@@ -1566,6 +1567,12 @@ Specifies the first display number avail X11 forwarding. This prevents sshd from interfering with real X11 servers. The default is 10. @@ -186,6 +211,3 @@ index fe246fc2..26fcdc84 100644 .It Cm X11Forwarding Specifies whether X11 forwarding is permitted. The argument must be --- -2.49.0 - diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch new file mode 100644 index 0000000..90640a0 --- /dev/null +++ b/openssh-7.5p1-sandbox.patch @@ -0,0 +1,86 @@ +In order to use the OpenSSL-ibmpkcs11 engine it is needed to allow flock +and ipc calls, because this engine calls OpenCryptoki (a PKCS#11 +implementation) which calls the libraries that will communicate with the +crypto cards. OpenCryptoki makes use of flock and ipc and, as of now, +this is only need on s390 architecture. + +Signed-off-by: Eduardo Barretto +--- + sandbox-seccomp-filter.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index ca75cc7..6e7de31 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -166,6 +166,9 @@ static const struct sock_filter preauth_insns[] = { + #ifdef __NR_exit_group + SC_ALLOW(__NR_exit_group), + #endif ++#if defined(__NR_flock) && defined(__s390__) ++ SC_ALLOW(__NR_flock), ++#endif + #ifdef __NR_futex + SC_FUTEX(__NR_futex), + #endif +@@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = { + #ifdef __NR_gettimeofday + SC_ALLOW(__NR_gettimeofday), + #endif ++#if defined(__NR_ipc) && defined(__s390__) ++ SC_ALLOW(__NR_ipc), ++#endif + #ifdef __NR_getuid + SC_ALLOW(__NR_getuid), + #endif +-- +1.9.1 + +getuid and geteuid are needed when using an openssl engine that calls a +crypto card, e.g. ICA (libica). +Those syscalls are also needed by the distros for audit code. + +Signed-off-by: Eduardo Barretto +--- + sandbox-seccomp-filter.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index 6e7de31..e86aa2c 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -175,6 +175,18 @@ static const struct sock_filter preauth_insns[] = { + #ifdef __NR_getpid + SC_ALLOW(__NR_getpid), + #endif ++#ifdef __NR_getuid ++ SC_ALLOW(__NR_getuid), ++#endif ++#ifdef __NR_getuid32 ++ SC_ALLOW(__NR_getuid32), ++#endif ++#ifdef __NR_geteuid ++ SC_ALLOW(__NR_geteuid), ++#endif ++#ifdef __NR_geteuid32 ++ SC_ALLOW(__NR_geteuid32), ++#endif + #ifdef __NR_getrandom + SC_ALLOW(__NR_getrandom), + #endif +-- 1.9.1 +1.9.1 +diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-seccomp-filter.c +--- openssh-7.6p1/sandbox-seccomp-filter.c.sandbox 2017-12-12 13:59:30.563874059 +0100 ++++ openssh-7.6p1/sandbox-seccomp-filter.c 2017-12-12 13:59:14.842784083 +0100 +@@ -190,6 +190,9 @@ static const struct sock_filter preauth_ + #ifdef __NR_geteuid32 + SC_ALLOW(__NR_geteuid32), + #endif ++#ifdef __NR_gettid ++ SC_ALLOW(__NR_gettid), ++#endif + #ifdef __NR_getrandom + SC_ALLOW(__NR_getrandom), + #endif + diff --git a/0039-openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch similarity index 83% rename from 0039-openssh-7.6p1-audit.patch rename to openssh-7.6p1-audit.patch index e4f89c7..2c7ddc5 100644 --- a/0039-openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1,57 +1,7 @@ -From b0505837bfa2dcdf07800634fa80c5cdb78799dc Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 39/50] openssh-7.6p1-audit - ---- - Makefile.in | 2 +- - audit-bsm.c | 45 ++++++- - audit-linux.c | 302 +++++++++++++++++++++++++++++++++++++++++++--- - audit.c | 129 ++++++++++++++++++-- - audit.h | 22 +++- - auditstub.c | 52 ++++++++ - auth.c | 3 - - auth.h | 4 + - 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 | 83 ++++++++++++- - session.h | 10 +- - sshd-session.c | 104 ++++++++++++++-- - sshd.c | 10 ++ - 27 files changed, 1258 insertions(+), 104 deletions(-) - create mode 100644 auditstub.c - -diff --git a/Makefile.in b/Makefile.in -index 6c417ef7..a2942392 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -119,7 +119,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kexsntrup761x25519.o kexmlkem768x25519.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 ccfcf6f7..a49abb92 100644 ---- a/audit-bsm.c -+++ b/audit-bsm.c -@@ -373,12 +373,25 @@ audit_connection_from(const char *host, int port) +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, #endif } @@ -69,16 +19,17 @@ index ccfcf6f7..a49abb92 100644 /* not implemented */ } -+void + void +audit_count_session_open(void) +{ + /* not necessary */ +} + - void ++void audit_session_open(struct logininfo *li) { -@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li) + /* not implemented */ +@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li /* not implemented */ } @@ -91,7 +42,7 @@ index ccfcf6f7..a49abb92 100644 void audit_event(struct ssh *ssh, ssh_audit_event_t event) { -@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) +@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_e debug("%s: unhandled event %d", __func__, event); } } @@ -120,10 +71,234 @@ index ccfcf6f7..a49abb92 100644 + /* not implemented */ +} #endif /* BSM */ -diff --git a/audit-linux.c b/audit-linux.c -index 3fcbe5c5..d484b82b 100644 ---- a/audit-linux.c -+++ b/audit-linux.c +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) ++{ ++ mm_audit_unsupported_body(ssh, what); ++} ++ ++void ++audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) ++{ ++ mm_audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid()); ++} ++ ++void ++audit_session_key_free(struct ssh *ssh, int ctos) ++{ ++ mm_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 @@ -33,27 +33,40 @@ #include "log.h" @@ -135,10 +310,11 @@ index 3fcbe5c5..d484b82b 100644 +#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; @@ -172,7 +348,7 @@ index 3fcbe5c5..d484b82b 100644 saved_errno = errno; close(audit_fd); -@@ -65,9 +78,96 @@ linux_audit_record_event(int uid, const char *username, const char *hostname, +@@ -65,9 +78,96 @@ linux_audit_record_event(int uid, const rc = 0; errno = saved_errno; @@ -270,7 +446,7 @@ index 3fcbe5c5..d484b82b 100644 /* Below is the sshd audit API code */ void -@@ -76,49 +176,211 @@ audit_connection_from(const char *host, int port) +@@ -76,49 +176,211 @@ audit_connection_from(const char *host, /* not implemented */ } @@ -494,238 +670,9 @@ index 3fcbe5c5..d484b82b 100644 + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff --git a/audit.c b/audit.c -index dd2f0355..d0433c3a 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) -+{ -+ mm_audit_unsupported_body(ssh, what); -+} -+ -+void -+audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) -+{ -+ mm_audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid()); -+} -+ -+void -+audit_session_key_free(struct ssh *ssh, int ctos) -+{ -+ mm_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) -+{ -+ 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 --git a/audit.h b/audit.h -index 38cb5ad3..45d66ccf 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 - }; -+ -+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 00000000..639a798d ---- /dev/null -+++ b/auditstub.c +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 @@ -0,0 +1,52 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -779,47 +726,23 @@ index 00000000..639a798d +audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ +} -diff --git a/auth.c b/auth.c -index e4578169..e10e804f 100644 ---- a/auth.c -+++ b/auth.c -@@ -501,9 +501,6 @@ getpwnamallow(struct ssh *ssh, const char *user) - record_failed_login(ssh, user, - auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); - #endif +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 + 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 --git a/auth.h b/auth.h -index 39163035..6be52d70 100644 ---- a/auth.h -+++ b/auth.h -@@ -215,6 +215,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 */ - int auth_activate_options(struct ssh *, struct sshauthopt *); -@@ -240,6 +242,8 @@ int auth_check_authkey_line(struct passwd *, struct sshkey *, - char *, const char *, const char *, const char *, struct sshauthopt **); - int auth_check_authkeys_file(struct passwd *, FILE *, char *, - struct sshkey *, const char *, const char *, struct sshauthopt **); -+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); - -diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index a3be6e49..8cebaffd 100644 ---- a/auth2-hostbased.c -+++ b/auth2-hostbased.c -@@ -157,7 +157,7 @@ userauth_hostbased(struct ssh *ssh, const char *method) +- mm_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) authenticated = 0; if (mm_hostbased_key_allowed(ssh, authctxt->pw, cuser, chost, key) && @@ -828,7 +751,7 @@ index a3be6e49..8cebaffd 100644 sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL) == 0) authenticated = 1; -@@ -174,6 +174,20 @@ done: +@@ -175,6 +175,20 @@ done: return authenticated; } @@ -849,11 +772,10 @@ index a3be6e49..8cebaffd 100644 /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, -diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index 0d5ae0df..99cb810f 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -235,7 +235,7 @@ userauth_pubkey(struct ssh *ssh, const char *method) +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) /* test for correct signature */ authenticated = 0; if (mm_user_key_allowed(ssh, pw, key, 1, &authopts) && @@ -862,7 +784,7 @@ index 0d5ae0df..99cb810f 100644 sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, ssh->compat, &sig_details) == 0) { -@@ -328,6 +328,20 @@ done: +@@ -305,6 +305,20 @@ done: return authenticated; } @@ -883,24 +805,43 @@ index 0d5ae0df..99cb810f 100644 static int match_principals_file(struct passwd *pw, char *file, struct sshkey_cert *cert, struct sshauthopt **authoptsp) -diff --git a/auth2.c b/auth2.c -index 8ec41de2..4a8515ea 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -310,9 +310,6 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) - authctxt->valid = 0; - /* Invalid user, fake password information */ - authctxt->pw = fakepw(); +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 -#ifdef SSH_AUDIT_EVENTS -- mm_audit_event(ssh, SSH_INVALID_USER); --#endif - } - #ifdef USE_PAM - if (options.use_pam) -diff --git a/cipher.c b/cipher.c -index 8a18da2d..57d55325 100644 ---- a/cipher.c -+++ b/cipher.c +- 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 +@@ -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 */ + int auth_activate_options(struct ssh *, struct sshauthopt *); +@@ -239,6 +241,8 @@ struct passwd * getpwnamallow(struct ssh + char *, const char *, const char *, const char *, struct sshauthopt **); + int auth_check_authkeys_file(struct passwd *, FILE *, char *, + struct sshkey *, const char *, const char *, struct sshauthopt **); ++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); + +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 @@ -64,25 +64,6 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; @@ -927,7 +868,7 @@ index 8a18da2d..57d55325 100644 static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES -@@ -420,7 +401,7 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, +@@ -422,7 +403,7 @@ cipher_get_length(struct sshcipher_ctx * void cipher_free(struct sshcipher_ctx *cc) { @@ -936,10 +877,9 @@ index 8a18da2d..57d55325 100644 return; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_free(cc->cp_ctx); -diff --git a/cipher.h b/cipher.h -index 6533ff2b..2e05a021 100644 ---- a/cipher.h -+++ b/cipher.h +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 @@ -47,7 +47,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -967,11 +907,10 @@ index 6533ff2b..2e05a021 100644 struct sshcipher_ctx; const struct sshcipher *cipher_by_name(const char *); -diff --git a/kex.c b/kex.c -index 8b200ff4..62f607d6 100644 ---- a/kex.c -+++ b/kex.c -@@ -68,6 +68,7 @@ +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 +@@ -65,6 +65,7 @@ #include "sshbuf.h" #include "digest.h" #include "xmalloc.h" @@ -979,7 +918,7 @@ index 8b200ff4..62f607d6 100644 /* prototype */ static int kex_choose_conf(struct ssh *, uint32_t seq); -@@ -821,12 +822,16 @@ kex_start_rekex(struct ssh *ssh) +@@ -816,12 +817,16 @@ kex_start_rekex(struct ssh *ssh) } static int @@ -998,7 +937,7 @@ index 8b200ff4..62f607d6 100644 if ((enc->cipher = cipher_by_name(name)) == NULL) { error_f("unsupported cipher %s", name); free(name); -@@ -847,8 +852,12 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) +@@ -842,8 +847,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -1012,7 +951,7 @@ index 8b200ff4..62f607d6 100644 if (mac_setup(mac, name) < 0) { error_f("unsupported MAC %s", name); free(name); -@@ -861,12 +870,16 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) +@@ -856,12 +865,16 @@ choose_mac(struct ssh *ssh, struct sshma } static int @@ -1031,7 +970,7 @@ index 8b200ff4..62f607d6 100644 #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; -@@ -1030,7 +1043,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -1002,7 +1015,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; @@ -1040,7 +979,7 @@ index 8b200ff4..62f607d6 100644 sprop[nenc])) != 0) { kex->failed_choice = peer[nenc]; peer[nenc] = NULL; -@@ -1045,7 +1058,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -1017,7 +1030,7 @@ kex_choose_conf(struct ssh *ssh) peer[nmac] = NULL; goto out; } @@ -1049,7 +988,7 @@ index 8b200ff4..62f607d6 100644 sprop[ncomp])) != 0) { kex->failed_choice = peer[ncomp]; peer[ncomp] = NULL; -@@ -1068,6 +1081,10 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -1040,6 +1053,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); @@ -1060,7 +999,7 @@ index 8b200ff4..62f607d6 100644 } /* XXX need runden? */ kex->we_need = need; -@@ -1337,6 +1354,36 @@ dump_digest(const char *msg, const u_char *digest, int len) +@@ -1297,6 +1314,36 @@ dump_digest(const char *msg, const u_cha } #endif @@ -1097,11 +1036,10 @@ index 8b200ff4..62f607d6 100644 /* * Send a plaintext error message to the peer, suffixed by \r\n. * Only used during banner exchange, and there only for the server. -diff --git a/kex.h b/kex.h -index 0e080ea3..6a55aadf 100644 ---- a/kex.h -+++ b/kex.h -@@ -255,6 +255,8 @@ int kexgss_client(struct ssh *); +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 *); int kexgss_server(struct ssh *); #endif @@ -1110,10 +1048,9 @@ index 0e080ea3..6a55aadf 100644 int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **); -diff --git a/mac.c b/mac.c -index f3dda669..bf051baa 100644 ---- a/mac.c -+++ b/mac.c +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 @@ -239,6 +239,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1135,21 +1072,31 @@ index f3dda669..bf051baa 100644 /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff --git a/mac.h b/mac.h -index 0b119d7a..5fb593b9 100644 ---- a/mac.h -+++ b/mac.h -@@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int32_t, const u_char *, 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 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 --git a/monitor.c b/monitor.c -index 43c10a4e..fbc35782 100644 ---- a/monitor.c -+++ b/monitor.c +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 kexmlkem768x25519.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 @@ -93,6 +93,7 @@ #include "compat.h" #include "ssh2.h" @@ -1158,8 +1105,8 @@ index 43c10a4e..fbc35782 100644 #include "match.h" #include "ssherr.h" #include "sk-api.h" -@@ -110,6 +111,8 @@ extern struct sshbuf *loginmsg; - extern struct include_list includes; +@@ -107,6 +108,8 @@ extern u_int utmp_len; + extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ +extern void destroy_sensitive_data(struct ssh *); @@ -1167,7 +1114,7 @@ index 43c10a4e..fbc35782 100644 /* State exported from the child */ static struct sshbuf *child_state; -@@ -154,6 +157,11 @@ int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); +@@ -157,6 +160,11 @@ int mm_answer_gss_updatecreds(struct ssh #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(struct ssh *, int, struct sshbuf *); int mm_answer_audit_command(struct ssh *, int, struct sshbuf *); @@ -1179,7 +1126,7 @@ index 43c10a4e..fbc35782 100644 #endif static Authctxt *authctxt; -@@ -214,6 +222,10 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -215,6 +223,10 @@ struct mon_table mon_dispatch_proto20[] #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1190,7 +1137,7 @@ index 43c10a4e..fbc35782 100644 #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -249,6 +261,11 @@ struct mon_table mon_dispatch_postauth20[] = { +@@ -249,6 +261,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}, @@ -1202,7 +1149,7 @@ index 43c10a4e..fbc35782 100644 #endif {0, 0, NULL} }; -@@ -1569,8 +1586,10 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1444,8 +1461,10 @@ mm_answer_keyverify(struct ssh *ssh, int int r, ret, req_presence = 0, req_verify = 0, valid_data = 0; int encoded_ret; struct sshkey_sig_details *sig_details = NULL; @@ -1214,7 +1161,7 @@ index 43c10a4e..fbc35782 100644 (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) -@@ -1579,6 +1598,8 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1454,6 +1473,8 @@ mm_answer_keyverify(struct ssh *ssh, int if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal_f("bad key, not previously allowed"); @@ -1223,7 +1170,7 @@ index 43c10a4e..fbc35782 100644 /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1594,14 +1615,19 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1469,14 +1490,19 @@ mm_answer_keyverify(struct ssh *ssh, int case MM_USERKEY: valid_data = monitor_valid_userblob(ssh, data, datalen); auth_method = "publickey"; @@ -1243,16 +1190,16 @@ index 43c10a4e..fbc35782 100644 break; } if (!valid_data) -@@ -1613,8 +1639,6 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1488,8 +1514,6 @@ mm_answer_keyverify(struct ssh *ssh, int 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 using %s %s%s%s", auth_method, - sshkey_type(key), sigalg == NULL ? "default" : sigalg, - (ret == 0) ? "verified" : "unverified", -@@ -1702,13 +1726,19 @@ mm_record_login(struct ssh *ssh, Session *s, struct passwd *pw) + debug3_f("%s %s signature using %s %s%s%s", auth_method, + sshkey_type(key), sigalg == NULL ? "default" : sigalg, + (ret == 0) ? "verified" : "unverified", +@@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session } static void @@ -1273,7 +1220,7 @@ index 43c10a4e..fbc35782 100644 session_unused(s->self); } -@@ -1775,7 +1805,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1649,7 +1679,7 @@ mm_answer_pty(struct ssh *ssh, int sock, error: if (s != NULL) @@ -1282,7 +1229,7 @@ index 43c10a4e..fbc35782 100644 if ((r = sshbuf_put_u32(m, 0)) != 0) fatal_fr(r, "assemble 0"); mm_request_send(sock, MONITOR_ANS_PTY, m); -@@ -1794,7 +1824,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1668,7 +1698,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) fatal_fr(r, "parse tty"); if ((s = session_by_tty(tty)) != NULL) @@ -1291,7 +1238,7 @@ index 43c10a4e..fbc35782 100644 sshbuf_reset(m); free(tty); return (0); -@@ -1816,6 +1846,8 @@ mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req) +@@ -1690,6 +1720,8 @@ mm_answer_term(struct ssh *ssh, int sock sshpam_cleanup(); #endif @@ -1300,7 +1247,7 @@ index 43c10a4e..fbc35782 100644 while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1862,12 +1894,47 @@ mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) +@@ -1736,12 +1768,47 @@ mm_answer_audit_command(struct ssh *ssh, { char *cmd; int r; @@ -1349,7 +1296,7 @@ index 43c10a4e..fbc35782 100644 free(cmd); return (0); } -@@ -1940,6 +2007,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1813,6 +1880,7 @@ monitor_apply_keystate(struct ssh *ssh, void mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { @@ -1357,7 +1304,7 @@ index 43c10a4e..fbc35782 100644 debug3_f("Waiting for new keys"); if ((child_state = sshbuf_new()) == NULL) -@@ -1947,6 +2015,19 @@ mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1820,6 +1888,19 @@ mm_get_keystate(struct ssh *ssh, struct mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3_f("GOT new keys"); @@ -1377,7 +1324,7 @@ index 43c10a4e..fbc35782 100644 } -@@ -2234,3 +2315,102 @@ mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { +@@ -2111,3 +2192,102 @@ mm_answer_gss_updatecreds(struct ssh *ss #endif /* GSSAPI */ @@ -1480,11 +1427,10 @@ index 43c10a4e..fbc35782 100644 + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff --git a/monitor.h b/monitor.h -index d4d631dd..2c64f07d 100644 ---- a/monitor.h -+++ b/monitor.h -@@ -66,7 +66,13 @@ enum monitor_reqtype { +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 +@@ -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, MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, @@ -1499,11 +1445,10 @@ index d4d631dd..2c64f07d 100644 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, -diff --git a/monitor_wrap.c b/monitor_wrap.c -index b6e3b3f3..1a079c15 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -567,7 +567,7 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, +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 */ int @@ -1512,7 +1457,7 @@ index b6e3b3f3..1a079c15 100644 const u_char *data, size_t datalen, const char *sigalg, u_int compat, struct sshkey_sig_details **sig_detailsp) { -@@ -583,7 +583,8 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, +@@ -536,7 +536,8 @@ mm_sshkey_verify(const struct sshkey *ke *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -1522,7 +1467,7 @@ index b6e3b3f3..1a079c15 100644 (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) -@@ -616,6 +617,22 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, +@@ -569,6 +570,22 @@ mm_sshkey_verify(const struct sshkey *ke return 0; } @@ -1545,7 +1490,7 @@ index b6e3b3f3..1a079c15 100644 void mm_send_keystate(struct ssh *ssh, struct monitor *monitor) { -@@ -1032,11 +1049,12 @@ mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) +@@ -921,11 +938,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi sshbuf_free(m); } @@ -1560,7 +1505,7 @@ index b6e3b3f3..1a079c15 100644 debug3("%s entering command %s", __func__, command); -@@ -1046,6 +1064,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); @@ -1591,7 +1536,7 @@ index b6e3b3f3..1a079c15 100644 sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1294,3 +1336,83 @@ server_get_connection_info(struct ssh *ssh, int populate, int use_dns) +@@ -1095,3 +1137,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc return &ci; } @@ -1675,11 +1620,10 @@ index b6e3b3f3..1a079c15 100644 + sshbuf_free(m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 672dce52..661ed63b 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -58,7 +58,9 @@ int mm_user_key_allowed(struct ssh *ssh, struct passwd *, struct sshkey *, int, +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 struct sshauthopt **); int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, const char *, struct sshkey *); @@ -1690,7 +1634,7 @@ index 672dce52..661ed63b 100644 const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); -@@ -85,7 +87,12 @@ void mm_sshpam_free_ctx(void *); +@@ -86,7 +88,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(struct ssh *, ssh_audit_event_t); @@ -1704,10 +1648,9 @@ index 672dce52..661ed63b 100644 #endif struct Session; -diff --git a/packet.c b/packet.c -index 9dea2cfc..344b5f54 100644 ---- a/packet.c -+++ b/packet.c +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 @@ -81,6 +81,7 @@ #endif @@ -1716,7 +1659,7 @@ index 9dea2cfc..344b5f54 100644 #include "compat.h" #include "ssh2.h" #include "cipher.h" -@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh *ssh) +@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1730,7 +1673,7 @@ index 9dea2cfc..344b5f54 100644 /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -675,22 +683,19 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) +@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ss { struct session_state *state = ssh->state; u_int mode; @@ -1758,7 +1701,7 @@ index 9dea2cfc..344b5f54 100644 for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; -@@ -726,8 +731,18 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) +@@ -634,8 +639,18 @@ ssh_packet_close_internal(struct ssh *ss #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); @@ -1777,7 +1720,7 @@ index 9dea2cfc..344b5f54 100644 free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); -@@ -984,6 +999,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode) +@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod (unsigned long long)state->p_send.bytes, (unsigned long long)state->p_send.blocks); kex_free_newkeys(state->newkeys[mode]); @@ -1785,7 +1728,7 @@ index 9dea2cfc..344b5f54 100644 state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2325,6 +2341,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2173,6 +2189,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1858,21 +1801,19 @@ index 9dea2cfc..344b5f54 100644 /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff --git a/packet.h b/packet.h -index 49bb87f0..44a39a9e 100644 ---- a/packet.h -+++ b/packet.h -@@ -223,4 +223,5 @@ const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); +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 # undef EC_POINT #endif +void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ -diff --git a/session.c b/session.c -index 28bbb8a7..83fc9418 100644 ---- a/session.c -+++ b/session.c -@@ -145,7 +145,7 @@ extern char *__progname; +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; extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; @@ -1881,7 +1822,7 @@ index 28bbb8a7..83fc9418 100644 extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; extern char *tun_fwd_ifnames; /* serverloop.c */ -@@ -653,6 +653,14 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) +@@ -644,6 +644,14 @@ do_exec_pty(struct ssh *ssh, Session *s, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1896,7 +1837,7 @@ index 28bbb8a7..83fc9418 100644 /* Enter interactive session. */ s->ptymaster = ptymaster; ssh_packet_set_interactive(ssh, 1, -@@ -745,15 +753,19 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -736,15 +744,19 @@ do_exec(struct ssh *ssh, Session *s, con s->self); #ifdef SSH_AUDIT_EVENTS @@ -1918,10 +1859,11 @@ index 28bbb8a7..83fc9418 100644 #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1538,7 +1550,11 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1550,8 +1562,11 @@ do_child(struct ssh *ssh, Session *s, co sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); - /* remove keys from memory */ + /* remove hostkey from the child's memory */ +- destroy_sensitive_data(); + destroy_sensitive_data(ssh); ssh_packet_clear_keys(ssh); + /* Don't audit this - both us and the parent would be talking to the @@ -1930,7 +1872,7 @@ index 28bbb8a7..83fc9418 100644 /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1750,6 +1766,9 @@ session_unused(int id) +@@ -1763,6 +1778,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1940,11 +1882,10 @@ index 28bbb8a7..83fc9418 100644 sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1828,6 +1847,19 @@ session_open(Authctxt *authctxt, int chanid) - return 1; +@@ -1843,6 +1861,19 @@ session_open(Authctxt *authctxt, int cha } -+Session * + Session * +session_by_id(int id) +{ + if (id >= 0 && id < sessions_nalloc) { @@ -1957,10 +1898,11 @@ index 28bbb8a7..83fc9418 100644 + return NULL; +} + - Session * ++Session * session_by_tty(char *tty) { -@@ -2445,6 +2477,32 @@ session_exit_message(struct ssh *ssh, Session *s, int status) + int i; +@@ -2450,6 +2481,32 @@ session_exit_message(struct ssh *ssh, Se chan_write_failed(ssh, c); } @@ -1993,7 +1935,7 @@ index 28bbb8a7..83fc9418 100644 void session_close(struct ssh *ssh, Session *s) { -@@ -2458,6 +2516,10 @@ session_close(struct ssh *ssh, Session *s) +@@ -2463,6 +2520,10 @@ session_close(struct ssh *ssh, Session * if (s->ttyfd != -1) session_pty_cleanup(s); @@ -2004,7 +1946,7 @@ index 28bbb8a7..83fc9418 100644 free(s->term); free(s->display); free(s->x11_chanids); -@@ -2534,14 +2596,14 @@ session_close_by_channel(struct ssh *ssh, int id, int force, void *arg) +@@ -2537,14 +2598,14 @@ session_close_by_channel(struct ssh *ssh } void @@ -2021,7 +1963,7 @@ index 28bbb8a7..83fc9418 100644 else session_close(ssh, s); } -@@ -2668,6 +2730,15 @@ do_authenticated2(struct ssh *ssh, Authctxt *authctxt) +@@ -2671,6 +2732,15 @@ do_authenticated2(struct ssh *ssh, Authc server_loop2(ssh, authctxt); } @@ -2037,7 +1979,7 @@ index 28bbb8a7..83fc9418 100644 void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2731,7 +2802,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2734,7 +2804,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au * or if running in monitor. */ if (mm_is_monitor()) @@ -2046,10 +1988,9 @@ index 28bbb8a7..83fc9418 100644 } /* Return a name for the remote host that fits inside utmp_size */ -diff --git a/session.h b/session.h -index 344a1ddf..a41c6efc 100644 ---- a/session.h -+++ b/session.h +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 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2077,25 +2018,53 @@ index 344a1ddf..a41c6efc 100644 Session *session_by_tty(char *); void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); -diff --git a/sshd-session.c b/sshd-session.c -index 81d30152..a808ac9a 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -194,8 +194,8 @@ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); +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 +@@ -279,6 +280,15 @@ close_listen_socks(void) + num_listen_socks = 0; + } + ++/* ++ * Is this process listening for clients (i.e. not specific to any specific ++ * client connection?) ++ */ ++int listening_for_clients(void) ++{ ++ return num_listen_socks > 0; ++} ++ + /* Allocate and initialise the children array */ + static void + child_alloc(void) +@@ -1204,6 +1259,7 @@ server_accept_loop(int *sock_in, int *so + if (received_sigterm) { + logit("Received signal %d; terminating.", + (int) received_sigterm); ++ /* destroy_sensitive_data(ssh, 0); FIXME */ + close_listen_socks(); + if (options.pid_file != NULL) + unlink(options.pid_file); +diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c +--- openssh-8.6p1/sshd-session.c.audit 2021-04-19 16:47:35.727061907 +0200 ++++ openssh-8.6p1/sshd-session.c 2021-04-19 16:47:35.759062152 +0200 +@@ -122,6 +122,7 @@ + #include "ssh-gss.h" + #endif + #include "monitor_wrap.h" ++#include "audit.h" + #include "ssh-sandbox.h" + #include "auth-options.h" + #include "version.h" +@@ -260,8 +261,44 @@ struct sshbuf *loginmsg; struct sshbuf *loginmsg; /* Prototypes for various functions defined later in this file. */ -void destroy_sensitive_data(void); -void demote_sensitive_data(void); -+void destroy_sensitive_data(struct ssh *ssh); -+void demote_sensitive_data(struct ssh *ssh); - - /* XXX reduce to stub once postauth split */ - int -@@ -208,6 +208,41 @@ mm_is_monitor(void) - return (pmonitor && pmonitor->m_pid > 0); - } - ++void destroy_sensitive_data(struct ssh *); ++void demote_sensitive_data(struct ssh *); ++ +static int +sshkey_is_private(const struct sshkey *k) +{ @@ -2131,13 +2100,13 @@ index 81d30152..a808ac9a 100644 + } +} + + static void do_ssh2_kex(struct ssh *); + /* - * Signal handler for the alarm after the login grace period has expired. - * As usual, this may only take signal-safe actions, even though it is -@@ -236,18 +271,40 @@ grace_alarm_handler(int sig) +@@ -377,18 +387,40 @@ grace_alarm_handler(int sig) _exit(EXIT_LOGIN_GRACE); } - + -/* Destroy the host and server keys. They will no longer be needed. */ +/* + * Destroy the host and server keys. They will no longer be needed. Careful, @@ -2178,7 +2147,7 @@ index 81d30152..a808ac9a 100644 sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -256,20 +313,38 @@ destroy_sensitive_data(void) +@@ -397,20 +434,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2218,7 +2187,43 @@ index 81d30152..a808ac9a 100644 } /* Certs do not need demotion */ } -@@ -463,7 +538,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -438,7 +493,7 @@ reseed_prngs(void) + } + + static void +-privsep_preauth_child(void) ++privsep_preauth_child(struct ssh *ssh) + { + gid_t gidset[1]; + +@@ -453,7 +508,7 @@ privsep_preauth_child(void) + reseed_prngs(); + + /* Demote the private keys to public keys. */ +- demote_sensitive_data(); ++ demote_sensitive_data(ssh); + + #ifdef WITH_SELINUX + sshd_selinux_change_privsep_preauth_context(); +@@ -492,7 +547,7 @@ privsep_preauth(struct ssh *ssh) + pmonitor->m_pkex = &ssh->kex; + + box = ssh_sandbox_init(pmonitor); +- pid = fork(); ++ pmonitor->m_pid = pid = fork(); + if (pid == -1) { + fatal("fork of unprivileged child failed"); + } else if (pid != 0) { +@@ -537,7 +592,7 @@ privsep_preauth(struct ssh *ssh) + /* Arrange for logging to be sent to the monitor */ + set_log_handler(mm_log_handler, pmonitor); + +- privsep_preauth_child(); ++ privsep_preauth_child(ssh); + setproctitle("%s", "[net]"); + if (box != NULL) + ssh_sandbox_child(box); +@@ -589,7 +644,7 @@ privsep_postauth(struct ssh *ssh, Authct set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ @@ -2227,7 +2232,7 @@ index 81d30152..a808ac9a 100644 reseed_prngs(); -@@ -1387,6 +1462,9 @@ main(int ac, char **av) +@@ -2333,6 +2389,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ @@ -2237,7 +2242,7 @@ index 81d30152..a808ac9a 100644 ssh_packet_get_bytes(ssh, &ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -1432,6 +1510,14 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, +@@ -2513,6 +2572,14 @@ do_ssh2_kex(struct ssh *ssh) void cleanup_exit(int i) { @@ -2252,7 +2257,7 @@ index 81d30152..a808ac9a 100644 extern int auth_attempted; /* monitor.c */ if (the_active_state != NULL && the_authctxt != NULL) { -@@ -1448,7 +1534,9 @@ cleanup_exit(int i) +@@ -2525,7 +2593,9 @@ cleanup_exit(int i) } #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ @@ -2263,34 +2268,3 @@ index 81d30152..a808ac9a 100644 audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif /* Override default fatal exit value when auth was attempted */ -diff --git a/sshd.c b/sshd.c -index c9ea8e38..8a99f0b2 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -217,6 +217,15 @@ close_listen_socks(void) - num_listen_socks = 0; - } - -+/* -+ * Is this process listening for clients (i.e. not specific to any specific -+ * client connection?) -+ */ -+int listening_for_clients(void) -+{ -+ return num_listen_socks > 0; -+} -+ - /* Allocate and initialise the children array */ - static void - child_alloc(void) -@@ -959,6 +968,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); -+ /* destroy_sensitive_data(ssh, 0); FIXME */ - close_listen_socks(); - if (options.pid_file != NULL) - unlink(options.pid_file); --- -2.49.0 - diff --git a/0026-openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch similarity index 65% rename from 0026-openssh-7.6p1-cleanup-selinux.patch rename to openssh-7.6p1-cleanup-selinux.patch index c4f2d15..cfe11ad 100644 --- a/0026-openssh-7.6p1-cleanup-selinux.patch +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -1,25 +1,7 @@ -From 43320351b6f150167190aacc84f2f87030fef3d2 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 26/50] openssh-7.6p1-cleanup-selinux - ---- - auth2-pubkey.c | 8 ++++-- - misc.c | 5 ++-- - misc.h | 2 +- - openbsd-compat/port-linux-sshd.c | 42 +++++++++++++++++--------------- - openbsd-compat/port-linux.h | 4 +-- - platform.c | 6 ++++- - sshconnect.c | 2 +- - sshd-auth.c | 2 +- - sshd-session.c | 6 +++-- - 9 files changed, 45 insertions(+), 32 deletions(-) - -diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index 267a27d2..0d5ae0df 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -77,6 +77,8 @@ +diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c +--- openssh/auth2-pubkey.c.refactor 2019-04-04 13:19:12.188821236 +0200 ++++ openssh/auth2-pubkey.c 2019-04-04 13:19:12.276822078 +0200 +@@ -72,6 +72,8 @@ /* import */ extern ServerOptions options; @@ -28,7 +10,7 @@ index 267a27d2..0d5ae0df 100644 extern struct authmethod_cfg methodcfg_pubkey; static char * -@@ -485,7 +487,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key, +@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh if ((pid = subprocess("AuthorizedPrincipalsCommand", command, ac, av, &f, SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, @@ -38,21 +20,20 @@ index 267a27d2..0d5ae0df 100644 goto out; uid_swapped = 1; -@@ -755,7 +758,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key, +@@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss if ((pid = subprocess("AuthorizedKeysCommand", command, ac, av, &f, - SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, + SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, - runas_pw, temporarily_use_uid, restore_uid)) == 0) + runas_pw, temporarily_use_uid, restore_uid, + inetd_flag, the_authctxt)) == 0) goto out; uid_swapped = 1; -diff --git a/misc.c b/misc.c -index 1e31acc9..09722962 100644 ---- a/misc.c -+++ b/misc.c -@@ -2764,7 +2764,8 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) +diff -up openssh/misc.c.refactor openssh/misc.c +--- openssh/misc.c.refactor 2019-04-04 13:19:12.235821686 +0200 ++++ openssh/misc.c 2019-04-04 13:19:12.276822078 +0200 +@@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh * pid_t subprocess(const char *tag, const char *command, int ac, char **av, FILE **child, u_int flags, @@ -62,7 +43,7 @@ index 1e31acc9..09722962 100644 { FILE *f = NULL; struct stat st; -@@ -2898,7 +2899,7 @@ subprocess(const char *tag, const char *command, +@@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw _exit(1); } #ifdef WITH_SELINUX @@ -71,11 +52,10 @@ index 1e31acc9..09722962 100644 error ("failed to copy environment: %s", strerror(errno)); _exit(127); -diff --git a/misc.h b/misc.h -index efecdf1a..9efa9cf4 100644 ---- a/misc.h -+++ b/misc.h -@@ -122,7 +122,7 @@ typedef void privrestore_fn(void); +diff -up openssh/misc.h.refactor openssh/misc.h +--- openssh/misc.h.refactor 2019-04-04 13:19:12.251821839 +0200 ++++ openssh/misc.h 2019-04-04 13:19:12.276822078 +0200 +@@ -235,7 +235,7 @@ struct passwd *fakepw(void); #define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */ #define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */ pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int, @@ -84,10 +64,23 @@ index efecdf1a..9efa9cf4 100644 typedef struct arglist arglist; struct arglist { -diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index 646f0887..291b569a 100644 ---- a/openbsd-compat/port-linux-sshd.c -+++ b/openbsd-compat/port-linux-sshd.c +diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h +--- openssh/openbsd-compat/port-linux.h.refactor 2019-04-04 13:19:12.256821887 +0200 ++++ openssh/openbsd-compat/port-linux.h 2019-04-04 13:19:12.276822078 +0200 +@@ -26,8 +26,8 @@ void ssh_selinux_setfscreatecon(const ch + + int sshd_selinux_enabled(void); + void sshd_selinux_copy_context(void); +-void sshd_selinux_setup_exec_context(char *); +-int sshd_selinux_setup_env_variables(void); ++void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int); ++int sshd_selinux_setup_env_variables(int inetd, void *); + void sshd_selinux_change_privsep_preauth_context(void); + #endif + +diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compat/port-linux-sshd.c +--- openssh/openbsd-compat/port-linux-sshd.c.refactor 2019-04-04 13:19:12.256821887 +0200 ++++ openssh/openbsd-compat/port-linux-sshd.c 2019-04-04 13:19:12.276822078 +0200 @@ -49,10 +49,6 @@ #include #endif @@ -99,7 +92,7 @@ index 646f0887..291b569a 100644 /* Wrapper around is_selinux_enabled() to log its return value once only */ int sshd_selinux_enabled(void) -@@ -222,7 +218,8 @@ get_user_context(const char *sename, const char *role, const char *lvl, +@@ -223,7 +218,8 @@ get_user_context(const char *sename, con } static void @@ -109,7 +102,7 @@ index 646f0887..291b569a 100644 { *role = NULL; *level = NULL; -@@ -240,8 +237,8 @@ ssh_selinux_get_role_level(char **role, const char **level) +@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role, /* Return the default security context for the given username */ static int @@ -120,7 +113,7 @@ index 646f0887..291b569a 100644 { char *sename, *lvl; char *role; -@@ -249,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname, int r = 0; context_t con = NULL; @@ -129,7 +122,7 @@ index 646f0887..291b569a 100644 #ifdef HAVE_GETSEUSERBYNAME if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { -@@ -271,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname, if (r == 0) { /* If launched from xinetd, we must use current level */ @@ -138,7 +131,7 @@ index 646f0887..291b569a 100644 security_context_t sshdsc=NULL; if (getcon_raw(&sshdsc) < 0) -@@ -332,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int @@ -148,7 +141,7 @@ index 646f0887..291b569a 100644 { const char *reqlvl; char *role; -@@ -341,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) +@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it debug3_f("setting execution context"); @@ -162,7 +155,7 @@ index 646f0887..291b569a 100644 use_current = "1"; } else { use_current = ""; -@@ -361,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) +@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it } static int @@ -175,7 +168,7 @@ index 646f0887..291b569a 100644 } static int -@@ -373,25 +372,28 @@ do_setenv(char *name, const char *value) +@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value) } int @@ -209,7 +202,7 @@ index 646f0887..291b569a 100644 switch (security_getenforce()) { case -1: fatal_f("security_getenforce() failed"); -@@ -407,7 +409,7 @@ sshd_selinux_setup_exec_context(char *pwname) +@@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw debug3_f("setting execution context"); @@ -218,26 +211,10 @@ index 646f0887..291b569a 100644 if (r >= 0) { r = setexeccon(user_ctx); if (r < 0) { -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index 7f8ba200..3cd7da6a 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -25,8 +25,8 @@ void ssh_selinux_setfscreatecon(const char *); - - int sshd_selinux_enabled(void); - void sshd_selinux_copy_context(void); --void sshd_selinux_setup_exec_context(char *); --int sshd_selinux_setup_env_variables(void); -+void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int); -+int sshd_selinux_setup_env_variables(int inetd, void *); - void sshd_selinux_change_privsep_preauth_context(void); - #endif - -diff --git a/platform.c b/platform.c -index 0d12f311..f0800b1f 100644 ---- a/platform.c -+++ b/platform.c -@@ -33,6 +33,8 @@ +diff -up openssh/platform.c.refactor openssh/platform.c +--- openssh/platform.c.refactor 2019-04-04 13:19:12.204821389 +0200 ++++ openssh/platform.c 2019-04-04 13:19:12.277822088 +0200 +@@ -32,6 +32,8 @@ #include "openbsd-compat/openbsd-compat.h" extern ServerOptions options; @@ -246,7 +223,7 @@ index 0d12f311..f0800b1f 100644 /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ int -@@ -140,7 +142,9 @@ platform_setusercontext_post_groups(struct passwd *pw) +@@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX @@ -257,37 +234,10 @@ index 0d12f311..f0800b1f 100644 #endif } -diff --git a/sshconnect.c b/sshconnect.c -index c86182d1..04084810 100644 ---- a/sshconnect.c -+++ b/sshconnect.c -@@ -925,7 +925,7 @@ load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template, - - if ((pid = subprocess(tag, command, ac, av, &f, - SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH| -- SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0) -+ SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL, 0, NULL)) == 0) - goto out; - - load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1); -diff --git a/sshd-auth.c b/sshd-auth.c -index e4a8edfd..897db9b4 100644 ---- a/sshd-auth.c -+++ b/sshd-auth.c -@@ -122,7 +122,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; - int debug_flag = 0; - - /* Flag indicating that the daemon is being started from inetd. */ --static int inetd_flag = 0; -+int inetd_flag = 0; - - /* Saved arguments to main(). */ - static char **saved_argv; -diff --git a/sshd-session.c b/sshd-session.c -index 9342e416..81d30152 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -136,7 +136,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; +diff -up openssh/sshd-session.c.refactor openssh/sshd-session.c +--- openssh/sshd-session.c.refactor 2019-04-04 13:19:12.275822068 +0200 ++++ openssh/sshd-session.c 2019-04-04 13:19:51.270195262 +0200 +@@ -158,7 +158,7 @@ int debug_flag = 0; int debug_flag = 0; /* Flag indicating that the daemon is being started from inetd. */ @@ -296,7 +246,7 @@ index 9342e416..81d30152 100644 /* debug goes to stderr unless inetd_flag is set */ static int log_stderr = 0; -@@ -1359,7 +1359,9 @@ main(int ac, char **av) +@@ -2192,7 +2192,9 @@ main(int ac, char **av) } #endif #ifdef WITH_SELINUX @@ -307,6 +257,15 @@ index 9342e416..81d30152 100644 #endif #ifdef USE_PAM if (options.use_pam) { --- -2.49.0 - +diff -up openssh/sshconnect.c.refactor openssh/sshconnect.c +--- openssh/sshconnect.c.refactor 2021-02-24 00:12:03.065325046 +0100 ++++ openssh/sshconnect.c 2021-02-24 00:12:12.126449544 +0100 +@@ -892,7 +892,7 @@ load_hostkeys_command(struct hostkeys *h + + if ((pid = subprocess(tag, command, ac, av, &f, + SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH| +- SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0) ++ SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL, 0, NULL)) == 0) + goto out; + + load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1); diff --git a/0042-openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch similarity index 67% rename from 0042-openssh-7.7p1-fips.patch rename to openssh-7.7p1-fips.patch index 9a81cc0..5d8da08 100644 --- a/0042-openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,34 +1,6 @@ -From 79f9b2763d85ec592cb7e54dcf1c695d8dd138b1 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 28 Aug 2025 14:01:38 +0200 -Subject: [PATCH 42/54] openssh-7.7p1-fips - ---- - dh.c | 41 ++++++++++++++++++++++ - dh.h | 1 + - kex-names.c | 6 +++- - kex.c | 3 +- - kexgen.c | 74 ++++++++++++++++++++++++++++++++-------- - kexgexc.c | 5 +++ - myproposal.h | 33 ++++++++++++++++++ - readconf.c | 16 ++++++--- - sandbox-seccomp-filter.c | 3 ++ - servconf.c | 16 ++++++--- - ssh-ed25519.c | 9 +++++ - ssh-gss.h | 5 +++ - ssh-keygen.c | 22 ++++++++++-- - ssh-rsa.c | 3 ++ - ssh.c | 5 +++ - sshconnect2.c | 9 ++++- - sshd-session.c | 1 + - sshd.c | 13 +++++++ - sshkey.c | 37 ++++++++++++++++++++ - 19 files changed, 272 insertions(+), 30 deletions(-) - -diff --git a/dh.c b/dh.c -index 168dea1dd..8c9a29fa7 100644 ---- a/dh.c -+++ b/dh.c +diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c +--- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/dh.c 2021-05-06 12:12:10.107634472 +0200 @@ -36,6 +36,7 @@ #include @@ -37,7 +9,7 @@ index 168dea1dd..8c9a29fa7 100644 #include "dh.h" #include "pathnames.h" -@@ -164,6 +165,12 @@ choose_dh(int min, int wantbits, int max) +@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max int best, bestcount, which, linenum; struct dhgroup dhg; @@ -50,7 +22,7 @@ index 168dea1dd..8c9a29fa7 100644 if ((f = fopen(get_moduli_filename(), "r")) == NULL) { logit("WARNING: could not open %s (%s), using fixed modulus", get_moduli_filename(), strerror(errno)); -@@ -502,4 +509,38 @@ dh_estimate(int bits) +@@ -502,4 +508,38 @@ dh_estimate(int bits) return 8192; } @@ -89,10 +61,9 @@ index 168dea1dd..8c9a29fa7 100644 +} + #endif /* WITH_OPENSSL */ -diff --git a/dh.h b/dh.h -index c6326a39d..e51e292b8 100644 ---- a/dh.h -+++ b/dh.h +diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h +--- openssh-8.6p1/dh.h.fips 2021-05-06 12:08:36.498926877 +0200 ++++ openssh-8.6p1/dh.h 2021-05-06 12:11:28.393298005 +0200 @@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); int dh_gen_key(DH *, int); @@ -101,11 +72,10 @@ index c6326a39d..e51e292b8 100644 u_int dh_estimate(int); void dh_set_moduli_file(const char *); -diff --git a/kex-names.c b/kex-names.c -index 6c0b7c2b3..cd3902ad2 100644 ---- a/kex-names.c -+++ b/kex-names.c -@@ -33,6 +33,7 @@ +diff -up openssh-8.6p1/kex-names.c.fips openssh-8.6p1/kex-names.c +--- openssh-8.6p1/kex-names.c.fips 2021-05-06 12:08:36.489926807 +0200 ++++ openssh-8.6p1/kex-names.c 2021-05-06 12:08:36.498926877 +0200 +@@ -39,6 +39,7 @@ #ifdef WITH_OPENSSL #include @@ -113,7 +83,7 @@ index 6c0b7c2b3..cd3902ad2 100644 #include #endif -@@ -206,7 +207,10 @@ kex_names_valid(const char *names) +@@ -203,7 +203,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -125,31 +95,508 @@ index 6c0b7c2b3..cd3902ad2 100644 free(s); return 0; } -diff --git a/kex.c b/kex.c -index 62f607d6f..71fbe5cbe 100644 ---- a/kex.c -+++ b/kex.c -@@ -40,6 +40,7 @@ - #ifdef WITH_OPENSSL - #include - #include -+#include - # ifdef HAVE_EVP_KDF_CTX_NEW - # include - # include -@@ -109,7 +110,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], +diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c +--- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/kexgexc.c 2021-05-06 12:08:36.498926877 +0200 +@@ -28,6 +28,7 @@ - /* Append EXT_INFO signalling to KexAlgorithms */ - if (kexalgos == NULL) -- kexalgos = defprop[PROPOSAL_KEX_ALGS]; -+ kexalgos = FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : defprop[PROPOSAL_KEX_ALGS]; - if ((cp = kex_names_cat(kexalgos, ssh->kex->server ? - "ext-info-s,kex-strict-s-v00@openssh.com" : - "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL) -diff --git a/kexgen.c b/kexgen.c -index 15df591ca..eecdceba2 100644 ---- a/kexgen.c -+++ b/kexgen.c + #ifdef WITH_OPENSSL + ++#include + #include + + #include +@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32 + r = SSH_ERR_ALLOC_FAIL; + goto out; + } ++ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) { ++ r = SSH_ERR_INVALID_ARGUMENT; ++ goto out; ++ } + p = g = NULL; /* belong to kex->dh now */ + + /* generate and send 'e', client DH public key */ +diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h +--- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200 +@@ -57,6 +57,18 @@ + "rsa-sha2-512," \ + "rsa-sha2-256" + ++#define KEX_FIPS_PK_ALG \ ++ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ ++ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \ ++ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ ++ "rsa-sha2-512-cert-v01@openssh.com," \ ++ "rsa-sha2-256-cert-v01@openssh.com," \ ++ "ecdsa-sha2-nistp256," \ ++ "ecdsa-sha2-nistp384," \ ++ "ecdsa-sha2-nistp521," \ ++ "rsa-sha2-512," \ ++ "rsa-sha2-256" ++ + #define KEX_SERVER_ENCRYPT \ + "chacha20-poly1305@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ +@@ -78,6 +92,27 @@ + + #define KEX_CLIENT_MAC KEX_SERVER_MAC + ++#define KEX_FIPS_ENCRYPT \ ++ "aes128-ctr,aes192-ctr,aes256-ctr," \ ++ "aes128-cbc,3des-cbc," \ ++ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ ++ "aes128-gcm@openssh.com,aes256-gcm@openssh.com" ++#define KEX_DEFAULT_KEX_FIPS \ ++ "ecdh-sha2-nistp256," \ ++ "ecdh-sha2-nistp384," \ ++ "ecdh-sha2-nistp521," \ ++ "diffie-hellman-group-exchange-sha256," \ ++ "diffie-hellman-group16-sha512," \ ++ "diffie-hellman-group18-sha512," \ ++ "diffie-hellman-group14-sha256" ++#define KEX_FIPS_MAC \ ++ "hmac-sha1," \ ++ "hmac-sha2-256," \ ++ "hmac-sha2-512," \ ++ "hmac-sha1-etm@openssh.com," \ ++ "hmac-sha2-256-etm@openssh.com," \ ++ "hmac-sha2-512-etm@openssh.com" ++ + /* Not a KEX value, but here so all the algorithm defaults are together */ + #define SSH_ALLOWED_CA_SIGALGS \ + "ssh-ed25519," \ +diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c +--- openssh-8.6p1/readconf.c.fips 2021-05-06 12:08:36.428926336 +0200 ++++ openssh-8.6p1/readconf.c 2021-05-06 12:08:36.499926885 +0200 +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #ifdef USE_SYSTEM_GLOB + # include + #else +@@ -2538,11 +2538,16 @@ fill_default_options(Options * options) + all_key = sshkey_alg_list(0, 0, 1, ','); + all_sig = sshkey_alg_list(0, 1, 1, ','); + /* remove unsupported algos from default lists */ +- def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher); +- def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac); +- def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex); +- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); +- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); ++ def_cipher = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher); ++ def_mac = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac); ++ def_kex = match_filter_allowlist((FIPS_mode() ? ++ KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex); ++ def_key = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); ++ def_sig = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); + #define ASSEMBLE(what, defaults, all) \ + do { \ + if ((r = kex_assemble_names(&options->what, \ +diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c +--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-05-06 12:08:36.463926606 +0200 ++++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-06 12:08:36.499926885 +0200 +@@ -160,6 +160,9 @@ static const struct sock_filter preauth_ + #ifdef __NR_open + SC_DENY(__NR_open, EACCES), + #endif ++#ifdef __NR_socket ++ SC_DENY(__NR_socket, EACCES), ++#endif + #ifdef __NR_openat + SC_DENY(__NR_openat, EACCES), + #endif +diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.fips 2021-05-06 12:08:36.455926545 +0200 ++++ openssh-8.6p1/servconf.c 2021-05-06 12:08:36.500926893 +0200 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #ifdef HAVE_UTIL_H + #include + #endif +@@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o) + all_key = sshkey_alg_list(0, 0, 1, ','); + all_sig = sshkey_alg_list(0, 1, 1, ','); + /* remove unsupported algos from default lists */ +- def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher); +- def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac); +- def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex); +- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); +- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); ++ def_cipher = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher); ++ def_mac = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac); ++ def_kex = match_filter_allowlist((FIPS_mode() ? ++ KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex); ++ def_key = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); ++ def_sig = match_filter_allowlist((FIPS_mode() ? ++ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); + #define ASSEMBLE(what, defaults, all) \ + do { \ + if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ +diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c +--- openssh-8.6p1/ssh.c.fips 2021-05-06 12:08:36.467926637 +0200 ++++ openssh-8.6p1/ssh.c 2021-05-06 12:08:36.500926893 +0200 +@@ -77,6 +77,7 @@ + #include + #include + #endif ++#include + #include "openbsd-compat/openssl-compat.h" + #include "openbsd-compat/sys-queue.h" + +@@ -1516,6 +1517,10 @@ main(int ac, char **av) + exit(0); + } + ++ if (FIPS_mode()) { ++ debug("FIPS mode initialized"); ++ } ++ + /* Expand SecurityKeyProvider if it refers to an environment variable */ + if (options.sk_provider != NULL && *options.sk_provider == '$' && + strlen(options.sk_provider) > 1) { +diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c +--- openssh-8.6p1/sshconnect2.c.fips 2021-05-06 12:08:36.485926777 +0200 ++++ openssh-8.6p1/sshconnect2.c 2021-05-06 12:08:36.501926900 +0200 +@@ -45,6 +45,8 @@ + #include + #endif + ++#include ++ + #include "openbsd-compat/sys-queue.h" + + #include "xmalloc.h" +@@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st + + #if defined(GSSAPI) && defined(WITH_OPENSSL) + if (options.gss_keyex) { +- /* Add the GSSAPI mechanisms currently supported on this +- * client to the key exchange algorithm proposal */ +- orig = myproposal[PROPOSAL_KEX_ALGS]; +- +- if (options.gss_server_identity) { +- gss_host = xstrdup(options.gss_server_identity); +- } else if (options.gss_trust_dns) { +- gss_host = remote_hostname(ssh); +- /* Fall back to specified host if we are using proxy command +- * and can not use DNS on that socket */ +- if (strcmp(gss_host, "UNKNOWN") == 0) { +- free(gss_host); ++ if (FIPS_mode()) { ++ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); ++ options.gss_keyex = 0; ++ } else { ++ /* Add the GSSAPI mechanisms currently supported on this ++ * client to the key exchange algorithm proposal */ ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ ++ if (options.gss_server_identity) { ++ gss_host = xstrdup(options.gss_server_identity); ++ } else if (options.gss_trust_dns) { ++ gss_host = remote_hostname(ssh); ++ /* Fall back to specified host if we are using proxy command ++ * and can not use DNS on that socket */ ++ if (strcmp(gss_host, "UNKNOWN") == 0) { ++ free(gss_host); ++ gss_host = xstrdup(host); ++ } ++ } else { + gss_host = xstrdup(host); + } +- } else { +- gss_host = xstrdup(host); +- } + +- gss = ssh_gssapi_client_mechanisms(gss_host, +- options.gss_client_identity, options.gss_kex_algorithms); +- if (gss) { +- debug("Offering GSSAPI proposal: %s", gss); +- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], +- "%s,%s", gss, orig); +- +- /* If we've got GSSAPI algorithms, then we also support the +- * 'null' hostkey, as a last resort */ +- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; +- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], +- "%s,null", orig); ++ gss = ssh_gssapi_client_mechanisms(gss_host, ++ options.gss_client_identity, options.gss_kex_algorithms); ++ if (gss) { ++ debug("Offering GSSAPI proposal: %s", gss); ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ ++ /* If we've got GSSAPI algorithms, then we also support the ++ * 'null' hostkey, as a last resort */ ++ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], ++ "%s,null", orig); ++ } + } + } + #endif +diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.fips 2021-05-06 12:08:36.493926838 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-06 12:13:56.501492639 +0200 +@@ -66,6 +66,7 @@ + #endif + #include + #include ++#include + #include + #include + #include +@@ -77,6 +78,7 @@ + #ifdef WITH_OPENSSL + #include + #include ++#include + #include "openbsd-compat/openssl-compat.h" + #endif + +@@ -1931,6 +1931,13 @@ main(int ac, char **av) + &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) + do_log2_r(r, ll, "Unable to load host key \"%s\"", + options.host_key_files[i]); ++ if (FIPS_mode() && key != NULL && (sshkey_type_plain(key->type) == KEY_ED25519_SK ++ || sshkey_type_plain(key->type) == KEY_ED25519)) { ++ logit_f("sshd: Ed25519 keys are not allowed in FIPS mode, skipping %s", options.host_key_files[i]); ++ sshkey_free(key); ++ key = NULL; ++ continue; ++ } + if (sshkey_is_sk(key) && + key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { + debug("host key %s requires user presence, ignoring", +@@ -2110,6 +2113,10 @@ main(int ac, char **av) + /* Reinitialize the log (because of the fork above). */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + ++ if (FIPS_mode()) { ++ debug("FIPS mode initialized"); ++ } ++ + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. +diff -up openssh-8.6p1/sshd-session.c.fips openssh-8.6p1/sshd-session.c +--- a/sshd-session.c.fips 2021-05-06 12:08:36.493926838 +0200 ++++ b/sshd-session.c 2021-05-06 12:13:56.501492639 +0200 +@@ -78,6 +79,7 @@ + #include + #include + #include ++#include + #include "openbsd-compat/openssl-compat.h" + #endif + +@@ -2506,10 +2513,14 @@ do_ssh2_kex(struct ssh *ssh) + if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) + orig = NULL; + +- if (options.gss_keyex) +- gss = ssh_gssapi_server_mechanisms(); +- else +- gss = NULL; ++ if (options.gss_keyex) { ++ if (FIPS_mode()) { ++ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); ++ options.gss_keyex = 0; ++ } else { ++ gss = ssh_gssapi_server_mechanisms(); ++ } ++ } + + if (gss && orig) + xasprintf(&newstr, "%s,%s", gss, orig); +diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c +--- openssh-8.6p1/sshkey.c.fips 2021-05-06 12:08:36.493926838 +0200 ++++ openssh-8.6p1/sshkey.c 2021-05-06 12:08:36.502926908 +0200 +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #endif + + #include "crypto_api.h" +@@ -57,6 +58,7 @@ + #define SSHKEY_INTERNAL + #include "sshkey.h" + #include "match.h" ++#include "log.h" + #include "ssh-sk.h" + + #ifdef WITH_XMSS +@@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai + impl = keyimpls[i]; + if (impl->name == NULL || impl->type == KEY_NULL) + continue; ++ if (FIPS_mode()) { ++ switch (impl->type) { ++ case KEY_ED25519: ++ case KEY_ED25519_SK: ++ case KEY_ED25519_CERT: ++ case KEY_ED25519_SK_CERT: ++ continue; ++ break; ++ default: ++ break; ++ } ++ } + if (!include_sigonly && impl->sigonly) + continue; + if ((certs_only && !impl->cert) || (plain_only && impl->cert)) +@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c + return SSH_ERR_EC_CURVE_MISMATCH; + } + ++ switch (type) { ++ case KEY_ED25519: ++ case KEY_ED25519_SK: ++ case KEY_ED25519_CERT: ++ case KEY_ED25519_SK_CERT: ++ if (FIPS_mode()) { ++ sshkey_free(k); ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++ break; ++ default: ++ break; ++ } + /* Fill in ret from parsed key */ + sshkey_free_contents(ret); + *ret = *k; +@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key, + *lenp = 0; + if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) + return SSH_ERR_INVALID_ARGUMENT; ++ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++ /* Fallthrough */ + if ((impl = sshkey_impl_from_key(key)) == NULL) + return SSH_ERR_KEY_TYPE_UNKNOWN; + if ((r = sshkey_unshield_private(key)) != 0) +@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key, + *detailsp = NULL; + if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) + return SSH_ERR_INVALID_ARGUMENT; ++ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) { ++ logit_f("Ed25519 keys are not allowed in FIPS mode"); ++ return SSH_ERR_INVALID_ARGUMENT; ++ } + if ((impl = sshkey_impl_from_key(key)) == NULL) + return SSH_ERR_KEY_TYPE_UNKNOWN; + return impl->funcs->verify(key, sig, siglen, data, dlen, +diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c +--- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200 ++++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200 +@@ -20,6 +20,7 @@ + + #ifdef WITH_OPENSSL + #include ++#include + #include + #include "openbsd-compat/openssl-compat.h" + #endif +@@ -69,6 +69,7 @@ + #include "cipher.h" + + #define DEFAULT_KEY_TYPE_NAME "ed25519" ++#define FIPS_DEFAULT_KEY_TYPE_NAME "rsa" + + /* + * Default number of bits in the RSA, DSA and ECDSA keys. These value can be +@@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na + #endif + } + #ifdef WITH_OPENSSL ++ if (FIPS_mode()) { ++ if (type == KEY_DSA) ++ fatal("DSA keys are not allowed in FIPS mode"); ++ if (type == KEY_ED25519 || type == KEY_ED25519_SK) ++ fatal("ED25519 keys are not allowed in FIPS mode"); ++ } + switch (type) { + case KEY_DSA: + if (*bitsp != 1024) +@@ -266,7 +267,7 @@ ask_filename(struct passwd *pw, const ch + char *name = NULL; + + if (key_type_name == NULL) +- name = _PATH_SSH_CLIENT_ID_ED25519; ++ name = FIPS_mode() ? _PATH_SSH_CLIENT_ID_RSA : _PATH_SSH_CLIENT_ID_ED25519; + else { + switch (sshkey_type_from_shortname(key_type_name)) { + #ifdef WITH_DSA +@@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw) + first = 1; + printf("%s: generating new host keys: ", __progname); + } ++ type = sshkey_type_from_shortname(key_types[i].key_type); ++ ++ /* Skip the keys that are not supported in FIPS mode */ ++ if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) { ++ logit("Skipping %s key in FIPS mode", ++ key_types[i].key_type_display); ++ goto next; ++ } ++ + printf("%s ", key_types[i].key_type_display); + fflush(stdout); +- type = sshkey_type_from_shortname(key_types[i].key_type); + if ((fd = mkstemp(prv_tmp)) == -1) { + error("Could not save your private key in %s: %s", + prv_tmp, strerror(errno)); +@@ -3830,7 +3831,7 @@ main(int argc, char **argv) + } + + if (key_type_name == NULL) +- key_type_name = DEFAULT_KEY_TYPE_NAME; ++ key_type_name = FIPS_mode() ? FIPS_DEFAULT_KEY_TYPE_NAME : DEFAULT_KEY_TYPE_NAME; + + type = sshkey_type_from_shortname(key_type_name); + type_bits_valid(type, key_type_name, &bits); +diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c +--- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200 ++++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200 +@@ -33,6 +33,7 @@ + + #include + #include ++#include + + #include + #include +@@ -1705,6 +1707,8 @@ ssh_rsa_generate(u_int bits, RSA + goto out; + } + if (EVP_PKEY_keygen(ctx, &res) <= 0 || res == 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; + } +diff -up openssh-9.9p1/kexgen.c.xxx openssh-9.9p1/kexgen.c +--- openssh-9.9p1/kexgen.c.xxx 2024-10-09 10:35:56.285946080 +0200 ++++ openssh-9.9p1/kexgen.c 2024-10-09 10:41:52.792597194 +0200 @@ -31,6 +31,7 @@ #include #include @@ -190,7 +637,7 @@ index 15df591ca..eecdceba2 100644 break; default: r = SSH_ERR_INVALID_ARGUMENT; -@@ -189,15 +205,30 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) +@@ -189,15 +205,30 @@ input_kex_gen_reply(int type, u_int32_t break; #endif case KEX_C25519_SHA256: @@ -226,7 +673,7 @@ index 15df591ca..eecdceba2 100644 break; default: r = SSH_ERR_INVALID_ARGUMENT; -@@ -312,16 +343,31 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) +@@ -312,16 +343,31 @@ input_kex_gen_init(int type, u_int32_t s break; #endif case KEX_C25519_SHA256: @@ -264,166 +711,9 @@ index 15df591ca..eecdceba2 100644 break; default: r = SSH_ERR_INVALID_ARGUMENT; -diff --git a/kexgexc.c b/kexgexc.c -index e99e0cf21..4c3feae09 100644 ---- a/kexgexc.c -+++ b/kexgexc.c -@@ -28,6 +28,7 @@ - - #ifdef WITH_OPENSSL - -+#include - #include - - #include -@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh) - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -+ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) { -+ r = SSH_ERR_INVALID_ARGUMENT; -+ goto out; -+ } - p = g = NULL; /* belong to kex->dh now */ - - /* generate and send 'e', client DH public key */ -diff --git a/myproposal.h b/myproposal.h -index 8fe9276c2..3e0ec6826 100644 ---- a/myproposal.h -+++ b/myproposal.h -@@ -58,6 +58,18 @@ - "rsa-sha2-512," \ - "rsa-sha2-256" - -+#define KEX_FIPS_PK_ALG \ -+ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ -+ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \ -+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ -+ "rsa-sha2-512-cert-v01@openssh.com," \ -+ "rsa-sha2-256-cert-v01@openssh.com," \ -+ "ecdsa-sha2-nistp256," \ -+ "ecdsa-sha2-nistp384," \ -+ "ecdsa-sha2-nistp521," \ -+ "rsa-sha2-512," \ -+ "rsa-sha2-256" -+ - #define KEX_SERVER_ENCRYPT \ - "chacha20-poly1305@openssh.com," \ - "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \ -@@ -79,6 +91,27 @@ - - #define KEX_CLIENT_MAC KEX_SERVER_MAC - -+#define KEX_FIPS_ENCRYPT \ -+ "aes128-ctr,aes192-ctr,aes256-ctr," \ -+ "aes128-cbc,3des-cbc," \ -+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ -+ "aes128-gcm@openssh.com,aes256-gcm@openssh.com" -+#define KEX_DEFAULT_KEX_FIPS \ -+ "ecdh-sha2-nistp256," \ -+ "ecdh-sha2-nistp384," \ -+ "ecdh-sha2-nistp521," \ -+ "diffie-hellman-group-exchange-sha256," \ -+ "diffie-hellman-group16-sha512," \ -+ "diffie-hellman-group18-sha512," \ -+ "diffie-hellman-group14-sha256" -+#define KEX_FIPS_MAC \ -+ "hmac-sha1," \ -+ "hmac-sha2-256," \ -+ "hmac-sha2-512," \ -+ "hmac-sha1-etm@openssh.com," \ -+ "hmac-sha2-256-etm@openssh.com," \ -+ "hmac-sha2-512-etm@openssh.com" -+ - /* Not a KEX value, but here so all the algorithm defaults are together */ - #define SSH_ALLOWED_CA_SIGALGS \ - "ssh-ed25519," \ -diff --git a/readconf.c b/readconf.c -index f340bf501..ea9d293c3 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - #ifdef USE_SYSTEM_GLOB - # include - #else -@@ -3043,11 +3044,16 @@ fill_default_options(Options * options) - all_key = sshkey_alg_list(0, 0, 1, ','); - all_sig = sshkey_alg_list(0, 1, 1, ','); - /* remove unsupported algos from default lists */ -- def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher); -- def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac); -- def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex); -- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); -- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); -+ def_cipher = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher); -+ def_mac = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac); -+ def_kex = match_filter_allowlist((FIPS_mode() ? -+ KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex); -+ def_key = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); -+ def_sig = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); - #define ASSEMBLE(what, defaults, all) \ - do { \ - if ((r = kex_assemble_names(&options->what, \ -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 1fabf99d0..ccb61586e 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -230,6 +230,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_open - SC_DENY(__NR_open, EACCES), - #endif -+#ifdef __NR_socket -+ SC_DENY(__NR_socket, EACCES), -+#endif - #ifdef __NR_openat - SC_DENY(__NR_openat, EACCES), - #endif -diff --git a/servconf.c b/servconf.c -index 84891544b..8b708cbf4 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - #ifdef HAVE_UTIL_H - #include - #endif -@@ -247,11 +248,16 @@ assemble_algorithms(ServerOptions *o) - all_key = sshkey_alg_list(0, 0, 1, ','); - all_sig = sshkey_alg_list(0, 1, 1, ','); - /* remove unsupported algos from default lists */ -- def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher); -- def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac); -- def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex); -- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); -- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); -+ def_cipher = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher); -+ def_mac = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac); -+ def_kex = match_filter_allowlist((FIPS_mode() ? -+ KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex); -+ def_key = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); -+ def_sig = match_filter_allowlist((FIPS_mode() ? -+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); - #define ASSEMBLE(what, defaults, all) \ - do { \ - if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ -diff --git a/ssh-ed25519.c b/ssh-ed25519.c -index 22d8db026..41942f4e5 100644 ---- a/ssh-ed25519.c -+++ b/ssh-ed25519.c +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 @@ -432,7 +722,7 @@ index 22d8db026..41942f4e5 100644 #include "log.h" #include "sshbuf.h" -@@ -164,6 +165,10 @@ ssh_ed25519_sign(struct sshkey *key, +@@ -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; @@ -443,7 +733,7 @@ index 22d8db026..41942f4e5 100644 smlen = slen = datalen + crypto_sign_ed25519_BYTES; if ((sig = malloc(slen)) == NULL) return SSH_ERR_ALLOC_FAIL; -@@ -221,6 +226,10 @@ ssh_ed25519_verify(const struct sshkey *key, +@@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey * dlen >= INT_MAX - crypto_sign_ed25519_BYTES || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; @@ -454,310 +744,23 @@ index 22d8db026..41942f4e5 100644 if ((b = sshbuf_from(sig, siglen)) == NULL) return SSH_ERR_ALLOC_FAIL; -diff --git a/ssh-gss.h b/ssh-gss.h -index a894e23c9..329dc9da0 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -88,6 +88,11 @@ extern char **k5users_allowed_cmds; - KEX_GSS_GRP14_SHA1_ID "," \ - KEX_GSS_GEX_SHA1_ID - -+#define GSS_KEX_DEFAULT_KEX_FIPS \ -+ KEX_GSS_GRP14_SHA256_ID "," \ -+ KEX_GSS_GRP16_SHA512_ID "," \ -+ KEX_GSS_NISTP256_SHA256_ID -+ - #include "digest.h" /* SSH_DIGEST_MAX_LENGTH */ - - typedef struct { -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 16cff9473..792aafde0 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -20,6 +20,7 @@ - +diff -up openssh-9.9p1/kex.c.xxx openssh-9.9p1/kex.c +--- openssh-9.9p1/kex.c.xxx 2024-10-11 12:44:08.087426597 +0200 ++++ openssh-9.9p1/kex.c 2024-10-11 14:00:10.404714521 +0200 +@@ -40,6 +40,7 @@ #ifdef WITH_OPENSSL - #include + #include + #include +#include - #include - #include "openbsd-compat/openssl-compat.h" - #endif -@@ -68,6 +69,7 @@ - #include "cipher.h" + # ifdef HAVE_EVP_KDF_CTX_NEW + # include + # include +@@ -109,7 +110,7 @@ kex_proposal_populate_entries(struct ssh - #define DEFAULT_KEY_TYPE_NAME "ed25519" -+#define FIPS_DEFAULT_KEY_TYPE_NAME "rsa" - - /* - * Default number of bits in the RSA, DSA and ECDSA keys. These value can be -@@ -202,6 +204,12 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) - #endif - } - #ifdef WITH_OPENSSL -+ if (FIPS_mode()) { -+ if (type == KEY_DSA) -+ fatal("DSA keys are not allowed in FIPS mode"); -+ if (type == KEY_ED25519 || type == KEY_ED25519_SK) -+ fatal("ED25519 keys are not allowed in FIPS mode"); -+ } - switch (type) { - case KEY_DSA: - if (*bitsp != 1024) -@@ -259,7 +267,7 @@ ask_filename(struct passwd *pw, const char *prompt) - char *name = NULL; - - if (key_type_name == NULL) -- name = _PATH_SSH_CLIENT_ID_ED25519; -+ name = FIPS_mode() ? _PATH_SSH_CLIENT_ID_RSA : _PATH_SSH_CLIENT_ID_ED25519; - else { - switch (sshkey_type_from_shortname(key_type_name)) { - #ifdef WITH_DSA -@@ -1144,9 +1152,17 @@ do_gen_all_hostkeys(struct passwd *pw) - first = 1; - printf("%s: generating new host keys: ", __progname); - } -+ type = sshkey_type_from_shortname(key_types[i].key_type); -+ -+ /* Skip the keys that are not supported in FIPS mode */ -+ if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) { -+ logit("Skipping %s key in FIPS mode", -+ key_types[i].key_type_display); -+ goto next; -+ } -+ - printf("%s ", key_types[i].key_type_display); - fflush(stdout); -- type = sshkey_type_from_shortname(key_types[i].key_type); - if ((fd = mkstemp(prv_tmp)) == -1) { - error("Could not save your private key in %s: %s", - prv_tmp, strerror(errno)); -@@ -3849,7 +3865,7 @@ main(int argc, char **argv) - } - - if (key_type_name == NULL) -- key_type_name = DEFAULT_KEY_TYPE_NAME; -+ key_type_name = FIPS_mode() ? FIPS_DEFAULT_KEY_TYPE_NAME : DEFAULT_KEY_TYPE_NAME; - - type = sshkey_type_from_shortname(key_type_name); - type_bits_valid(type, key_type_name, &bits); -diff --git a/ssh-rsa.c b/ssh-rsa.c -index 3ad1fddc4..6c2f771a3 100644 ---- a/ssh-rsa.c -+++ b/ssh-rsa.c -@@ -23,6 +23,7 @@ - - #include - #include -+#include - - #include - #include -@@ -142,6 +143,8 @@ ssh_rsa_generate(struct sshkey *k, int bits) - goto out; - } - if (EVP_PKEY_keygen(ctx, &res) <= 0 || res == 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; - } -diff --git a/ssh.c b/ssh.c -index 98b103c9e..abc8b8439 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -78,6 +78,7 @@ - #include - #include - #endif -+#include - #include "openbsd-compat/openssl-compat.h" - #include "openbsd-compat/sys-queue.h" - -@@ -1642,6 +1643,10 @@ main(int ac, char **av) - exit(0); - } - -+ if (FIPS_mode()) { -+ debug("FIPS mode initialized"); -+ } -+ - /* Expand SecurityKeyProvider if it refers to an environment variable */ - if (options.sk_provider != NULL && *options.sk_provider == '$' && - strlen(options.sk_provider) > 1) { -diff --git a/sshconnect2.c b/sshconnect2.c -index 0af15bcc1..3e02f485d 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -45,6 +45,8 @@ - #include - #endif - -+#include -+ - #include "openbsd-compat/sys-queue.h" - - #include "xmalloc.h" -@@ -262,6 +264,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - - #if defined(GSSAPI) && defined(WITH_OPENSSL) - if (options.gss_keyex) { -+ char * gss_kex_filtered = FIPS_mode() ? -+ match_filter_allowlist(options.gss_kex_algorithms, GSS_KEX_DEFAULT_KEX_FIPS) : xstrdup(options.gss_kex_algorithms); -+ - /* Add the GSSAPI mechanisms currently supported on this - * client to the key exchange algorithm proposal */ - orig = myproposal[PROPOSAL_KEX_ALGS]; -@@ -281,7 +286,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - } - - gss = ssh_gssapi_client_mechanisms(gss_host, -- options.gss_client_identity, options.gss_kex_algorithms); -+ options.gss_client_identity, gss_kex_filtered); -+ free(gss_kex_filtered); -+ - if (gss) { - debug("Offering GSSAPI proposal: %s", gss); - xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -diff --git a/sshd-session.c b/sshd-session.c -index a808ac9a6..a67a78391 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -62,6 +62,7 @@ - #include - #include - #include -+#include - #include "openbsd-compat/openssl-compat.h" - #endif - -diff --git a/sshd.c b/sshd.c -index 8a99f0b29..5ff0b5ff0 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -52,6 +52,7 @@ - #endif - #include - #include -+#include - #include - #include - #include -@@ -63,6 +64,7 @@ - #ifdef WITH_OPENSSL - #include - #include -+#include - #include "openbsd-compat/openssl-compat.h" - #endif - -@@ -1611,6 +1613,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", -@@ -1830,6 +1839,10 @@ main(int ac, char **av) - /* Reinitialize the log (because of the fork above). */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); - -+ if (FIPS_mode()) { -+ debug("FIPS mode initialized"); -+ } -+ - /* - * Chdir to the root directory so that the current disk can be - * unmounted if desired. -diff --git a/sshkey.c b/sshkey.c -index 4e41a78c7..ca1cdb642 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - #endif - - #include "crypto_api.h" -@@ -59,6 +60,7 @@ - #define SSHKEY_INTERNAL - #include "sshkey.h" - #include "match.h" -+#include "log.h" - #include "ssh-sk.h" - - #ifdef WITH_XMSS -@@ -408,6 +410,18 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) - impl = keyimpls[i]; - if (impl->name == NULL || impl->type == KEY_NULL) - continue; -+ if (FIPS_mode()) { -+ switch (impl->type) { -+ case KEY_ED25519: -+ case KEY_ED25519_SK: -+ case KEY_ED25519_CERT: -+ case KEY_ED25519_SK_CERT: -+ continue; -+ break; -+ default: -+ break; -+ } -+ } - if (!include_sigonly && impl->sigonly) - continue; - if ((certs_only && !impl->cert) || (plain_only && impl->cert)) -@@ -1441,6 +1455,20 @@ sshkey_read(struct sshkey *ret, char **cpp) - return SSH_ERR_EC_CURVE_MISMATCH; - } - -+ switch (type) { -+ case KEY_ED25519: -+ case KEY_ED25519_SK: -+ case KEY_ED25519_CERT: -+ case KEY_ED25519_SK_CERT: -+ if (FIPS_mode()) { -+ sshkey_free(k); -+ logit_f("Ed25519 keys are not allowed in FIPS mode"); -+ return SSH_ERR_INVALID_ARGUMENT; -+ } -+ break; -+ default: -+ break; -+ } - /* Fill in ret from parsed key */ - sshkey_free_contents(ret); - *ret = *k; -@@ -2275,6 +2303,11 @@ sshkey_sign(struct sshkey *key, - *lenp = 0; - if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) - return SSH_ERR_INVALID_ARGUMENT; -+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) { -+ logit_f("Ed25519 keys are not allowed in FIPS mode"); -+ return SSH_ERR_INVALID_ARGUMENT; -+ } -+ /* Fallthrough */ - if ((impl = sshkey_impl_from_key(key)) == NULL) - return SSH_ERR_KEY_TYPE_UNKNOWN; - if ((r = sshkey_unshield_private(key)) != 0) -@@ -2311,6 +2344,10 @@ sshkey_verify(const struct sshkey *key, - *detailsp = NULL; - if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) - return SSH_ERR_INVALID_ARGUMENT; -+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) { -+ logit_f("Ed25519 keys are not allowed in FIPS mode"); -+ return SSH_ERR_INVALID_ARGUMENT; -+ } - if ((impl = sshkey_impl_from_key(key)) == NULL) - return SSH_ERR_KEY_TYPE_UNKNOWN; - return impl->funcs->verify(key, sig, siglen, data, dlen, --- -2.51.0 - + /* Append EXT_INFO signalling to KexAlgorithms */ + if (kexalgos == NULL) +- kexalgos = defprop[PROPOSAL_KEX_ALGS]; ++ kexalgos = FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : defprop[PROPOSAL_KEX_ALGS]; + if ((cp = kex_names_cat(kexalgos, ssh->kex->server ? + "ext-info-s,kex-strict-s-v00@openssh.com" : + "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL) diff --git a/0014-openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch similarity index 78% rename from 0014-openssh-7.7p1-gssapi-new-unique.patch rename to openssh-7.7p1-gssapi-new-unique.patch index 1d21839..0b8ab02 100644 --- a/0014-openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -1,25 +1,26 @@ -From 5fca5946aa97dce23c6824c52b070a92532752a9 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 14/50] openssh-7.7p1-gssapi-new-unique - ---- - auth-krb5.c | 262 ++++++++++++++++++++++++++++++++++++++++++------ - auth.h | 3 +- - gss-serv-krb5.c | 42 +++----- - gss-serv.c | 10 +- - servconf.c | 12 ++- - servconf.h | 2 + - session.c | 5 +- - ssh-gss.h | 4 +- - sshd-session.c | 2 +- - sshd_config.5 | 8 ++ - 10 files changed, 279 insertions(+), 71 deletions(-) - -diff --git a/auth-krb5.c b/auth-krb5.c -index c99e4e43..77714e3d 100644 ---- a/auth-krb5.c -+++ b/auth-krb5.c +diff -up openssh-8.6p1/auth.h.ccache_name openssh-8.6p1/auth.h +--- openssh-8.6p1/auth.h.ccache_name 2021-04-19 14:05:10.820744325 +0200 ++++ openssh-8.6p1/auth.h 2021-04-19 14:05:10.853744569 +0200 +@@ -83,6 +83,7 @@ struct Authctxt { + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; ++ int krb5_set_env; + #endif + struct sshbuf *loginmsg; + +@@ -231,7 +232,7 @@ struct passwd *fakepw(void); + int sys_auth_passwd(struct ssh *, const char *); + + #if defined(KRB5) && !defined(HEIMDAL) +-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); ++krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + #endif + + #endif /* AUTH_H */ +diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c +--- openssh-8.6p1/auth-krb5.c.ccache_name 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/auth-krb5.c 2021-04-19 14:40:55.142832954 +0200 @@ -51,6 +51,7 @@ #include #include @@ -28,7 +29,7 @@ index c99e4e43..77714e3d 100644 extern ServerOptions options; -@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c #endif krb5_error_code problem; krb5_ccache ccache = NULL; @@ -37,7 +38,7 @@ index c99e4e43..77714e3d 100644 char *client, *platform_client; const char *errmsg; -@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c goto out; } @@ -48,7 +49,7 @@ index c99e4e43..77714e3d 100644 if (problem) goto out; -@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c goto out; #endif @@ -69,7 +70,7 @@ index c99e4e43..77714e3d 100644 do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); #endif -@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c void krb5_cleanup_proc(Authctxt *authctxt) { @@ -125,29 +126,12 @@ index c99e4e43..77714e3d 100644 if (authctxt->krb5_user) { krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; -@@ -238,36 +281,189 @@ krb5_cleanup_proc(Authctxt *authctxt) +@@ -238,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt) } } -#ifndef HEIMDAL --krb5_error_code --ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { -- int tmpfd, ret, oerrno; -- char ccname[40]; -- mode_t old_umask; - -- ret = snprintf(ccname, sizeof(ccname), -- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); -- if (ret < 0 || (size_t)ret >= sizeof(ccname)) -- return ENOMEM; -- -- old_umask = umask(0177); -- tmpfd = mkstemp(ccname + strlen("FILE:")); -- oerrno = errno; -- umask(old_umask); -- if (tmpfd == -1) { -- logit("mkstemp(): %.100s", strerror(oerrno)); -- return oerrno; ++ +#if !defined(HEIMDAL) +int +ssh_asprintf_append(char **dsc, const char *fmt, ...) { @@ -165,8 +149,7 @@ index c99e4e43..77714e3d 100644 + old = *dsc; + + i = asprintf(dsc, "%s%s", *dsc, src); -+ if (i == -1) { -+ *dsc = old; ++ if (i == -1 || src == NULL) { + free(src); + return -1; + } @@ -213,9 +196,8 @@ index c99e4e43..77714e3d 100644 + /* unknown token, fallback to the default */ + goto cleanup; + } - } - -- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { ++ } ++ + if (ssh_asprintf_append(&r, "%s", p_o) == -1) + goto cleanup; + @@ -250,13 +232,29 @@ index c99e4e43..77714e3d 100644 + return ret; +} + -+krb5_error_code + krb5_error_code +-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { +- int tmpfd, ret, oerrno; +- char ccname[40]; +ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { + int tmpfd, ret, oerrno, type_len; + char *ccname = NULL; -+ mode_t old_umask; + mode_t old_umask; + char *type = NULL, *colon = NULL; -+ + +- ret = snprintf(ccname, sizeof(ccname), +- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); +- if (ret < 0 || (size_t)ret >= sizeof(ccname)) +- return ENOMEM; +- +- old_umask = umask(0177); +- tmpfd = mkstemp(ccname + strlen("FILE:")); +- oerrno = errno; +- umask(old_umask); +- if (tmpfd == -1) { +- logit("mkstemp(): %.100s", strerror(oerrno)); +- return oerrno; +- } + debug3_f("called"); + if (need_environment) + *need_environment = 0; @@ -271,7 +269,8 @@ index c99e4e43..77714e3d 100644 + "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); + if (ret < 0) + return ENOMEM; -+ + +- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { + old_umask = umask(0177); + tmpfd = mkstemp(ccname + strlen("FILE:")); oerrno = errno; @@ -338,32 +337,42 @@ index c99e4e43..77714e3d 100644 } #endif /* !HEIMDAL */ #endif /* KRB5 */ -diff --git a/auth.h b/auth.h -index 83d07ae8..10e88e11 100644 ---- a/auth.h -+++ b/auth.h -@@ -85,6 +85,7 @@ struct Authctxt { - krb5_principal krb5_user; - char *krb5_ticket_file; - char *krb5_ccname; -+ int krb5_set_env; - #endif - struct sshbuf *loginmsg; +diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c +--- openssh-8.6p1/gss-serv.c.ccache_name 2021-04-19 14:05:10.844744503 +0200 ++++ openssh-8.6p1/gss-serv.c 2021-04-19 14:05:10.854744577 +0200 +@@ -413,13 +413,15 @@ ssh_gssapi_cleanup_creds(void) + } -@@ -245,7 +246,7 @@ FILE *auth_openprincipals(const char *, struct passwd *, int); - int sys_auth_passwd(struct ssh *, const char *); + /* As user */ +-void ++int + ssh_gssapi_storecreds(void) + { + if (gssapi_client.mech && gssapi_client.mech->storecreds) { +- (*gssapi_client.mech->storecreds)(&gssapi_client); ++ return (*gssapi_client.mech->storecreds)(&gssapi_client); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); ++ ++ return 0; + } - #if defined(KRB5) && !defined(HEIMDAL) --krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); -+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + /* This allows GSSAPI methods to do things to the child's environment based +@@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) { + char *envstr; #endif - #endif /* AUTH_H */ -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 14502c5a..df55512d 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, +- if (gssapi_client.store.filename == NULL && +- gssapi_client.store.envval == NULL && +- gssapi_client.store.envvar == NULL) ++ if (gssapi_client.store.envval == NULL) + return; + + ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); +diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c +--- openssh-8.6p1/gss-serv-krb5.c.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/gss-serv-krb5.c 2021-04-19 14:05:10.854744577 +0200 +@@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ @@ -372,7 +381,7 @@ index 14502c5a..df55512d 100644 ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; -@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl OM_uint32 maj_status, min_status; const char *new_ccname, *new_cctype; const char *errmsg; @@ -390,7 +399,7 @@ index 14502c5a..df55512d 100644 #ifdef HEIMDAL # ifdef HAVE_KRB5_CC_NEW_UNIQUE -@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_get_err_text(krb_context, problem)); # endif krb5_free_error_message(krb_context, errmsg); @@ -409,7 +418,7 @@ index 14502c5a..df55512d 100644 } #endif /* #ifdef HEIMDAL */ -@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_parse_name(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); @@ -418,7 +427,7 @@ index 14502c5a..df55512d 100644 } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { -@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_free_error_message(krb_context, errmsg); krb5_free_principal(krb_context, princ); krb5_cc_destroy(krb_context, ccache); @@ -427,7 +436,7 @@ index 14502c5a..df55512d 100644 } krb5_free_principal(krb_context, princ); -@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); @@ -465,7 +474,7 @@ index 14502c5a..df55512d 100644 do_pam_putenv(client->store.envvar, client->store.envval); #endif -@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl client->store.data = krb_context; @@ -474,44 +483,10 @@ index 14502c5a..df55512d 100644 } int -diff --git a/gss-serv.c b/gss-serv.c -index a5cca797..9d5435ed 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void) - } - - /* As user */ --void -+int - ssh_gssapi_storecreds(void) - { - if (gssapi_client.mech && gssapi_client.mech->storecreds) { -- (*gssapi_client.mech->storecreds)(&gssapi_client); -+ return (*gssapi_client.mech->storecreds)(&gssapi_client); - } else - debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -+ -+ return 0; - } - - /* This allows GSSAPI methods to do things to the child's environment based -@@ -500,9 +502,7 @@ ssh_gssapi_rekey_creds(void) { - char *envstr; - #endif - -- if (gssapi_client.store.filename == NULL && -- gssapi_client.store.envval == NULL && -- gssapi_client.store.envvar == NULL) -+ if (gssapi_client.store.envval == NULL) - return; - - ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); -diff --git a/servconf.c b/servconf.c -index d4f7fd66..55aa5bf0 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -138,6 +138,7 @@ initialize_server_options(ServerOptions *options) +diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.ccache_name 2021-04-19 14:05:10.848744532 +0200 ++++ openssh-8.6p1/servconf.c 2021-04-19 14:05:10.854744577 +0200 +@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -519,7 +494,7 @@ index d4f7fd66..55aa5bf0 100644 options->gss_authentication=-1; options->gss_keyex = -1; options->gss_cleanup_creds = -1; -@@ -382,6 +383,8 @@ fill_default_server_options(ServerOptions *options) +@@ -359,6 +360,8 @@ fill_default_server_options(ServerOption options->kerberos_ticket_cleanup = 1; if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; @@ -528,16 +503,16 @@ index d4f7fd66..55aa5bf0 100644 if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) -@@ -564,7 +567,7 @@ typedef enum { - sPort, sHostKeyFile, sLoginGraceTime, - sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +@@ -506,7 +509,7 @@ typedef enum { + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sPasswordAuthentication, + sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication, - sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, -@@ -655,11 +658,13 @@ static struct { + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, +@@ -593,11 +597,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -551,7 +526,7 @@ index d4f7fd66..55aa5bf0 100644 #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1668,6 +1673,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO intptr = &options->kerberos_get_afs_token; goto parse_flag; @@ -562,7 +537,7 @@ index d4f7fd66..55aa5bf0 100644 case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; -@@ -3293,6 +3302,7 @@ dump_config(ServerOptions *o) +@@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o) # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif @@ -570,11 +545,10 @@ index d4f7fd66..55aa5bf0 100644 #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff --git a/servconf.h b/servconf.h -index c3f50140..a4a38d6d 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -149,6 +149,8 @@ typedef struct { +diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h +--- openssh-8.6p1/servconf.h.ccache_name 2021-04-19 14:05:10.848744532 +0200 ++++ openssh-8.6p1/servconf.h 2021-04-19 14:05:10.855744584 +0200 +@@ -140,6 +140,8 @@ typedef struct { * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -583,11 +557,10 @@ index c3f50140..a4a38d6d 100644 int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff --git a/session.c b/session.c -index 89b3a9cf..2620dd11 100644 ---- a/session.c -+++ b/session.c -@@ -1025,7 +1025,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/session.c 2021-04-19 14:05:10.855744584 +0200 +@@ -1038,7 +1038,8 @@ do_setup_env(struct ssh *ssh, Session *s /* Allow any GSSAPI methods that we've used to alter * the child's environment as they see fit */ @@ -597,7 +570,7 @@ index 89b3a9cf..2620dd11 100644 #endif /* Set basic environment. */ -@@ -1101,7 +1102,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +@@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s } #endif #ifdef KRB5 @@ -606,33 +579,10 @@ index 89b3a9cf..2620dd11 100644 child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ccname); #endif -diff --git a/ssh-gss.h b/ssh-gss.h -index db34d77f..a894e23c 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -116,7 +116,7 @@ typedef struct ssh_gssapi_mech_struct { - int (*dochild) (ssh_gssapi_client *); - int (*userok) (ssh_gssapi_client *, char *); - int (*localname) (ssh_gssapi_client *, char **); -- void (*storecreds) (ssh_gssapi_client *); -+ int (*storecreds) (ssh_gssapi_client *); - int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - -@@ -186,7 +186,7 @@ int ssh_gssapi_userok(char *name, struct passwd *, int kex); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); --void ssh_gssapi_storecreds(void); -+int ssh_gssapi_storecreds(void); - const char *ssh_gssapi_displayname(void); - - char *ssh_gssapi_server_mechanisms(void); -diff --git a/sshd-session.c b/sshd-session.c -index f8c8a797..478381db 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -1349,7 +1349,7 @@ main(int ac, char **av) +diff -up openssh-8.6p1/sshd-session.c.ccache_name openssh-8.6p1/sshd-session.c +--- openssh-8.6p1/sshd-session.c.ccache_name 2021-04-19 14:05:10.849744540 +0200 ++++ openssh-8.6p1/sshd-session.c 2021-04-19 14:05:10.855744584 +0200 +@@ -2284,7 +2284,7 @@ main(int ac, char **av) #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(authctxt->pw); @@ -641,11 +591,10 @@ index f8c8a797..478381db 100644 restore_uid(); } #endif -diff --git a/sshd_config.5 b/sshd_config.5 -index 8bc6586e..1251d4d5 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -1033,6 +1033,14 @@ Specifies whether to automatically destroy the user's ticket cache +diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5 +--- openssh-8.6p1/sshd_config.5.ccache_name 2021-04-19 14:05:10.849744540 +0200 ++++ openssh-8.6p1/sshd_config.5 2021-04-19 14:05:10.856744592 +0200 +@@ -939,6 +939,14 @@ Specifies whether to automatically destr file on logout. The default is .Cm yes . @@ -660,6 +609,24 @@ index 8bc6586e..1251d4d5 100644 .It Cm KexAlgorithms Specifies the permitted KEX (Key Exchange) algorithms that the server will offer to clients. --- -2.49.0 - +diff -up openssh-8.6p1/ssh-gss.h.ccache_name openssh-8.6p1/ssh-gss.h +--- openssh-8.6p1/ssh-gss.h.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/ssh-gss.h 2021-04-19 14:05:10.855744584 +0200 +@@ -114,7 +114,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*dochild) (ssh_gssapi_client *); + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); +- void (*storecreds) (ssh_gssapi_client *); ++ int (*storecreds) (ssh_gssapi_client *); + int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + +@@ -175,7 +175,7 @@ int ssh_gssapi_userok(char *name, struct + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); +-void ssh_gssapi_storecreds(void); ++int ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + + char *ssh_gssapi_server_mechanisms(void); diff --git a/0011-openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch similarity index 50% rename from 0011-openssh-7.8p1-UsePAM-warning.patch rename to openssh-7.8p1-UsePAM-warning.patch index 76ee115..f8d7042 100644 --- a/0011-openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -1,18 +1,7 @@ -From 56b8d082bc9e25a77b5227d576f27088446c6fb9 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 11/50] openssh-7.8p1-UsePAM-warning - ---- - sshd-session.c | 4 ++++ - sshd_config | 2 ++ - 2 files changed, 6 insertions(+) - -diff --git a/sshd-session.c b/sshd-session.c -index a365f26f..a70b36c9 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -1127,6 +1127,10 @@ main(int ac, char **av) +diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd-session.c.log-usepam-no 2021-04-19 14:00:45.099735129 +0200 ++++ openssh-8.6p1/sshd-session.c 2021-04-19 14:03:21.140920974 +0200 +@@ -1749,6 +1749,10 @@ main(int ac, char **av) "enabled authentication methods"); } @@ -23,11 +12,10 @@ index a365f26f..a70b36c9 100644 #ifdef WITH_OPENSSL if (options.moduli_file != NULL) dh_set_moduli_file(options.moduli_file); -diff --git a/sshd_config b/sshd_config -index 608203e4..48af6321 100644 ---- a/sshd_config -+++ b/sshd_config -@@ -89,6 +89,8 @@ AuthorizedKeysFile .ssh/authorized_keys +diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config +--- openssh-8.6p1/sshd_config.log-usepam-no 2021-04-19 14:00:45.098735121 +0200 ++++ openssh-8.6p1/sshd_config 2021-04-19 14:00:45.099735129 +0200 +@@ -87,6 +87,8 @@ AuthorizedKeysFile .ssh/authorized_keys # 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'. @@ -36,6 +24,3 @@ index 608203e4..48af6321 100644 #UsePAM no #AllowAgentForwarding yes --- -2.49.0 - diff --git a/0001-openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch similarity index 80% rename from 0001-openssh-7.8p1-role-mls.patch rename to openssh-7.8p1-role-mls.patch index c08e414..7c6d0ca 100644 --- a/0001-openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -1,75 +1,46 @@ -From 95f4e30195382c3df7104c2ad3e5e9953f8ad554 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 01/50] openssh-7.8p1-role-mls - ---- - auth-pam.c | 2 +- - auth-pam.h | 2 +- - auth.h | 3 + - auth2-gss.c | 11 +- - auth2-hostbased.c | 9 + - auth2-pubkey.c | 11 +- - auth2.c | 14 ++ - misc.c | 8 + - monitor.c | 37 ++- - monitor.h | 4 + - monitor_wrap.c | 21 ++ - monitor_wrap.h | 3 + - openbsd-compat/Makefile.in | 3 +- - openbsd-compat/port-linux-sshd.c | 420 +++++++++++++++++++++++++++++++ - openbsd-compat/port-linux.c | 37 +-- - openbsd-compat/port-linux.h | 3 +- - platform.c | 2 +- - sshd-session.c | 3 + - 18 files changed, 551 insertions(+), 42 deletions(-) - create mode 100644 openbsd-compat/port-linux-sshd.c - -diff --git a/auth-pam.c b/auth-pam.c -index 13c0a792..b4100ea1 100644 ---- a/auth-pam.c -+++ b/auth-pam.c -@@ -1238,7 +1238,7 @@ is_pam_session_open(void) - * during the ssh authentication process. - */ - int --do_pam_putenv(char *name, char *value) -+do_pam_putenv(char *name, const char *value) - { - int ret = 1; - char *compound; -diff --git a/auth-pam.h b/auth-pam.h -index 8d801c68..9dd7ae07 100644 ---- a/auth-pam.h -+++ b/auth-pam.h -@@ -33,7 +33,7 @@ u_int do_pam_account(void); - void do_pam_session(struct ssh *); - void do_pam_setcred(void); - void do_pam_chauthtok(void); --int do_pam_putenv(char *, char *); -+int do_pam_putenv(char *, const char *); - char ** fetch_pam_environment(void); - char ** fetch_pam_child_environment(void); - void free_pam_environment(char **); -diff --git a/auth.h b/auth.h -index 98bb23d4..83d07ae8 100644 ---- a/auth.h -+++ b/auth.h -@@ -65,6 +65,9 @@ struct Authctxt { - char *service; - struct passwd *pw; /* set if 'valid' */ - char *style; +diff -up openssh/auth2.c.role-mls openssh/auth2.c +--- openssh/auth2.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/auth2.c 2018-08-22 11:14:56.815430916 +0200 +@@ -256,6 +256,9 @@ input_userauth_request(int type, u_int32 + Authctxt *authctxt = ssh->authctxt; + Authmethod *m = NULL; + char *user = NULL, *service = NULL, *method = NULL, *style = NULL; +#ifdef WITH_SELINUX -+ char *role; ++ char *role = NULL; +#endif + int r, authenticated = 0; + double tstart = monotime_double(); - /* Method lists for multiple authentication */ - char **auth_methods; /* modified from server config */ -diff --git a/auth2-gss.c b/auth2-gss.c -index 75eb4e3a..f7898ab3 100644 ---- a/auth2-gss.c -+++ b/auth2-gss.c -@@ -284,6 +284,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -268,6 +271,11 @@ input_userauth_request(int type, u_int32 + debug("userauth-request for user %s service %s method %s", user, service, method); + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + ++#ifdef WITH_SELINUX ++ if ((role = strchr(user, '/')) != NULL) ++ *role++ = 0; ++#endif ++ + if ((style = strchr(user, ':')) != NULL) + *style++ = 0; + +@@ -314,7 +314,13 @@ input_userauth_request(int type, u_int32 + setproctitle("%s [net]", authctxt->valid ? user : "unknown"); + authctxt->service = xstrdup(service); + authctxt->style = style ? xstrdup(style) : NULL; ++#ifdef WITH_SELINUX ++ authctxt->role = role ? xstrdup(role) : NULL; ++#endif + mm_inform_authserv(service, style); ++#ifdef WITH_SELINUX ++ mm_inform_authrole(role); ++#endif + userauth_banner(ssh); + if ((r = kex_server_update_ext_info(ssh)) != 0) + fatal_fr(r, "kex_server_update_ext_info failed"); +diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c +--- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200 +@@ -281,6 +281,7 @@ input_gssapi_mic(int type, u_int32_t ple Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; int r, authenticated = 0; @@ -77,7 +48,7 @@ index 75eb4e3a..f7898ab3 100644 struct sshbuf *b; gss_buffer_desc mic, gssbuf; u_char *p; -@@ -300,7 +301,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple fatal_f("sshbuf_new failed"); mic.value = p; mic.length = len; @@ -92,7 +63,7 @@ index 75eb4e3a..f7898ab3 100644 "gssapi-with-mic", ssh->kex->session_id); if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -@@ -313,6 +320,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple logit("GSSAPI MIC check failed"); sshbuf_free(b); @@ -101,11 +72,10 @@ index 75eb4e3a..f7898ab3 100644 free(mic.value); authctxt->postponed = 0; -diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index eb21479a..a3be6e49 100644 ---- a/auth2-hostbased.c -+++ b/auth2-hostbased.c -@@ -129,7 +129,16 @@ userauth_hostbased(struct ssh *ssh, const char *method) +diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c +--- openssh/auth2-hostbased.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/auth2-hostbased.c 2018-08-22 11:14:56.816430924 +0200 +@@ -123,7 +123,16 @@ userauth_hostbased(struct ssh *ssh) /* reconstruct packet */ if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -122,11 +92,10 @@ index eb21479a..a3be6e49 100644 (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || (r = sshbuf_put_cstring(b, method)) != 0 || (r = sshbuf_put_string(b, pkalg, alen)) != 0 || -diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index aa24fda0..267a27d2 100644 ---- a/auth2-pubkey.c -+++ b/auth2-pubkey.c -@@ -206,9 +206,16 @@ userauth_pubkey(struct ssh *ssh, const char *method) +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 ++++ openssh/auth2-pubkey.c 2018-08-22 11:17:07.331483958 +0200 +@@ -169,9 +169,16 @@ userauth_pubkey(struct ssh *ssh) goto done; } /* reconstruct packet */ @@ -145,51 +114,47 @@ index aa24fda0..267a27d2 100644 if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, userstyle)) != 0 || (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || -diff --git a/auth2.c b/auth2.c -index 82f6e621..5ba45c12 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -271,6 +271,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) - Authctxt *authctxt = ssh->authctxt; - Authmethod *m = NULL; - char *user = NULL, *service = NULL, *method = NULL, *style = NULL; +diff -up openssh/auth.h.role-mls openssh/auth.h +--- openssh/auth.h.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/auth.h 2018-08-22 11:14:56.816430924 +0200 +@@ -65,6 +65,9 @@ struct Authctxt { + char *service; + struct passwd *pw; /* set if 'valid' */ + char *style; +#ifdef WITH_SELINUX -+ char *role = NULL; ++ char *role; +#endif - int r, authenticated = 0; - double tstart = monotime_double(); -@@ -284,6 +287,11 @@ 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); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = 0; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = 0; - -@@ -313,7 +321,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) - setproctitle("%s [net]", authctxt->valid ? user : "unknown"); - authctxt->service = xstrdup(service); - authctxt->style = style ? xstrdup(style) : NULL; -+#ifdef WITH_SELINUX -+ authctxt->role = role ? xstrdup(role) : NULL; -+#endif - mm_inform_authserv(service, style); -+#ifdef WITH_SELINUX -+ mm_inform_authrole(role); -+#endif - userauth_banner(ssh); - if ((r = kex_server_update_ext_info(ssh)) != 0) - fatal_fr(r, "kex_server_update_ext_info failed"); -diff --git a/misc.c b/misc.c -index dd0bd032..c932f9bb 100644 ---- a/misc.c -+++ b/misc.c -@@ -806,6 +806,7 @@ char * + /* Method lists for multiple authentication */ + char **auth_methods; /* modified from server config */ +diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c +--- openssh/auth-pam.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/auth-pam.c 2018-08-22 11:14:56.816430924 +0200 +@@ -1172,7 +1172,7 @@ is_pam_session_open(void) + * during the ssh authentication process. + */ + int +-do_pam_putenv(char *name, char *value) ++do_pam_putenv(char *name, const char *value) + { + int ret = 1; + char *compound; +diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h +--- openssh/auth-pam.h.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/auth-pam.h 2018-08-22 11:14:56.817430932 +0200 +@@ -33,7 +33,7 @@ u_int do_pam_account(void); + void do_pam_session(struct ssh *); + void do_pam_setcred(void); + void do_pam_chauthtok(void); +-int do_pam_putenv(char *, char *); ++int do_pam_putenv(char *, const char *); + char ** fetch_pam_environment(void); + char ** fetch_pam_child_environment(void); + void free_pam_environment(char **); +diff -up openssh/misc.c.role-mls openssh/misc.c +--- openssh/misc.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/misc.c 2018-08-22 11:14:56.817430932 +0200 +@@ -542,6 +542,7 @@ char * colon(char *cp) { int flag = 0; @@ -197,7 +162,7 @@ index dd0bd032..c932f9bb 100644 if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -821,6 +822,13 @@ colon(char *cp) +@@ -557,6 +558,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -211,11 +176,10 @@ index dd0bd032..c932f9bb 100644 } return NULL; } -diff --git a/monitor.c b/monitor.c -index 2179553d..02b3eaaa 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -120,6 +120,9 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); +diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.role-mls 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/monitor.c 2021-05-21 14:21:56.719414087 +0200 +@@ -117,6 +117,9 @@ int mm_answer_sign(struct ssh *, int, st int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); int mm_answer_authserv(struct ssh *, int, struct sshbuf *); @@ -225,7 +189,7 @@ index 2179553d..02b3eaaa 100644 int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); -@@ -194,6 +197,9 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -195,6 +198,9 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, @@ -235,7 +199,7 @@ index 2179553d..02b3eaaa 100644 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -912,6 +918,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -803,6 +809,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -245,7 +209,7 @@ index 2179553d..02b3eaaa 100644 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM -@@ -986,6 +995,26 @@ key_base_type_match(const char *method, const struct sshkey *key, +@@ -877,6 +886,26 @@ key_base_type_match(const char *method, return found; } @@ -272,16 +236,16 @@ index 2179553d..02b3eaaa 100644 int mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { -@@ -1358,7 +1387,7 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) +@@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh, struct sshbuf *b; - struct sshkey *hostkey = NULL; + struct sshkey *hostkey = NULL; const u_char *p; - char *userstyle, *cp; + char *userstyle, *s, *cp; size_t len; u_char type; int hostbound = 0, r, fail = 0; -@@ -1389,6 +1418,8 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) +@@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh, fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse userstyle"); @@ -290,7 +254,7 @@ index 2179553d..02b3eaaa 100644 xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1439,7 +1470,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, +@@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char { struct sshbuf *b; const u_char *p; @@ -299,7 +263,7 @@ index 2179553d..02b3eaaa 100644 size_t len; int r, fail = 0; u_char type; -@@ -1460,6 +1491,8 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, +@@ -1338,6 +1370,8 @@ monitor_valid_hostbasedblob(const u_char fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse userstyle"); @@ -308,13 +272,12 @@ index 2179553d..02b3eaaa 100644 xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -diff --git a/monitor.h b/monitor.h -index 3f8a9bea..9dcd9c29 100644 ---- a/monitor.h -+++ b/monitor.h -@@ -56,6 +56,10 @@ enum monitor_reqtype { +diff -up openssh/monitor.h.role-mls openssh/monitor.h +--- openssh/monitor.h.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/monitor.h 2018-08-22 11:14:56.818430941 +0200 +@@ -55,6 +55,10 @@ enum monitor_reqtype { + MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, - MONITOR_REQ_STATE = 51, MONITOR_ANS_STATE = 52, +#ifdef WITH_SELINUX + MONITOR_REQ_AUTHROLE = 80, @@ -323,11 +286,10 @@ index 3f8a9bea..9dcd9c29 100644 MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, -diff --git a/monitor_wrap.c b/monitor_wrap.c -index bd900b2f..ef3ab1b1 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -442,6 +442,27 @@ mm_inform_authserv(char *service, char *style) +diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c +--- openssh/monitor_wrap.c.role-mls 2018-08-22 11:14:56.818430941 +0200 ++++ openssh/monitor_wrap.c 2018-08-22 11:21:47.938747968 +0200 +@@ -390,6 +390,27 @@ mm_inform_authserv(char *service, char * sshbuf_free(m); } @@ -355,11 +317,10 @@ index bd900b2f..ef3ab1b1 100644 /* Do the password authentication */ int mm_auth_password(struct ssh *ssh, char *password) -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 7134afee..38a280c8 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -46,6 +46,9 @@ int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, +diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h +--- openssh/monitor_wrap.h.role-mls 2018-08-22 11:14:56.818430941 +0200 ++++ openssh/monitor_wrap.h 2018-08-22 11:22:10.439929513 +0200 +@@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int); const u_char *, size_t, const char *, const char *, const char *, u_int compat); void mm_inform_authserv(char *, char *); @@ -369,11 +330,10 @@ index 7134afee..38a280c8 100644 struct passwd *mm_getpwnamallow(struct ssh *, const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); -diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in -index 1d549954..78e6fa5b 100644 ---- a/openbsd-compat/Makefile.in -+++ b/openbsd-compat/Makefile.in -@@ -100,7 +100,8 @@ PORTS= port-aix.o \ +diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in +--- openssh/openbsd-compat/Makefile.in.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/openbsd-compat/Makefile.in 2018-08-22 11:14:56.819430949 +0200 +@@ -92,7 +92,8 @@ PORTS= port-aix.o \ port-prngd.o \ port-solaris.o \ port-net.o \ @@ -383,11 +343,78 @@ index 1d549954..78e6fa5b 100644 .c.o: $(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< -diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -new file mode 100644 -index 00000000..b9fbe38b ---- /dev/null -+++ b/openbsd-compat/port-linux-sshd.c +diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/port-linux.c +--- openssh/openbsd-compat/port-linux.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/openbsd-compat/port-linux.c 2018-08-22 11:14:56.819430949 +0200 +@@ -100,37 +100,6 @@ ssh_selinux_getctxbyname(char *pwname) + return sc; + } + +-/* Set the execution context to the default for the specified user */ +-void +-ssh_selinux_setup_exec_context(char *pwname) +-{ +- char *user_ctx = NULL; +- +- if (!ssh_selinux_enabled()) +- return; +- +- debug3("%s: setting execution context", __func__); +- +- user_ctx = ssh_selinux_getctxbyname(pwname); +- if (setexeccon(user_ctx) != 0) { +- switch (security_getenforce()) { +- case -1: +- fatal("%s: security_getenforce() failed", __func__); +- case 0: +- error("%s: Failed to set SELinux execution " +- "context for %s", __func__, pwname); +- break; +- default: +- fatal("%s: Failed to set SELinux execution context " +- "for %s (in enforcing mode)", __func__, pwname); +- } +- } +- if (user_ctx != NULL) +- freecon(user_ctx); +- +- debug3("%s: done", __func__); +-} +- + /* Set the TTY context for the specified user */ + void + ssh_selinux_setup_pty(char *pwname, const char *tty) +@@ -145,7 +114,11 @@ ssh_selinux_setup_pty(char *pwname, cons + + debug3("%s: setting TTY context on %s", __func__, tty); + +- user_ctx = ssh_selinux_getctxbyname(pwname); ++ if (getexeccon(&user_ctx) != 0) { ++ error_f("getexeccon: %s", strerror(errno)); ++ goto out; ++ } ++ + + /* XXX: should these calls fatal() upon failure in enforcing mode? */ + +diff -up openssh/openbsd-compat/port-linux.h.role-mls openssh/openbsd-compat/port-linux.h +--- openssh/openbsd-compat/port-linux.h.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/openbsd-compat/port-linux.h 2018-08-22 11:14:56.819430949 +0200 +@@ -20,9 +20,10 @@ + #ifdef WITH_SELINUX + int ssh_selinux_enabled(void); + void ssh_selinux_setup_pty(char *, const char *); +-void ssh_selinux_setup_exec_context(char *); + void ssh_selinux_change_context(const char *); + void ssh_selinux_setfscreatecon(const char *); ++ ++void sshd_selinux_setup_exec_context(char *); + #endif + + #ifdef LINUX_OOM_ADJUST +diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compat/port-linux-sshd.c +--- openssh/openbsd-compat/port-linux-sshd.c.role-mls 2018-08-22 11:14:56.819430949 +0200 ++++ openssh/openbsd-compat/port-linux-sshd.c 2018-08-22 11:14:56.819430949 +0200 @@ -0,0 +1,420 @@ +/* + * Copyright (c) 2005 Daniel Walsh @@ -809,82 +836,10 @@ index 00000000..b9fbe38b +#endif +#endif + -diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index c1d54f38..7426f6f7 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -109,37 +109,6 @@ ssh_selinux_getctxbyname(char *pwname) - return sc; - } - --/* Set the execution context to the default for the specified user */ --void --ssh_selinux_setup_exec_context(char *pwname) --{ -- char *user_ctx = NULL; -- -- if (!ssh_selinux_enabled()) -- return; -- -- debug3("%s: setting execution context", __func__); -- -- user_ctx = ssh_selinux_getctxbyname(pwname); -- if (setexeccon(user_ctx) != 0) { -- switch (security_getenforce()) { -- case -1: -- fatal("%s: security_getenforce() failed", __func__); -- case 0: -- error("%s: Failed to set SELinux execution " -- "context for %s", __func__, pwname); -- break; -- default: -- fatal("%s: Failed to set SELinux execution context " -- "for %s (in enforcing mode)", __func__, pwname); -- } -- } -- if (user_ctx != NULL) -- freecon(user_ctx); -- -- debug3("%s: done", __func__); --} -- - /* Set the TTY context for the specified user */ - void - ssh_selinux_setup_pty(char *pwname, const char *tty) -@@ -152,7 +121,11 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) - - debug3("%s: setting TTY context on %s", __func__, tty); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -+ if (getexeccon(&user_ctx) != 0) { -+ error_f("getexeccon: %s", strerror(errno)); -+ goto out; -+ } -+ - - /* XXX: should these calls fatal() upon failure in enforcing mode? */ - -diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index 959430de..055c825e 100644 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -20,9 +20,10 @@ - #ifdef WITH_SELINUX - int ssh_selinux_enabled(void); - void ssh_selinux_setup_pty(char *, const char *); --void ssh_selinux_setup_exec_context(char *); - void ssh_selinux_change_context(const char *); - void ssh_selinux_setfscreatecon(const char *); -+ -+void sshd_selinux_setup_exec_context(char *); - #endif - - #ifdef LINUX_OOM_ADJUST -diff --git a/platform.c b/platform.c -index 4c4fe57e..1bfb4bea 100644 ---- a/platform.c -+++ b/platform.c -@@ -140,7 +140,7 @@ platform_setusercontext_post_groups(struct passwd *pw) +diff -up openssh/platform.c.role-mls openssh/platform.c +--- openssh/platform.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/platform.c 2018-08-22 11:14:56.819430949 +0200 +@@ -183,7 +183,7 @@ platform_setusercontext_post_groups(stru } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX @@ -893,11 +848,10 @@ index 4c4fe57e..1bfb4bea 100644 #endif } -diff --git a/sshd-session.c b/sshd-session.c -index c64eb29f..74d2cbc7 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -1328,6 +1328,9 @@ main(int ac, char **av) +diff -up openssh/sshd.c.role-mls openssh/sshd.c +--- openssh/sshd-session.c.role-mls 2018-08-20 07:57:29.000000000 +0200 ++++ openssh/sshd-session.c 2018-08-22 11:14:56.820430957 +0200 +@@ -2186,6 +2186,9 @@ main(int ac, char **av) restore_uid(); } #endif @@ -907,6 +861,3 @@ index c64eb29f..74d2cbc7 100644 #ifdef USE_PAM if (options.use_pam) { do_pam_setcred(); --- -2.49.0 - diff --git a/0029-openssh-7.8p1-scp-ipv6.patch b/openssh-7.8p1-scp-ipv6.patch similarity index 51% rename from 0029-openssh-7.8p1-scp-ipv6.patch rename to openssh-7.8p1-scp-ipv6.patch index dbd69aa..8ae0948 100644 --- a/0029-openssh-7.8p1-scp-ipv6.patch +++ b/openssh-7.8p1-scp-ipv6.patch @@ -1,17 +1,8 @@ -From 507e6f245557ae7261806f7ecbd40697cb0dd389 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 29/50] openssh-7.8p1-scp-ipv6 - ---- - scp.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - diff --git a/scp.c b/scp.c -index 9554b188..7f9795a5 100644 +index 60682c68..9344806e 100644 --- a/scp.c +++ b/scp.c -@@ -1183,7 +1183,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) +@@ -714,7 +714,9 @@ toremote(int argc, char **argv) addargs(&alist, "%s", host); addargs(&alist, "%s", cmd); addargs(&alist, "%s", src); @@ -22,6 +13,4 @@ index 9554b188..7f9795a5 100644 tuser ? tuser : "", tuser ? "@" : "", thost, targ); if (do_local_cmd(&alist) != 0) --- -2.49.0 diff --git a/0030-openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch similarity index 90% rename from 0030-openssh-8.0p1-crypto-policies.patch rename to openssh-8.0p1-crypto-policies.patch index 498e3f5..a666c5c 100644 --- a/0030-openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,18 +1,7 @@ -From b436140fe3abd9f97f01f9af9f5da5cf6c5d7725 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 30/50] openssh-8.0p1-crypto-policies - ---- - ssh_config.5 | 164 ++++++++++++++++++++------------------------- - sshd_config.5 | 179 +++++++++++++++++++------------------------------- - 2 files changed, 140 insertions(+), 203 deletions(-) - -diff --git a/ssh_config.5 b/ssh_config.5 -index 8d5d0722..a43b2a27 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -438,17 +438,13 @@ A single argument of +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh_config.5 openssh-9.3p1-patched/ssh_config.5 +--- openssh-9.3p1/ssh_config.5 2023-06-07 10:26:48.284590156 +0200 ++++ openssh-9.3p1-patched/ssh_config.5 2023-06-07 10:26:00.623052194 +0200 +@@ -378,17 +378,13 @@ causes no CNAMEs to be considered for canonicalization. This is the default behaviour. .It Cm CASignatureAlgorithms @@ -35,7 +24,7 @@ index 8d5d0722..a43b2a27 100644 If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -587,20 +583,25 @@ If the option is set to +@@ -450,20 +446,25 @@ (the default), the check will not be executed. .It Cm Ciphers @@ -65,21 +54,21 @@ index 8d5d0722..a43b2a27 100644 .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -616,13 +617,6 @@ aes256-gcm@openssh.com +@@ -479,13 +480,6 @@ chacha20-poly1305@openssh.com .Ed .Pp -The default is: -.Bd -literal -offset indent -chacha20-poly1305@openssh.com, --aes128-gcm@openssh.com,aes256-gcm@openssh.com, --aes128-ctr,aes192-ctr,aes256-ctr +-aes128-ctr,aes192-ctr,aes256-ctr, +-aes128-gcm@openssh.com,aes256-gcm@openssh.com -.Ed -.Pp The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClearAllForwardings -@@ -1022,6 +1016,11 @@ command line will be passed untouched to the GSSAPI library. +@@ -885,6 +879,11 @@ The default is .Dq no . .It Cm GSSAPIKexAlgorithms @@ -91,7 +80,7 @@ index 8d5d0722..a43b2a27 100644 The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are .Bd -literal -offset 3n -@@ -1034,10 +1033,8 @@ gss-nistp256-sha256-, +@@ -897,10 +896,8 @@ gss-curve25519-sha256- .Ed .Pp @@ -103,7 +92,7 @@ index 8d5d0722..a43b2a27 100644 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -1056,36 +1053,25 @@ will not be converted automatically, +@@ -919,36 +916,25 @@ but may be manually hashed using .Xr ssh-keygen 1 . .It Cm HostbasedAcceptedAlgorithms @@ -148,7 +137,7 @@ index 8d5d0722..a43b2a27 100644 .Pp The .Fl Q -@@ -1138,6 +1124,17 @@ to prefer their algorithms. +@@ -1001,6 +987,17 @@ .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . @@ -166,7 +155,7 @@ index 8d5d0722..a43b2a27 100644 .It Cm HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key -@@ -1376,6 +1373,11 @@ it may be zero or more of: +@@ -1330,6 +1330,11 @@ it may be zero or more of: and .Cm pam . .It Cm KexAlgorithms @@ -178,7 +167,7 @@ index 8d5d0722..a43b2a27 100644 Specifies the permitted KEX (Key Exchange) algorithms that will be used and their preference order. The selected algorithm will be the first algorithm in this list that -@@ -1384,29 +1386,17 @@ Multiple algorithms must be comma-separated. +@@ -1338,29 +1343,17 @@ Multiple algorithms must be comma-separa .Pp If the specified list begins with a .Sq + @@ -198,8 +187,8 @@ index 8d5d0722..a43b2a27 100644 -.Pp -The default is: -.Bd -literal -offset indent --mlkem768x25519-sha256, -sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, +-mlkem768x25519-sha256, -curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, @@ -212,7 +201,7 @@ index 8d5d0722..a43b2a27 100644 The list of supported key exchange algorithms may also be obtained using .Qq ssh -Q kex . .It Cm KnownHostsCommand -@@ -1522,37 +1512,33 @@ function, and all code in the +@@ -1365,37 +1357,33 @@ file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -259,7 +248,7 @@ index 8d5d0722..a43b2a27 100644 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1741,39 +1727,31 @@ instead of continuing to execute and pass data. +@@ -1567,39 +1555,31 @@ The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -311,7 +300,7 @@ index 8d5d0722..a43b2a27 100644 .It Cm PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be -@@ -2497,7 +2475,9 @@ for those users who do not have a configuration file. +@@ -2265,7 +2245,9 @@ This file must be world-readable. .El .Sh SEE ALSO @@ -322,11 +311,10 @@ index 8d5d0722..a43b2a27 100644 .Sh AUTHORS .An -nosplit OpenSSH is a derivative of the original and free -diff --git a/sshd_config.5 b/sshd_config.5 -index 26fcdc84..583a01cd 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -379,17 +379,13 @@ If the argument is +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshd_config.5 openssh-9.3p1-patched/sshd_config.5 +--- openssh-9.3p1/sshd_config.5 2023-06-07 10:26:48.277590077 +0200 ++++ openssh-9.3p1-patched/sshd_config.5 2023-06-07 10:26:00.592051845 +0200 +@@ -379,17 +379,13 @@ then no banner is displayed. By default, no banner is displayed. .It Cm CASignatureAlgorithms @@ -349,7 +337,7 @@ index 26fcdc84..583a01cd 100644 If the specified list begins with a .Sq + character, then the specified algorithms will be appended to the default set -@@ -533,20 +529,25 @@ The default is +@@ -525,20 +521,25 @@ indicating not to .Xr chroot 2 . .It Cm Ciphers @@ -379,21 +367,21 @@ index 26fcdc84..583a01cd 100644 .Pp The supported ciphers are: .Pp -@@ -573,13 +574,6 @@ aes256-gcm@openssh.com +@@ -565,13 +566,6 @@ chacha20-poly1305@openssh.com .El .Pp -The default is: -.Bd -literal -offset indent -chacha20-poly1305@openssh.com, --aes128-gcm@openssh.com,aes256-gcm@openssh.com, --aes128-ctr,aes192-ctr,aes256-ctr +-aes128-ctr,aes192-ctr,aes256-ctr, +-aes128-gcm@openssh.com,aes256-gcm@openssh.com -.Ed -.Pp The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -774,53 +768,43 @@ For this to work +@@ -766,53 +760,43 @@ .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -466,7 +454,7 @@ index 26fcdc84..583a01cd 100644 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q HostbasedAcceptedAlgorithms . -@@ -887,25 +871,14 @@ is specified, the location of the socket will be read from the +@@ -879,25 +863,14 @@ .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -497,7 +485,7 @@ index 26fcdc84..583a01cd 100644 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -1052,6 +1025,11 @@ Specifies whether to look at .k5login file for user's aliases. +@@ -1025,6 +1025,11 @@ Specifies whether to look at .k5login fi The default is .Cm yes . .It Cm KexAlgorithms @@ -509,7 +497,7 @@ index 26fcdc84..583a01cd 100644 Specifies the permitted KEX (Key Exchange) algorithms that the server will offer to clients. The ordering of this list is not important, as the client specifies the -@@ -1060,16 +1038,16 @@ Multiple algorithms must be comma-separated. +@@ -1033,16 +1038,16 @@ Multiple algorithms must be comma-separa .Pp If the specified list begins with a .Sq + @@ -530,22 +518,25 @@ index 26fcdc84..583a01cd 100644 .Pp The supported algorithms are: .Pp -@@ -1106,14 +1084,6 @@ sntrup761x25519-sha512 +@@ -1075,17 +1080,6 @@ ecdh-sha2-nistp521 sntrup761x25519-sha512@openssh.com .El .Pp -The default is: -.Bd -literal -offset indent --mlkem768x25519-sha256, -sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, +-mlkem768x25519-sha256, -curve25519-sha256,curve25519-sha256@libssh.org, --ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521 +-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, +-diffie-hellman-group-exchange-sha256, +-diffie-hellman-group16-sha512,diffie-hellman-group18-sha512, +-diffie-hellman-group14-sha256 -.Ed -.Pp The list of supported key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress -@@ -1200,21 +1170,26 @@ function, and all code in the +@@ -1184,21 +1152,26 @@ file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -576,7 +567,7 @@ index 26fcdc84..583a01cd 100644 .Pp The algorithms that contain .Qq -etm -@@ -1257,15 +1232,6 @@ umac-64-etm@openssh.com +@@ -1241,15 +1214,6 @@ umac-128-etm@openssh.com .El .Pp @@ -592,7 +583,7 @@ index 26fcdc84..583a01cd 100644 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1753,36 +1719,25 @@ or equivalent.) +@@ -1633,36 +1597,25 @@ The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms @@ -638,7 +629,7 @@ index 26fcdc84..583a01cd 100644 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -@@ -2289,7 +2244,9 @@ This file should be writable by root only, but it is recommended +@@ -2131,7 +2084,9 @@ .El .Sh SEE ALSO .Xr sftp-server 8 , @@ -649,6 +640,3 @@ index 26fcdc84..583a01cd 100644 .Sh AUTHORS .An -nosplit OpenSSH is a derivative of the original and free --- -2.49.0 - diff --git a/openssh-8.0p1-keygen-strip-doseol.patch b/openssh-8.0p1-keygen-strip-doseol.patch new file mode 100644 index 0000000..3117a7a --- /dev/null +++ b/openssh-8.0p1-keygen-strip-doseol.patch @@ -0,0 +1,12 @@ +diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c +--- openssh-8.0p1/ssh-keygen.c.strip-doseol 2021-03-18 17:41:34.472404994 +0100 ++++ openssh-8.0p1/ssh-keygen.c 2021-03-18 17:41:55.255538761 +0100 +@@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw) + while (getline(&line, &linesize, f) != -1) { + lnum++; + cp = line; +- cp[strcspn(cp, "\n")] = '\0'; ++ cp[strcspn(cp, "\r\n")] = '\0'; + /* Trim leading space and comments */ + cp = line + strspn(line, " \t"); + if (*cp == '#' || *cp == '\0') diff --git a/0031-openssh-8.0p1-openssl-kdf.patch b/openssh-8.0p1-openssl-kdf.patch similarity index 84% rename from 0031-openssh-8.0p1-openssl-kdf.patch rename to openssh-8.0p1-openssl-kdf.patch index 529940f..c22b210 100644 --- a/0031-openssh-8.0p1-openssl-kdf.patch +++ b/openssh-8.0p1-openssl-kdf.patch @@ -1,18 +1,14 @@ -From 430bd33963725beb8ec01a1e581529ae6bf6bec0 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 31/50] openssh-8.0p1-openssl-kdf +commit 2c3ef499bfffce3cfd315edeebf202850ba4e00a +Author: Jakub Jelen +Date: Tue Apr 16 15:35:18 2019 +0200 ---- - configure.ac | 1 + - kex.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 108 insertions(+) + Use the new OpenSSL KDF diff --git a/configure.ac b/configure.ac -index d9bd2f51..d92a8580 100644 +index 2a455e4e..e01c3d43 100644 --- a/configure.ac +++ b/configure.ac -@@ -3137,6 +3137,7 @@ if test "x$openssl" = "xyes" ; then +@@ -2712,6 +2712,7 @@ if test "x$openssl" = "xyes" ; then HMAC_CTX_init \ RSA_generate_key_ex \ RSA_get_default_method \ @@ -21,10 +17,10 @@ index d9bd2f51..d92a8580 100644 # OpenSSL_add_all_algorithms may be a macro. diff --git a/kex.c b/kex.c -index 19a56e8e..8b200ff4 100644 +index b6f041f4..1fbce2bb 100644 --- a/kex.c +++ b/kex.c -@@ -40,6 +40,11 @@ +@@ -38,6 +38,11 @@ #ifdef WITH_OPENSSL #include #include @@ -36,7 +32,7 @@ index 19a56e8e..8b200ff4 100644 #endif #include "ssh.h" -@@ -1078,6 +1083,107 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -942,6 +945,107 @@ kex_choose_conf(struct ssh *ssh) return r; } @@ -144,7 +140,7 @@ index 19a56e8e..8b200ff4 100644 static int derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, const struct sshbuf *shared_secret, u_char **keyp) -@@ -1141,6 +1247,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, +@@ -1004,6 +1096,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, ssh_digest_free(hashctx); return r; } @@ -152,6 +148,4 @@ index 19a56e8e..8b200ff4 100644 #define NKEYS 6 int --- -2.49.0 diff --git a/0028-openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch similarity index 90% rename from 0028-openssh-8.0p1-pkcs11-uri.patch rename to openssh-8.0p1-pkcs11-uri.patch index 73e890b..bdc4722 100644 --- a/0028-openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,102 +1,7 @@ -From 5d6ec35c1a0e06452a2c087decb0baf6e8063e21 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 28/50] openssh-8.0p1-pkcs11-uri - ---- - Makefile.in | 20 +- - configure.ac | 37 ++ - regress/Makefile | 8 +- - regress/pkcs11.sh | 349 +++++++++++++++ - regress/unittests/Makefile | 2 +- - regress/unittests/pkcs11/tests.c | 346 ++++++++++++++ - ssh-add.c | 48 +- - ssh-agent.c | 103 ++++- - ssh-keygen.c | 7 +- - ssh-pkcs11-client.c | 3 + - ssh-pkcs11-uri.c | 437 ++++++++++++++++++ - ssh-pkcs11-uri.h | 43 ++ - ssh-pkcs11.c | 745 +++++++++++++++++++++++-------- - ssh-pkcs11.h | 4 + - ssh.c | 104 ++++- - ssh_config.5 | 15 + - 16 files changed, 2024 insertions(+), 247 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 78f65948..6c417ef7 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -110,7 +110,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 ed25519.o hash.o \ -@@ -339,6 +339,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/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) -@@ -377,6 +379,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 -@@ -558,6 +562,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 - $(MKDIR_P) `pwd`/regress/misc/ssh-verify-attestation - [ -f `pwd`/regress/Makefile ] || \ -@@ -731,6 +736,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 -lcrypto $(LIBS) -+ - # These all need to be compiled -fPIC, so they are treated differently. - SK_DUMMY_OBJS=\ - regress/misc/sk-dummy/sk-dummy.lo \ -@@ -776,7 +791,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 extra-tests unit - echo all tests passed -diff --git a/configure.ac b/configure.ac -index 13c70a98..d9bd2f51 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2172,12 +2172,14 @@ AC_LINK_IFELSE( +diff -up openssh-9.6p1/configure.ac.pkcs11-uri openssh-9.6p1/configure.ac +--- openssh-9.6p1/configure.ac.pkcs11-uri 2024-01-12 14:25:25.228942213 +0100 ++++ openssh-9.6p1/configure.ac 2024-01-12 14:25:25.233942336 +0100 +@@ -2066,12 +2066,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -111,7 +16,7 @@ index 13c70a98..d9bd2f51 100644 fi ] ) -@@ -2207,6 +2209,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2095,6 +2097,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -152,7 +57,7 @@ index 13c70a98..d9bd2f51 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5820,6 +5856,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" +@@ -5708,6 +5744,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -160,11 +65,75 @@ index 13c70a98..d9bd2f51 100644 echo " U2F/FIDO support: $enable_sk" echo "" -diff --git a/regress/Makefile b/regress/Makefile -index 7e7f95b5..f36de51e 100644 ---- a/regress/Makefile -+++ b/regress/Makefile -@@ -137,7 +137,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ +diff -up openssh-9.6p1/Makefile.in.pkcs11-uri openssh-9.6p1/Makefile.in +--- openssh-9.6p1/Makefile.in.pkcs11-uri 2024-01-12 14:25:25.204941622 +0100 ++++ openssh-9.6p1/Makefile.in 2024-01-12 14:25:25.233942336 +0100 +@@ -105,7 +105,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ + ssh-ed25519-sk.o ssh-rsa.o dh.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ +- 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 ed25519.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 +@@ -685,6 +690,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 -lcrypto $(LIBS) ++ + # These all need to be compiled -fPIC, so they are treated differently. + SK_DUMMY_OBJS=\ + regress/misc/sk-dummy/sk-dummy.lo \ +@@ -720,7 +735,8 @@ regress-unit-binaries: regress-prep $(RE + regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ + regress/unittests/sshkey/test_sshkey$(EXEEXT) \ + regress/unittests/sshsig/test_sshsig$(EXEEXT) \ +- 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 extra-tests unit + echo all tests passed +diff -up openssh-9.6p1/regress/Makefile.pkcs11-uri openssh-9.6p1/regress/Makefile +--- openssh-9.6p1/regress/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/regress/Makefile 2024-01-12 14:25:25.233942336 +0100 +@@ -134,7 +134,8 @@ CLEANFILES= *.core actual agent-key.* au known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -174,7 +143,7 @@ index 7e7f95b5..f36de51e 100644 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 \ -@@ -297,8 +298,9 @@ unit: +@@ -273,8 +274,9 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -186,11 +155,9 @@ index 7e7f95b5..f36de51e 100644 -d ${.CURDIR}/unittests/sshkey/testdata ; \ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ -d ${.CURDIR}/unittests/sshsig/testdata ; \ -diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh -new file mode 100644 -index 00000000..a91aee94 ---- /dev/null -+++ b/regress/pkcs11.sh +diff -up openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri openssh-9.6p1/regress/pkcs11.sh +--- openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 ++++ openssh-9.6p1/regress/pkcs11.sh 2024-01-12 14:25:25.233942336 +0100 @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -541,10 +508,9 @@ index 00000000..a91aee94 + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index e370900e..d6c89c12 100644 ---- a/regress/unittests/Makefile -+++ b/regress/unittests/Makefile +diff -up openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri openssh-9.6p1/regress/unittests/Makefile +--- openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/regress/unittests/Makefile 2024-01-12 14:25:25.233942336 +0100 @@ -1,6 +1,6 @@ # $OpenBSD: Makefile,v 1.13 2023/09/24 08:14:13 claudio Exp $ @@ -553,11 +519,9 @@ index e370900e..d6c89c12 100644 +SUBDIR+=authopt misc sshsig pkcs11 .include -diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c -new file mode 100644 -index 00000000..7d4fa499 ---- /dev/null -+++ b/regress/unittests/pkcs11/tests.c +diff -up openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-9.6p1/regress/unittests/pkcs11/tests.c +--- openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 ++++ openssh-9.6p1/regress/unittests/pkcs11/tests.c 2024-01-12 14:25:25.233942336 +0100 @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017 Red Hat @@ -905,10 +869,9 @@ index 00000000..7d4fa499 + test_parse_invalid(); + test_generate_valid(); +} -diff --git a/ssh-add.c b/ssh-add.c -index 0035cb84..b0f47f4d 100644 ---- a/ssh-add.c -+++ b/ssh-add.c +diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c +--- openssh-9.6p1/ssh-add.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-add.c 2024-01-12 14:25:25.233942336 +0100 @@ -69,6 +69,7 @@ #include "ssh-sk.h" #include "sk-api.h" @@ -917,7 +880,7 @@ index 0035cb84..b0f47f4d 100644 /* argv0 */ extern char *__progname; -@@ -242,6 +243,38 @@ delete_all(int agent_fd, int qflag) +@@ -240,6 +241,38 @@ delete_all(int agent_fd, int qflag) return ret; } @@ -956,7 +919,7 @@ index 0035cb84..b0f47f4d 100644 static int add_file(int agent_fd, const char *filename, int key_only, int cert_only, int qflag, const char *skprovider, -@@ -462,15 +495,14 @@ static int +@@ -460,15 +489,14 @@ static int update_card(int agent_fd, int add, const char *id, int qflag, int key_only, int cert_only, struct dest_constraint **dest_constraints, size_t ndest_constraints, @@ -974,7 +937,7 @@ index 0035cb84..b0f47f4d 100644 if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -658,6 +690,14 @@ do_file(int agent_fd, int deleting, int key_only, int cert_only, +@@ -656,6 +684,14 @@ do_file(int agent_fd, int deleting, int char *file, int qflag, const char *skprovider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { @@ -989,7 +952,7 @@ index 0035cb84..b0f47f4d 100644 if (deleting) { if (delete_file(agent_fd, file, key_only, cert_only, qflag) == -1) -@@ -1001,7 +1041,7 @@ main(int argc, char **argv) +@@ -999,7 +1035,7 @@ main(int argc, char **argv) if (update_card(agent_fd, !deleting, pkcs11provider, qflag, key_only, cert_only, dest_constraints, ndest_constraints, @@ -998,11 +961,10 @@ index 0035cb84..b0f47f4d 100644 ret = 1; goto done; } -diff --git a/ssh-agent.c b/ssh-agent.c -index c27c5a95..798bf9b6 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -1569,10 +1569,74 @@ add_p11_identity(struct sshkey *key, char *comment, const char *provider, +diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c +--- openssh-9.6p1/ssh-agent.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-agent.c 2024-01-12 14:25:25.234942360 +0100 +@@ -1549,10 +1549,74 @@ add_p11_identity(struct sshkey *key, cha idtab->nentries++; } @@ -1078,21 +1040,21 @@ index c27c5a95..798bf9b6 100644 char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; -@@ -1601,25 +1665,18 @@ process_add_smartcard_key(SocketEntry *e) +@@ -1581,25 +1643,18 @@ process_add_smartcard_key(SocketEntry *e "providers is disabled", provider); goto send; } - if (realpath(provider, canonical_provider) == NULL) { - verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", - provider, strerror(errno)); -- goto send; ++ sane_uri = sanitize_pkcs11_provider(provider); ++ if (sane_uri == NULL) + goto send; - } - if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { - verbose("refusing PKCS#11 add of \"%.100s\": " - "provider not allowed", canonical_provider); -+ sane_uri = sanitize_pkcs11_provider(provider); -+ if (sane_uri == NULL) - goto send; +- goto send; - } - debug_f("add %.100s", canonical_provider); if (lifetime && !death) @@ -1109,7 +1071,7 @@ index c27c5a95..798bf9b6 100644 } for (j = 0; j < ncerts; j++) { if (!sshkey_is_cert(certs[j])) -@@ -1629,13 +1686,13 @@ process_add_smartcard_key(SocketEntry *e) +@@ -1609,13 +1664,13 @@ process_add_smartcard_key(SocketEntry *e if (pkcs11_make_cert(keys[i], certs[j], &k) != 0) continue; add_p11_identity(k, xstrdup(comments[i]), @@ -1125,7 +1087,7 @@ index c27c5a95..798bf9b6 100644 dest_constraints, ndest_constraints); keys[i] = NULL; /* transferred */ comments[i] = NULL; /* transferred */ -@@ -1648,6 +1705,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -1628,6 +1683,7 @@ process_add_smartcard_key(SocketEntry *e send: free(pin); free(provider); @@ -1133,7 +1095,7 @@ index c27c5a95..798bf9b6 100644 free(keys); free(comments); free_dest_constraints(dest_constraints, ndest_constraints); -@@ -1660,7 +1718,7 @@ send: +@@ -1640,7 +1696,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1142,7 +1104,7 @@ index c27c5a95..798bf9b6 100644 int r, success = 0; Identity *id, *nxt; -@@ -1672,30 +1730,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -1652,30 +1708,29 @@ process_remove_smartcard_key(SocketEntry } free(pin); @@ -1179,11 +1141,185 @@ index c27c5a95..798bf9b6 100644 send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 89c3ed28..16cff947 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -906,8 +906,11 @@ do_download(struct passwd *pw) +diff -up openssh-9.6p1/ssh_config.5.pkcs11-uri openssh-9.6p1/ssh_config.5 +--- openssh-9.6p1/ssh_config.5.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 ++++ openssh-9.6p1/ssh_config.5 2024-01-12 14:25:25.234942360 +0100 +@@ -1216,6 +1216,21 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.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-9.6p1/ssh.c.pkcs11-uri openssh-9.6p1/ssh.c +--- openssh-9.6p1/ssh.c.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 ++++ openssh-9.6p1/ssh.c 2024-01-12 14:25:25.234942360 +0100 +@@ -882,6 +882,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#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; ++ } ++#endif + p = tilde_expand_filename(optarg, getuid()); + if (stat(p, &st) == -1) + fprintf(stderr, "Warning: Identity file %s " +@@ -1784,6 +1792,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); +@@ -2307,6 +2316,45 @@ ssh_session2(struct ssh *ssh, const stru + 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; ++ ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ 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); ++ } ++ ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ ++ + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2321,11 +2369,6 @@ load_public_identity_files(const struct + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; +-#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)); +@@ -2338,33 +2381,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); ++ ++ /* 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 -up openssh-9.6p1/ssh-keygen.c.pkcs11-uri openssh-9.6p1/ssh-keygen.c +--- openssh-9.6p1/ssh-keygen.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-keygen.c 2024-01-12 14:25:25.234942360 +0100 +@@ -862,8 +862,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1197,11 +1333,10 @@ index 89c3ed28..16cff947 100644 } free(comments[i]); sshkey_free(keys[i]); -diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c -index b8d1700f..64df695e 100644 ---- a/ssh-pkcs11-client.c -+++ b/ssh-pkcs11-client.c -@@ -635,6 +635,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +diff -up openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-client.c +--- openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11-client.c 2024-01-12 14:25:25.234942360 +0100 +@@ -592,6 +592,8 @@ pkcs11_add_provider(char *name, char *pi struct sshbuf *msg; struct helper *helper; @@ -1210,7 +1345,7 @@ index b8d1700f..64df695e 100644 if ((helper = helper_by_provider(name)) == NULL && (helper = pkcs11_start_helper(name)) == NULL) return -1; -@@ -655,6 +657,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +@@ -612,6 +614,7 @@ pkcs11_add_provider(char *name, char *pi *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); @@ -1218,11 +1353,1296 @@ index b8d1700f..64df695e 100644 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 00000000..8bd97e9e ---- /dev/null -+++ b/ssh-pkcs11-uri.c +diff -up openssh-9.9p1/ssh-pkcs11.c.xxx openssh-9.9p1/ssh-pkcs11.c +--- openssh-9.9p1/ssh-pkcs11.c.xxx 2024-10-09 11:56:35.890126144 +0200 ++++ openssh-9.9p1/ssh-pkcs11.c 2024-10-09 11:56:48.528459585 +0200 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #define CRYPTOKI_COMPAT + #include "pkcs11.h" +@@ -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_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; ++ ++ 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); ++ ++ debug3_f("called with provider %s", provider_uri); + +- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { ++ 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,60 @@ 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: { ++ const RSA *rsa = EVP_PKEY_get0_RSA(key->pkey); ++ k11 = RSA_get_ex_data(rsa, rsa_idx); ++ break; ++ } ++#ifdef HAVE_EC_KEY_METHOD_NEW ++ case KEY_ECDSA: { ++ const EC_KEY * ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); ++ k11 = EC_KEY_get_ex_data(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; ++ uri.serial = k11->provider->module->slotinfo[k11->slotidx].token.serialNumber; ++ ++ p = pkcs11_uri_get(&uri); ++ /* do not cleanup -- we do not allocate here, only reference */ ++ if (p == NULL) ++ return -1; ++ ++ fprintf(f, " %s", p); ++ free(p); ++ return 0; ++} ++ + /* release a wrapped object */ + static void + pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, +@@ -208,6 +349,7 @@ pkcs11_k11_free(void *parent, void *ptr, + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ free(k11->label); + free(k11); + } + +@@ -222,8 +364,8 @@ pkcs11_find(struct pkcs11_provider *p, C + CK_RV rv; + int ret = -1; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { + error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); + return (-1); +@@ -260,14 +402,14 @@ pkcs11_login_slot(struct pkcs11_provider + if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) + verbose("Deferring PIN entry to reader keypad."); + else { +- snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", ++ snprintf(prompt, sizeof(prompt), "Enter PIN for '%.32s': ", + si->token.label); +- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { ++ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { + debug_f("no pin specified"); + return (-1); /* bail out */ + } + } +- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, ++ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, + (pin != NULL) ? strlen(pin) : 0); + if (pin != NULL) + freezero(pin, strlen(pin)); +@@ -297,13 +439,14 @@ pkcs11_login_slot(struct pkcs11_provider + static int + pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) + { +- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { ++ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || ++ k11->provider->module == NULL || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + + return pkcs11_login_slot(k11->provider, +- &k11->provider->slotinfo[k11->slotidx], type); ++ &k11->provider->module->slotinfo[k11->slotidx], type); + } + + +@@ -319,13 +462,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs + + *val = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + attr.type = type; + attr.pValue = &flag; +@@ -356,13 +500,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C + int always_auth = 0; + int did_login = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { + if (pkcs11_login(k11, CKU_USER) < 0) { +@@ -439,8 +584,8 @@ pkcs11_rsa_private_encrypt(int flen, con + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + tlen = RSA_size(rsa); + + /* XXX handle CKR_BUFFER_TOO_SMALL */ +@@ -484,7 +629,7 @@ pkcs11_rsa_start_wrapper(void) + /* redirect private key operations for rsa key to pkcs11 token */ + static int + pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) + { + struct pkcs11_key *k11; + +@@ -502,6 +647,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * + 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); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + if (RSA_set_method(rsa, rsa_method) != 1) + fatal_f("RSA_set_method failed"); + if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) +@@ -532,8 +683,8 @@ ecdsa_do_sign(const unsigned char *dgst, + return (NULL); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + siglen = ECDSA_size(ec); + sig = xmalloc(siglen); +@@ -598,7 +749,7 @@ pkcs11_ecdsa_start_wrapper(void) + + static int + pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) + { + struct pkcs11_key *k11; + +@@ -615,6 +766,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + if (EC_KEY_set_method(ec, ec_key_method) != 1) + fatal_f("EC_KEY_set_method failed"); + if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) +@@ -622,7 +779,8 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider + } + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + +-/* remove trailing spaces */ ++/* remove trailing spaces. Note, that this does NOT guarantee the buffer ++ * will be null terminated if there are no trailing spaces! */ + static char * + rmspace(u_char *buf, size_t len) + { +@@ -654,8 +812,8 @@ pkcs11_open_session(struct pkcs11_provid + CK_SESSION_HANDLE session; + int login_required, ret; + +- f = p->function_list; +- si = &p->slotinfo[slotidx]; ++ f = p->module->function_list; ++ si = &p->module->slotinfo[slotidx]; + + login_required = si->token.flags & CKF_LOGIN_REQUIRED; + +@@ -665,9 +823,9 @@ pkcs11_open_session(struct pkcs11_provid + error("pin required"); + return (-SSH_PKCS11_ERR_PIN_REQUIRED); + } +- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| ++ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| + CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { +- error("C_OpenSession failed: %lu", rv); ++ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); + return (-1); + } + if (login_required && pin != NULL && strlen(pin) != 0) { +@@ -703,7 +861,8 @@ static struct sshkey * + pkcs11_fetch_ecdsa_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; +@@ -717,14 +876,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); +@@ -735,19 +895,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- 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; +@@ -759,8 +919,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; +@@ -771,13 +931,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; +@@ -794,7 +954,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); +@@ -810,7 +970,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + key->flags |= SSHKEY_FLAG_EXT; + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + if (ec) + EC_KEY_free(ec); +@@ -827,7 +987,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; +@@ -838,14 +999,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); +@@ -856,19 +1018,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- 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; +@@ -880,8 +1042,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; +@@ -890,7 +1052,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); +@@ -905,7 +1067,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + key->flags |= SSHKEY_FLAG_EXT; + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + RSA_free(rsa); + +@@ -916,7 +1078,8 @@ static int + pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) + { +- 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; +@@ -940,14 +1103,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; + +- 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; +@@ -959,18 +1123,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + * 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; + } + + /* 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; +@@ -984,8 +1149,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; + } +@@ -1005,7 +1170,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); +@@ -1035,7 +1200,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); +@@ -1055,7 +1220,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); +@@ -1106,11 +1271,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; +@@ -1127,10 +1293,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++; ++ } + +- 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; +@@ -1211,11 +1390,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; +@@ -1231,10 +1411,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++; ++ } ++ ++ 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; +@@ -1503,16 +1696,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; +@@ -1521,162 +1708,309 @@ 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) +- goto fail; +- *providerp = NULL; +- +- if (keyp != NULL) +- *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; ++ /* if no provider specified, fallback to p11-kit */ ++ if (uri->module_path == NULL) { ++#ifdef PKCS11_DEFAULT_PROVIDER ++ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); ++#else ++ error_f("No module path provided"); ++ goto fail; ++#endif ++ } else { ++ provider_module = strdup(uri->module_path); ++ } ++ p = xcalloc(1, sizeof(*p)); ++ p->name = pkcs11_uri_get(uri); + +- if (pkcs11_provider_lookup(provider_id) != NULL) { +- debug_f("provider already registered: %s", provider_id); ++ if (lib_contains_symbol(provider_module, "C_GetFunctionList") != 0) { ++ error("provider %s is not a PKCS11 library", provider_module); + goto fail; + } +- if (lib_contains_symbol(provider_id, "C_GetFunctionList") != 0) { +- error("provider %s is not a PKCS11 library", provider_id); +- goto fail; ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ 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()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) + fatal("dlsym(C_GetFunctionList) failed: %s", dlerror()); +- 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); + 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; + } +- debug("provider %s: manufacturerID <%.*s> cryptokiVersion %d.%d" +- " libraryDescription <%.*s> libraryVersion %d.%d", +- provider_id, +- RMSPACE(p->info.manufacturerID), +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- RMSPACE(p->info.libraryDescription), +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strncmp(uri->lib_manuf, m->info.manufacturerID, 32)) { ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); ++ goto fail; ++ } ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); ++ debug("provider %s: manufacturerID <%.32s> cryptokiVersion %d.%d" ++ " libraryDescription <%.32s> libraryVersion %d.%d", ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ 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); + 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)); ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); + p->valid = 1; +- nkeys = 0; +- for (i = 0; i < p->nslots; i++) { +- token = &p->slotinfo[i].token; +- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) ++ m->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; + } + debug("provider %s slot %lu: label <%.*s> " + "manufacturerID <%.*s> model <%.*s> serial <%.*s> " + "flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_module, (unsigned long)i, + RMSPACE(token->label), RMSPACE(token->manufacturerID), + RMSPACE(token->model), RMSPACE(token->serialNumber), + token->flags); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; ++ ++ /* now owned by caller */ ++ *providerp = p; ++ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ ++ 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 (p) { ++ free(p->name); ++ free(p); ++ } ++ 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; ++ ++ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { ++ goto fail; ++ } ++ ++ 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 && ++ strncmp(token->label, uri->token, 32) != 0) { ++ debug2_f("ignoring token not matching label (%.32s) " ++ "specified by PKCS#11 URI in slot %lu", ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strncmp(token->manufacturerID, uri->manuf, 32) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "manufacturerID (%.32s) specified by PKCS#11 URI in " ++ "slot %lu", token->manufacturerID, (unsigned long)i); ++ continue; ++ } ++ if (uri->serial != NULL && ++ strncmp(token->serialNumber, uri->serial, 16) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "serialNumber (%s) specified by PKCS#11 URI in " ++ "slot %lu", token->serialNumber, (unsigned long)i); ++ continue; ++ } ++ debug("provider %s slot %lu: label <%.32s> manufacturerID <%.32s> " ++ "model <%.16s> serial <%.16s> flags 0x%lx", ++ provider_uri, (unsigned long)i, ++ token->label, token->manufacturerID, token->model, ++ token->serialNumber, token->flags); + /* +- * open session, login with pin and retrieve public +- * keys (if keyp is provided) ++ * open session if not yet opened, login with pin and ++ * retrieve public keys (if keyp is provided) + */ +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || ++ 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 (%.32s) ", ++ 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) ++{ ++ 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) + { + 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) { +@@ -1685,7 +2019,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"); ++ ++ 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); ++ } ++ ++ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); ++ pkcs11_uri_cleanup(uri); + + return (nkeys); + } +diff -up openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11.h +--- openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11.h 2024-01-12 14:25:25.235942385 +0100 +@@ -22,10 +22,14 @@ + #define SSH_PKCS11_ERR_PIN_REQUIRED 4 + #define SSH_PKCS11_ERR_PIN_LOCKED 5 + ++#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-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.c +--- openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 ++++ openssh-9.6p1/ssh-pkcs11-uri.c 2024-01-12 14:25:25.235942385 +0100 @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2017 Red Hat @@ -1661,11 +3081,9 @@ index 00000000..8bd97e9e +} + +#endif /* ENABLE_PKCS11 */ -diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h -new file mode 100644 -index 00000000..29e9f732 ---- /dev/null -+++ b/ssh-pkcs11-uri.h +diff -up openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.h +--- openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 ++++ openssh-9.6p1/ssh-pkcs11-uri.h 2024-01-12 14:25:25.235942385 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Red Hat @@ -1710,1473 +3128,3 @@ index 00000000..29e9f732 +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 31b9360f..b96f5b89 100644 ---- a/ssh-pkcs11.c -+++ b/ssh-pkcs11.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #define CRYPTOKI_COMPAT - #include "pkcs11.h" -@@ -55,8 +56,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 +66,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 +83,7 @@ struct pkcs11_key { - CK_ULONG slotidx; - char *keyid; - int keyid_len; -+ char *label; - }; - - int pkcs11_interactive = 0; -@@ -106,26 +115,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 +181,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 +201,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 +229,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 +287,60 @@ 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: { -+ const RSA *rsa = EVP_PKEY_get0_RSA(key->pkey); -+ k11 = RSA_get_ex_data(rsa, rsa_idx); -+ break; -+ } -+#ifdef HAVE_EC_KEY_METHOD_NEW -+ case KEY_ECDSA: { -+ const EC_KEY * ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); -+ k11 = EC_KEY_get_ex_data(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; -+ uri.serial = k11->provider->module->slotinfo[k11->slotidx].token.serialNumber; -+ -+ p = pkcs11_uri_get(&uri); -+ /* do not cleanup -- we do not allocate here, only reference */ -+ if (p == NULL) -+ return -1; -+ -+ fprintf(f, " %s", p); -+ free(p); -+ return 0; -+} -+ - /* release a wrapped object */ - static void - pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +354,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); -+ free(k11->label); - free(k11); - } - -@@ -222,8 +369,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, - CK_RV rv; - int ret = -1; - -- f = p->function_list; -- session = p->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ session = p->module->slotinfo[slotidx].session; - if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { - error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); - return (-1); -@@ -260,14 +407,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, - if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) - verbose("Deferring PIN entry to reader keypad."); - else { -- snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", -+ snprintf(prompt, sizeof(prompt), "Enter PIN for '%.32s': ", - si->token.label); -- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { -+ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { - debug_f("no pin specified"); - return (-1); /* bail out */ - } - } -- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, -+ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, - (pin != NULL) ? strlen(pin) : 0); - if (pin != NULL) - freezero(pin, strlen(pin)); -@@ -297,13 +444,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, - static int - pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) - { -- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { -+ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || -+ k11->provider->module == NULL || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - - return pkcs11_login_slot(k11->provider, -- &k11->provider->slotinfo[k11->slotidx], type); -+ &k11->provider->module->slotinfo[k11->slotidx], type); - } - - -@@ -319,13 +467,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, - - *val = 0; - -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || -+ !k11->provider->module || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - attr.type = type; - attr.pValue = &flag; -@@ -356,13 +505,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) - int always_auth = 0; - int did_login = 0; - -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || -+ !k11->provider->module || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { - if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -439,8 +589,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - tlen = RSA_size(rsa); - - /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -484,7 +634,7 @@ pkcs11_rsa_start_wrapper(void) - /* redirect private key operations for rsa key to pkcs11 token */ - static int - pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) - { - struct pkcs11_key *k11; - -@@ -502,6 +652,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - 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); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } -+ - if (RSA_set_method(rsa, rsa_method) != 1) - fatal_f("RSA_set_method failed"); - if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) -@@ -534,8 +690,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, - return (NULL); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - siglen = ECDSA_size(ec); - sig = xmalloc(siglen); -@@ -600,7 +756,7 @@ pkcs11_ecdsa_start_wrapper(void) - - static int - pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) - { - struct pkcs11_key *k11; - -@@ -617,6 +773,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); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } -+ - if (EC_KEY_set_method(ec, ec_key_method) != 1) - fatal_f("EC_KEY_set_method failed"); - if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) -@@ -626,7 +788,8 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - } - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - --/* remove trailing spaces */ -+/* remove trailing spaces. Note, that this does NOT guarantee the buffer -+ * will be null terminated if there are no trailing spaces! */ - static char * - rmspace(u_char *buf, size_t len) - { -@@ -658,8 +821,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, - CK_SESSION_HANDLE session; - int login_required, ret; - -- f = p->function_list; -- si = &p->slotinfo[slotidx]; -+ f = p->module->function_list; -+ si = &p->module->slotinfo[slotidx]; - - login_required = si->token.flags & CKF_LOGIN_REQUIRED; - -@@ -669,9 +832,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, - error("pin required"); - return (-SSH_PKCS11_ERR_PIN_REQUIRED); - } -- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| -+ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| - CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { -- error("C_OpenSession failed: %lu", rv); -+ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); - return (-1); - } - if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -707,7 +870,8 @@ static struct sshkey * - pkcs11_fetch_ecdsa_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; -@@ -721,14 +885,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; -+ 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); -@@ -739,19 +904,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 (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; -@@ -763,8 +928,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - 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; -@@ -775,13 +940,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - 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; -@@ -798,7 +963,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - 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); -@@ -817,7 +982,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - key->flags |= SSHKEY_FLAG_EXT; - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - if (ec) - EC_KEY_free(ec); -@@ -834,7 +999,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; -@@ -845,14 +1011,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); -@@ -863,19 +1030,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); - } - - /* 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; -@@ -887,8 +1054,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - 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; -@@ -897,7 +1064,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); -@@ -915,7 +1082,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - key->flags |= SSHKEY_FLAG_EXT; - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - RSA_free(rsa); - -@@ -926,7 +1093,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; -@@ -950,14 +1118,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; -@@ -969,18 +1138,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; - } - - /* 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; -@@ -994,8 +1164,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; - } -@@ -1015,7 +1185,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - 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); -@@ -1048,7 +1218,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); -@@ -1071,7 +1241,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); -@@ -1122,11 +1292,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; -@@ -1143,10 +1314,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 (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; -@@ -1227,11 +1411,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; -@@ -1247,10 +1432,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++; -+ } -+ 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; -@@ -1532,16 +1730,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, - } - #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; -@@ -1550,162 +1742,309 @@ pkcs11_register_provider(char *provider_id, char *pin, - CK_FUNCTION_LIST *f = NULL; - CK_TOKEN_INFO *token; - CK_ULONG i; -+ char *provider_module = NULL; -+ struct pkcs11_module *m = NULL; -+ -+ /* if no provider specified, fallback to p11-kit */ -+ if (uri->module_path == NULL) { -+#ifdef PKCS11_DEFAULT_PROVIDER -+ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); -+#else -+ error_f("No module path provided"); -+ goto fail; -+#endif -+ } else { -+ provider_module = strdup(uri->module_path); -+ } -+ p = xcalloc(1, sizeof(*p)); -+ p->name = pkcs11_uri_get(uri); - -- if (providerp == NULL) -- goto fail; -- *providerp = NULL; -- -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; -- -- if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug_f("provider already registered: %s", provider_id); -+ if (lib_contains_symbol(provider_module, "C_GetFunctionList") != 0) { -+ error("provider %s is not a PKCS11 library", provider_module); - goto fail; - } -- if (lib_contains_symbol(provider_id, "C_GetFunctionList") != 0) { -- error("provider %s is not a PKCS11 library", provider_id); -- goto fail; -+ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL -+ && m->valid) { -+ 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()); - goto fail; - } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) - fatal("dlsym(C_GetFunctionList) failed: %s", dlerror()); -- 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); - 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 && -+ strncmp(uri->lib_manuf, m->info.manufacturerID, 32)) { -+ debug_f("Skipping provider %s not matching library_manufacturer", -+ m->info.manufacturerID); - goto fail; - } -- debug("provider %s: manufacturerID <%.*s> cryptokiVersion %d.%d" -- " libraryDescription <%.*s> libraryVersion %d.%d", -- provider_id, -- RMSPACE(p->info.manufacturerID), -- p->info.cryptokiVersion.major, -- p->info.cryptokiVersion.minor, -- RMSPACE(p->info.libraryDescription), -- p->info.libraryVersion.major, -- p->info.libraryVersion.minor); -- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); -+ debug("provider %s: manufacturerID <%.32s> cryptokiVersion %d.%d" -+ " libraryDescription <%.32s> libraryVersion %d.%d", -+ provider_module, -+ m->info.manufacturerID, -+ m->info.cryptokiVersion.major, -+ 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); - 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)); -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); - p->valid = 1; -- nkeys = 0; -- for (i = 0; i < p->nslots; i++) { -- token = &p->slotinfo[i].token; -- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ m->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; - } - debug("provider %s slot %lu: label <%.*s> " - "manufacturerID <%.*s> model <%.*s> serial <%.*s> " - "flags 0x%lx", -- provider_id, (unsigned long)i, -+ provider_module, (unsigned long)i, - RMSPACE(token->label), RMSPACE(token->manufacturerID), - RMSPACE(token->model), RMSPACE(token->serialNumber), - token->flags); -+ } -+ m->module_path = provider_module; -+ provider_module = NULL; -+ -+ /* now owned by caller */ -+ *providerp = p; -+ -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ -+ 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 (p) { -+ free(p->name); -+ free(p); -+ } -+ 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; -+ -+ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { -+ goto fail; -+ } -+ -+ 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 && -+ strncmp(token->label, uri->token, 32) != 0) { -+ debug2_f("ignoring token not matching label (%.32s) " -+ "specified by PKCS#11 URI in slot %lu", -+ token->label, (unsigned long)i); -+ continue; -+ } -+ if (uri->manuf != NULL && -+ strncmp(token->manufacturerID, uri->manuf, 32) != 0) { -+ debug2_f("ignoring token not matching requrested " -+ "manufacturerID (%.32s) specified by PKCS#11 URI in " -+ "slot %lu", token->manufacturerID, (unsigned long)i); -+ continue; -+ } -+ if (uri->serial != NULL && -+ strncmp(token->serialNumber, uri->serial, 16) != 0) { -+ debug2_f("ignoring token not matching requrested " -+ "serialNumber (%s) specified by PKCS#11 URI in " -+ "slot %lu", token->serialNumber, (unsigned long)i); -+ continue; -+ } -+ debug("provider %s slot %lu: label <%.32s> manufacturerID <%.32s> " -+ "model <%.16s> serial <%.16s> flags 0x%lx", -+ provider_uri, (unsigned long)i, -+ token->label, token->manufacturerID, token->model, -+ token->serialNumber, token->flags); - /* -- * open session, login with pin and retrieve public -- * keys (if keyp is provided) -+ * open session if not yet opened, login with pin and -+ * retrieve public keys (if keyp is provided) - */ -- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || -+ 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 (%.32s) ", -+ 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) -+{ -+ 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) - { - 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) { -@@ -1714,7 +2053,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(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"); -+ -+ 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); -+ } -+ -+ 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 52602231..9ce20c1f 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" -+ - 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 c23d3b9e..98b103c9 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -890,6 +890,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; -+ } -+#endif - p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) == -1) - fprintf(stderr, "Warning: Identity file %s " -@@ -1847,6 +1855,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); -@@ -2370,6 +2379,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; -+ -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ 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); -+ } -+ -+ pkcs11_uri_cleanup(uri); -+} -+#endif /* ENABLE_PKCS11 */ -+ - /* Loads all IdentityFile and CertificateFile keys */ - static void - load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2384,11 +2432,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)); -@@ -2401,33 +2444,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); -+ -+ 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); -+ -+ /* 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 3a8e246c..8d5d0722 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -1263,6 +1263,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.49.0 - diff --git a/0034-openssh-8.0p1-preserve-pam-errors.patch b/openssh-8.0p1-preserve-pam-errors.patch similarity index 67% rename from 0034-openssh-8.0p1-preserve-pam-errors.patch rename to openssh-8.0p1-preserve-pam-errors.patch index 15e59c2..b7ab965 100644 --- a/0034-openssh-8.0p1-preserve-pam-errors.patch +++ b/openssh-8.0p1-preserve-pam-errors.patch @@ -1,17 +1,7 @@ -From 8de0391e3b3eb75e23ee9f173f04a9c78f2b96c9 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 34/50] openssh-8.0p1-preserve-pam-errors - ---- - auth-pam.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/auth-pam.c b/auth-pam.c -index b4100ea1..a042c3c8 100644 ---- a/auth-pam.c -+++ b/auth-pam.c -@@ -523,7 +523,11 @@ sshpam_thread(void *ctxtp) +diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c +--- openssh-8.0p1/auth-pam.c.preserve-pam-errors 2021-03-31 17:03:15.618592347 +0200 ++++ openssh-8.0p1/auth-pam.c 2021-03-31 17:06:58.115220014 +0200 +@@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp) goto auth_fail; if (!do_pam_account()) { @@ -24,7 +14,7 @@ index b4100ea1..a042c3c8 100644 goto auth_fail; } if (sshpam_authctxt->force_pwchange) { -@@ -580,8 +584,10 @@ sshpam_thread(void *ctxtp) +@@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp) pam_strerror(sshpam_handle, sshpam_err))) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* XXX - can't do much about an error here */ @@ -37,20 +27,17 @@ index b4100ea1..a042c3c8 100644 else if (sshpam_maxtries_reached) ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer); else -@@ -890,9 +896,11 @@ sshpam_query(void *ctx, char **name, char **info, +@@ -856,9 +862,11 @@ sshpam_query(void *ctx, char **name, cha free(msg); break; case PAM_ACCT_EXPIRED: + sshpam_account_status = 0; + /* FALLTHROUGH */ case PAM_MAXTRIES: -- if (type == PAM_ACCT_EXPIRED) -- sshpam_account_status = 0; + case PAM_USER_UNKNOWN: + case PAM_PERM_DENIED: +- if (type == PAM_ACCT_EXPIRED) +- sshpam_account_status = 0; if (type == PAM_MAXTRIES) sshpam_set_maxtries_reached(1); /* FALLTHROUGH */ --- -2.49.0 - diff --git a/0032-openssh-8.2p1-visibility.patch b/openssh-8.2p1-visibility.patch similarity index 62% rename from 0032-openssh-8.2p1-visibility.patch rename to openssh-8.2p1-visibility.patch index c67373c..89c35ef 100644 --- a/0032-openssh-8.2p1-visibility.patch +++ b/openssh-8.2p1-visibility.patch @@ -1,17 +1,8 @@ -From 6aa231d9acfeca870ee87e3bf9c4a1239518706d Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 32/50] openssh-8.2p1-visibility - ---- - regress/misc/sk-dummy/sk-dummy.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - diff --git a/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c -index 347b2122..344f8a8a 100644 +index dca158de..afdcb1d2 100644 --- a/regress/misc/sk-dummy/sk-dummy.c +++ b/regress/misc/sk-dummy/sk-dummy.c -@@ -81,7 +81,7 @@ skdebug(const char *func, const char *fmt, ...) +@@ -71,7 +71,7 @@ skdebug(const char *func, const char *fmt, ...) #endif } @@ -20,7 +11,7 @@ index 347b2122..344f8a8a 100644 sk_api_version(void) { return SSH_SK_VERSION_MAJOR; -@@ -230,7 +230,7 @@ check_options(struct sk_option **options) +@@ -220,7 +220,7 @@ check_options(struct sk_option **options) return 0; } @@ -29,7 +20,7 @@ index 347b2122..344f8a8a 100644 sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, const char *application, uint8_t flags, const char *pin, struct sk_option **options, struct sk_enroll_response **enroll_response) -@@ -478,7 +478,7 @@ sig_ed25519(const uint8_t *message, size_t message_len, +@@ -467,7 +467,7 @@ sig_ed25519(const uint8_t *message, size_t message_len, return ret; } @@ -38,7 +29,7 @@ index 347b2122..344f8a8a 100644 sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, const char *application, const uint8_t *key_handle, size_t key_handle_len, uint8_t flags, const char *pin, struct sk_option **options, -@@ -535,7 +535,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, +@@ -518,7 +518,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len, return ret; } @@ -47,6 +38,3 @@ index 347b2122..344f8a8a 100644 sk_load_resident_keys(const char *pin, struct sk_option **options, struct sk_resident_key ***rks, size_t *nrks) { --- -2.49.0 - diff --git a/0033-openssh-8.2p1-x11-without-ipv6.patch b/openssh-8.2p1-x11-without-ipv6.patch similarity index 55% rename from 0033-openssh-8.2p1-x11-without-ipv6.patch rename to openssh-8.2p1-x11-without-ipv6.patch index 32a9056..8b83bc3 100644 --- a/0033-openssh-8.2p1-x11-without-ipv6.patch +++ b/openssh-8.2p1-x11-without-ipv6.patch @@ -1,17 +1,12 @@ -From cfe5a99d335eb57b8c08b4eb6b4535dd042d96e3 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 33/50] openssh-8.2p1-x11-without-ipv6 - ---- - channels.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - diff --git a/channels.c b/channels.c -index 7438c1a5..95836d50 100644 --- a/channels.c +++ b/channels.c -@@ -5055,6 +5055,16 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +@@ -3933,16 +3933,26 @@ x11_create_display_inet(int x11_display_ + if (ai->ai_family == AF_INET6) + sock_set_v6only(sock); + if (x11_use_localhost) + set_reuseaddr(sock); + if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { debug2_f("bind port %d: %.100s", port, strerror(errno)); close(sock); @@ -28,6 +23,8 @@ index 7438c1a5..95836d50 100644 for (n = 0; n < num_socks; n++) close(socks[n]); num_socks = 0; --- -2.49.0 - + break; + } + socks[num_socks++] = sock; + if (num_socks == NUM_SOCKS) + break; diff --git a/openssh-8.7p1-ibmca.patch b/openssh-8.7p1-ibmca.patch new file mode 100644 index 0000000..88914bf --- /dev/null +++ b/openssh-8.7p1-ibmca.patch @@ -0,0 +1,11 @@ +--- openssh-8.7p1/openbsd-compat/bsd-closefrom.c.orig 2022-04-12 15:47:03.815044607 +0200 ++++ openssh-8.7p1/openbsd-compat/bsd-closefrom.c 2022-04-12 15:48:12.464963511 +0200 +@@ -16,7 +16,7 @@ + + #include "includes.h" + +-#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) ++#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__) + + #include + #include diff --git a/0037-openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch similarity index 63% rename from 0037-openssh-8.7p1-minrsabits.patch rename to openssh-8.7p1-minrsabits.patch index 59e530b..d8577d2 100644 --- a/0037-openssh-8.7p1-minrsabits.patch +++ b/openssh-8.7p1-minrsabits.patch @@ -1,18 +1,7 @@ -From 286bc4a302b5130f732c857095ae665f7bea01dd Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 37/50] openssh-8.7p1-minrsabits - ---- - readconf.c | 1 + - servconf.c | 1 + - 2 files changed, 2 insertions(+) - diff --git a/readconf.c b/readconf.c -index 6c04ed43..f340bf50 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -343,6 +343,7 @@ static struct { +--- a/readconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/readconf.c (date 1703169891147) +@@ -326,6 +326,7 @@ { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, { "requiredrsasize", oRequiredRSASize }, @@ -21,10 +10,9 @@ index 6c04ed43..f340bf50 100644 { "obscurekeystroketiming", oObscureKeystrokeTiming }, { "channeltimeout", oChannelTimeout }, diff --git a/servconf.c b/servconf.c -index 15c99b30..84891544 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -788,6 +788,7 @@ static struct { +--- a/servconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/servconf.c (date 1703169891148) +@@ -691,6 +691,7 @@ { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, @@ -32,6 +20,3 @@ index 15c99b30..84891544 100644 { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, --- -2.49.0 - diff --git a/0044-openssh-8.7p1-negotiate-supported-algs.patch b/openssh-8.7p1-negotiate-supported-algs.patch similarity index 74% rename from 0044-openssh-8.7p1-negotiate-supported-algs.patch rename to openssh-8.7p1-negotiate-supported-algs.patch index f4c3b8a..c4d86e7 100644 --- a/0044-openssh-8.7p1-negotiate-supported-algs.patch +++ b/openssh-8.7p1-negotiate-supported-algs.patch @@ -1,17 +1,6 @@ -From 5c92430c08ac392b5b2ace899cc043247c923734 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 44/50] openssh-8.7p1-negotiate-supported-algs - ---- - regress/hostkey-agent.sh | 32 +++++++++++++++++++++++++------- - sshconnect2.c | 17 +++++++++++++++-- - 2 files changed, 40 insertions(+), 9 deletions(-) - -diff --git a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh -index 28dcfe17..b9e716dc 100644 ---- a/regress/hostkey-agent.sh -+++ b/regress/hostkey-agent.sh +diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostkey-agent.sh +--- openssh-9.3p1/regress/hostkey-agent.sh.xxx 2023-05-29 18:15:56.311236887 +0200 ++++ openssh-9.3p1/regress/hostkey-agent.sh 2023-05-29 18:16:07.598503551 +0200 @@ -17,8 +17,21 @@ trace "make CA key" ${SSHKEYGEN} -qt ed25519 -f $OBJ/agent-ca -N '' || fatal "ssh-keygen CA" @@ -35,7 +24,7 @@ index 28dcfe17..b9e716dc 100644 ${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" ${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \ -I localhost-with-alias $OBJ/agent-key.$k.pub || \ -@@ -32,12 +45,16 @@ rm $OBJ/agent-ca # Don't need CA private any more either +@@ -32,12 +48,16 @@ rm $OBJ/agent-ca # Don't need CA private unset SSH_AUTH_SOCK @@ -55,10 +44,10 @@ index 28dcfe17..b9e716dc 100644 ( printf 'localhost-with-alias,127.0.0.1,::1 ' ; cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` -@@ -50,15 +67,16 @@ for k in $SSH_KEYTYPES ; do +@@ -50,15 +70,16 @@ for k in $SSH_KEYTYPES ; do done - SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com' | maybe_filter_sk` + SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com'` +SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"` # Prepare sshd_proxy for certificates. @@ -74,7 +63,7 @@ index 28dcfe17..b9e716dc 100644 echo "Hostkey $OBJ/agent-key.${k}.pub" >> $OBJ/sshd_proxy echo "HostCertificate $OBJ/agent-key.${k}-cert.pub" >> $OBJ/sshd_proxy test -f $OBJ/agent-key.${k}.pub || fatal "no $k key" -@@ -70,7 +88,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >> $OBJ/sshd_proxy +@@ -70,7 +93,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >> ( printf '@cert-authority localhost-with-alias ' ; cat $OBJ/agent-ca.pub) > $OBJ/known_hosts @@ -83,11 +72,10 @@ index 28dcfe17..b9e716dc 100644 verbose "cert type $k" opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy" SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` -diff --git a/sshconnect2.c b/sshconnect2.c -index 14f7671a..ad3f560f 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c +--- openssh-9.3p1/sshconnect2.c.xxx 2023-04-26 17:37:35.100827792 +0200 ++++ openssh-9.3p1/sshconnect2.c 2023-04-26 17:50:31.860748877 +0200 +@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, st const struct ssh_conn_info *cinfo) { char *myproposal[PROPOSAL_MAX]; @@ -96,7 +84,7 @@ index 14f7671a..ad3f560f 100644 int r, use_known_hosts_order = 0; #if defined(GSSAPI) && defined(WITH_OPENSSL) -@@ -257,10 +257,22 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +@@ -260,10 +260,22 @@ ssh_kex2(struct ssh *ssh, char *host, st if (use_known_hosts_order) hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo); @@ -120,7 +108,7 @@ index 14f7671a..ad3f560f 100644 #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { -@@ -304,6 +316,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +@@ -303,6 +315,7 @@ ssh_kex2(struct ssh *ssh, char *host, st #endif free(hkalgs); @@ -128,6 +116,3 @@ index 14f7671a..ad3f560f 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) --- -2.49.0 - diff --git a/0046-openssh-8.7p1-nohostsha1proof.patch b/openssh-8.7p1-nohostsha1proof.patch similarity index 69% rename from 0046-openssh-8.7p1-nohostsha1proof.patch rename to openssh-8.7p1-nohostsha1proof.patch index 9e75c8a..dae0932 100644 --- a/0046-openssh-8.7p1-nohostsha1proof.patch +++ b/openssh-8.7p1-nohostsha1proof.patch @@ -1,27 +1,7 @@ -From e4ca3b9dba1cc832a9974493c91207d42e218a68 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 46/50] openssh-8.7p1-nohostsha1proof - ---- - compat.c | 6 +++++ - compat.h | 2 +- - monitor.c | 27 ++++++++++++++++------ - regress/unittests/kex/test_kex.c | 3 ++- - regress/unittests/sshkey/test_file.c | 3 ++- - regress/unittests/sshkey/test_fuzz.c | 3 ++- - regress/unittests/sshkey/test_sshkey.c | 32 +++++++++++++++++--------- - serverloop.c | 6 ++++- - ssh-rsa.c | 3 ++- - sshconnect2.c | 8 +++++++ - sshd-session.c | 21 +++++++++++++++++ - 11 files changed, 90 insertions(+), 24 deletions(-) - -diff --git a/compat.c b/compat.c -index b59f0bfc..4e611dc3 100644 ---- a/compat.c -+++ b/compat.c -@@ -42,6 +42,7 @@ void +diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c +--- openssh-8.7p1/compat.c.sshrsacheck 2023-01-12 13:29:06.338710923 +0100 ++++ openssh-8.7p1/compat.c 2023-01-12 13:29:06.357711165 +0100 +@@ -43,6 +43,7 @@ void compat_banner(struct ssh *ssh, const char *version) { int i; @@ -29,7 +9,7 @@ index b59f0bfc..4e611dc3 100644 static struct { char *pat; int bugs; -@@ -125,16 +126,21 @@ compat_banner(struct ssh *ssh, const char *version) +@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha }; /* process table, return first match */ @@ -51,10 +31,9 @@ index b59f0bfc..4e611dc3 100644 } /* Always returns pointer to allocated memory, caller must free. */ -diff --git a/compat.h b/compat.h -index 1a19060f..2e6db5bf 100644 ---- a/compat.h -+++ b/compat.h +diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h +--- openssh-8.7p1/compat.h.sshrsacheck 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/compat.h 2023-01-12 13:29:06.358711178 +0100 @@ -30,7 +30,7 @@ #define SSH_BUG_UTF8TTYMODE 0x00000001 #define SSH_BUG_SIGTYPE 0x00000002 @@ -64,28 +43,24 @@ index 1a19060f..2e6db5bf 100644 #define SSH_OLD_SESSIONID 0x00000010 /* #define unused 0x00000020 */ #define SSH_BUG_DEBUG 0x00000040 -diff --git a/monitor.c b/monitor.c -index fbc35782..19cb058e 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -747,11 +747,12 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) - struct sshkey *pubkey, *key; +diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c +--- openssh-8.7p1/monitor.c.sshrsacheck 2023-01-20 13:07:54.279676981 +0100 ++++ openssh-8.7p1/monitor.c 2023-01-20 15:01:07.007821379 +0100 +@@ -660,11 +660,12 @@ mm_answer_sign(struct ssh *ssh, int sock + struct sshkey *key; struct sshbuf *sigbuf = NULL; u_char *p = NULL, *signature = NULL; - char *alg = NULL; -- size_t datlen, siglen; -- int r, is_proof = 0, keyid; -- u_int compat; + char *alg = NULL, *effective_alg; -+ size_t datlen, siglen, alglen; -+ int r, is_proof = 0; -+ u_int keyid, compat; + size_t datlen, siglen, alglen; + int r, is_proof = 0; + u_int keyid, compat; const char proof_req[] = "hostkeys-prove-00@openssh.com"; + const char safe_rsa[] = "rsa-sha2-256"; debug3_f("entering"); -@@ -809,18 +810,30 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -719,18 +720,30 @@ mm_answer_sign(struct ssh *ssh, int sock } if ((key = get_hostkey_by_index(keyid)) != NULL) { @@ -119,11 +94,10 @@ index fbc35782..19cb058e 100644 is_proof ? "hostkey proof" : "KEX", siglen); sshbuf_reset(m); -diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c -index caf8f57f..09016aea 100644 ---- a/regress/unittests/kex/test_kex.c -+++ b/regress/unittests/kex/test_kex.c -@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype, int bits) +diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p1/regress/unittests/kex/test_kex.c +--- openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck 2023-01-26 13:34:52.645743677 +0100 ++++ openssh-8.7p1/regress/unittests/kex/test_kex.c 2023-01-26 13:36:56.220745823 +0100 +@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype, memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); if (kex != NULL) kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; @@ -133,11 +107,10 @@ index caf8f57f..09016aea 100644 ASSERT_PTR_NE(keyname, NULL); kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname; ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0); -diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c -index 3babe604..cc80fe97 100644 ---- a/regress/unittests/sshkey/test_file.c -+++ b/regress/unittests/sshkey/test_file.c -@@ -109,6 +109,7 @@ sshkey_file_tests(void) +diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_file.c +--- openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck 2023-01-26 12:04:55.946343408 +0100 ++++ openssh-8.7p1/regress/unittests/sshkey/test_file.c 2023-01-26 12:06:35.235164432 +0100 +@@ -110,6 +110,7 @@ sshkey_file_tests(void) sshkey_free(k2); TEST_DONE(); @@ -145,7 +118,7 @@ index 3babe604..cc80fe97 100644 TEST_START("load RSA cert with SHA1 signature"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); -@@ -116,7 +117,7 @@ sshkey_file_tests(void) +@@ -117,7 +118,7 @@ sshkey_file_tests(void) ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); ASSERT_STRING_EQ(k2->cert->signature_type, "ssh-rsa"); sshkey_free(k2); @@ -154,11 +127,10 @@ index 3babe604..cc80fe97 100644 TEST_START("load RSA cert with SHA512 signature"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0); -diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c -index 0aff7c9b..951122e1 100644 ---- a/regress/unittests/sshkey/test_fuzz.c -+++ b/regress/unittests/sshkey/test_fuzz.c -@@ -338,13 +338,14 @@ sshkey_fuzz_tests(void) +diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c +--- openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck 2023-01-26 12:10:37.533168013 +0100 ++++ openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c 2023-01-26 12:15:35.637631860 +0100 +@@ -333,13 +333,14 @@ sshkey_fuzz_tests(void) TEST_DONE(); #ifdef WITH_OPENSSL @@ -174,11 +146,10 @@ index 0aff7c9b..951122e1 100644 TEST_START("fuzz RSA SHA256 sig"); buf = load_file("rsa_1"); -diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c -index 5bf4b65c..6d0a35bb 100644 ---- a/regress/unittests/sshkey/test_sshkey.c -+++ b/regress/unittests/sshkey/test_sshkey.c -@@ -61,6 +61,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type, +diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c +--- openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck 2023-01-26 11:02:52.339413463 +0100 ++++ openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c 2023-01-26 11:58:42.324253896 +0100 +@@ -60,6 +60,9 @@ build_cert(struct sshbuf *b, struct sshk u_char *sigblob; size_t siglen; @@ -188,7 +159,7 @@ index 5bf4b65c..6d0a35bb 100644 ca_buf = sshbuf_new(); ASSERT_PTR_NE(ca_buf, NULL); ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); -@@ -102,8 +105,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type, +@@ -101,8 +104,9 @@ build_cert(struct sshbuf *b, struct sshk ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, @@ -200,7 +171,7 @@ index 5bf4b65c..6d0a35bb 100644 free(sigblob); sshbuf_free(ca_buf); -@@ -120,16 +124,22 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, +@@ -119,16 +123,22 @@ signature_test(struct sshkey *k, struct { size_t len; u_char *sig; @@ -231,7 +202,7 @@ index 5bf4b65c..6d0a35bb 100644 free(sig); } -@@ -526,7 +536,7 @@ sshkey_tests(void) +@@ -514,7 +524,7 @@ sshkey_tests(void) ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); k3 = get_private("rsa_1"); @@ -240,10 +211,9 @@ index 5bf4b65c..6d0a35bb 100644 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); ASSERT_PTR_EQ(k4, NULL); -diff --git a/serverloop.c b/serverloop.c -index 40ddfb04..9c5b1567 100644 ---- a/serverloop.c -+++ b/serverloop.c +diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c +--- openssh-8.7p1/serverloop.c.sshrsacheck 2023-01-12 14:57:08.118400073 +0100 ++++ openssh-8.7p1/serverloop.c 2023-01-12 14:59:17.330470518 +0100 @@ -80,6 +80,7 @@ #include "auth-options.h" #include "serverloop.h" @@ -252,11 +222,10 @@ index 40ddfb04..9c5b1567 100644 extern ServerOptions options; -@@ -699,7 +700,10 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) +@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh * else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) sigalg = "rsa-sha2-256"; } -- + if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) { + sigalg = "rsa-sha2-512"; + debug3_f("SHA1 signature is not supported, falling back to %s", sigalg); @@ -264,25 +233,10 @@ index 40ddfb04..9c5b1567 100644 debug3_f("sign %s key (index %d) using sigalg %s", sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); if ((r = sshbuf_put_cstring(sigbuf, -diff --git a/ssh-rsa.c b/ssh-rsa.c -index 6c2f771a..8dd4ab01 100644 ---- a/ssh-rsa.c -+++ b/ssh-rsa.c -@@ -509,7 +509,8 @@ ssh_rsa_verify(const struct sshkey *key, - ret = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -- if (hash_alg != want_alg) { -+ if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) { -+ debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg); - ret = SSH_ERR_SIGNATURE_INVALID; - goto out; - } -diff --git a/sshconnect2.c b/sshconnect2.c -index ad3f560f..3941e089 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -1434,6 +1434,14 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp, +diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c +--- openssh-8.7p1/sshconnect2.c.sshrsacheck 2023-01-25 15:33:29.140353651 +0100 ++++ openssh-8.7p1/sshconnect2.c 2023-01-25 15:59:34.225364883 +0100 +@@ -1461,6 +1464,14 @@ identity_sign(struct identity *id, u_cha retried = 1; goto retry_pin; } @@ -297,11 +251,23 @@ index ad3f560f..3941e089 100644 goto out; } -diff --git a/sshd-session.c b/sshd-session.c -index a808ac9a..c3349a8a 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -1316,6 +1316,27 @@ main(int ac, char **av) +diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c +--- openssh-8.7p1/ssh-rsa.c.sshrsacheck 2023-01-20 13:07:54.180676144 +0100 ++++ openssh-8.7p1/ssh-rsa.c 2023-01-20 13:07:54.290677074 +0100 +@@ -254,7 +254,8 @@ ssh_rsa_verify(const struct sshkey *key, + ret = SSH_ERR_INVALID_ARGUMENT; + goto out; + } +- if (hash_alg != want_alg) { ++ if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) { ++ debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg); + ret = SSH_ERR_SIGNATURE_INVALID; + goto out; + } +diff -up openssh-9.8p1/sshd-session.c.xxx openssh-9.8p1/sshd-session.c +--- openssh-9.8p1/sshd-session.c.xxx 2024-07-23 15:08:14.794350818 +0200 ++++ openssh-9.8p1/sshd-session.c 2024-07-23 15:40:21.658456636 +0200 +@@ -1305,6 +1305,27 @@ main(int ac, char **av) check_ip_options(ssh); @@ -329,6 +295,3 @@ index a808ac9a..c3349a8a 100644 /* Prepare the channels layer */ channel_init_channels(ssh); channel_set_af(ssh, options.address_family); --- -2.49.0 - diff --git a/0036-openssh-8.7p1-recursive-scp.patch b/openssh-8.7p1-recursive-scp.patch similarity index 73% rename from 0036-openssh-8.7p1-recursive-scp.patch rename to openssh-8.7p1-recursive-scp.patch index 929b408..17c340e 100644 --- a/0036-openssh-8.7p1-recursive-scp.patch +++ b/openssh-8.7p1-recursive-scp.patch @@ -1,21 +1,8 @@ -From 99e1e3af524376788e591ca73387f1ca37e6f5ef Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 36/50] openssh-8.7p1-recursive-scp - ---- - scp.c | 2 +- - sftp-client.c | 60 +++++++++++++++++++++++++++++++++++++++------------ - sftp-client.h | 4 ++-- - sftp.c | 6 +++--- - 4 files changed, 52 insertions(+), 20 deletions(-) - diff --git a/scp.c b/scp.c -index 7ed1a54c..0c87dd0e 100644 ---- a/scp.c -+++ b/scp.c -@@ -1388,7 +1388,7 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) - +--- a/scp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/scp.c (date 1703111453316) +@@ -1372,7 +1372,7 @@ + if (src_is_dir && iamrecursive) { if (sftp_upload_dir(conn, src, abs_dst, pflag, - SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) { @@ -24,11 +11,10 @@ index 7ed1a54c..0c87dd0e 100644 errs = 1; } diff --git a/sftp-client.c b/sftp-client.c -index 9f8ab4af..873dec04 100644 ---- a/sftp-client.c -+++ b/sftp-client.c -@@ -1003,7 +1003,7 @@ sftp_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, - +--- a/sftp-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp-client.c (date 1703169614263) +@@ -1003,7 +1003,7 @@ + /* Implements both the realpath and expand-path operations */ static char * -sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) @@ -36,7 +22,7 @@ index 9f8ab4af..873dec04 100644 { struct sshbuf *msg; u_int expected_id, count, id; -@@ -1049,11 +1049,43 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) +@@ -1049,11 +1049,43 @@ if ((r = sshbuf_get_u32(msg, &status)) != 0 || (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0) fatal_fr(r, "parse status"); @@ -85,9 +71,9 @@ index 9f8ab4af..873dec04 100644 } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); -@@ -1078,9 +1110,9 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) +@@ -1078,9 +1110,9 @@ } - + char * -sftp_realpath(struct sftp_conn *conn, const char *path) +sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir) @@ -95,9 +81,9 @@ index 9f8ab4af..873dec04 100644 - return sftp_realpath_expand(conn, path, 0); + return sftp_realpath_expand(conn, path, 0, create_dir); } - + int -@@ -1094,9 +1126,9 @@ sftp_expand_path(struct sftp_conn *conn, const char *path) +@@ -1094,9 +1126,9 @@ { if (!sftp_can_expand_path(conn)) { debug3_f("no server support, fallback to realpath"); @@ -107,18 +93,18 @@ index 9f8ab4af..873dec04 100644 - return sftp_realpath_expand(conn, path, 1); + return sftp_realpath_expand(conn, path, 1, 0); } - + int -@@ -2016,7 +2048,7 @@ sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst, +@@ -2016,7 +2048,7 @@ char *src_canon; int ret; - + - if ((src_canon = sftp_realpath(conn, src)) == NULL) { + if ((src_canon = sftp_realpath(conn, src, 0)) == NULL) { error("download \"%s\": path canonicalization failed", src); return -1; } -@@ -2366,12 +2398,12 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, +@@ -2365,12 +2397,12 @@ int sftp_upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int preserve_flag, int print_flag, int resume, int fsync_flag, @@ -127,48 +113,47 @@ index 9f8ab4af..873dec04 100644 { char *dst_canon; int ret; - + - if ((dst_canon = sftp_realpath(conn, dst)) == NULL) { + if ((dst_canon = sftp_realpath(conn, dst, create_dir)) == NULL) { error("upload \"%s\": path canonicalization failed", dst); return -1; } -@@ -2826,7 +2858,7 @@ sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to, +@@ -2825,7 +2857,7 @@ char *from_path_canon; int ret; - + - if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) { + if ((from_path_canon = sftp_realpath(from, from_path, 0)) == NULL) { error("crossload \"%s\": path canonicalization failed", from_path); return -1; diff --git a/sftp-client.h b/sftp-client.h -index 74cdae7d..00ed6630 100644 ---- a/sftp-client.h -+++ b/sftp-client.h -@@ -111,7 +111,7 @@ int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *); +--- a/sftp-client.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp-client.h (date 1703111691284) +@@ -111,7 +111,7 @@ int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); - + /* Canonicalise 'path' - caller must free result */ -char *sftp_realpath(struct sftp_conn *, const char *); +char *sftp_realpath(struct sftp_conn *, const char *, int); - + /* Canonicalisation with tilde expansion (requires server extension) */ char *sftp_expand_path(struct sftp_conn *, const char *); -@@ -163,7 +163,7 @@ int sftp_upload(struct sftp_conn *, const char *, const char *, +@@ -163,7 +163,7 @@ * times if 'pflag' is set */ int sftp_upload_dir(struct sftp_conn *, const char *, const char *, - int, int, int, int, int, int); + int, int, int, int, int, int, int); - + /* * Download a 'from_path' from the 'from' connection and upload it to + diff --git a/sftp.c b/sftp.c -index bdedd141..322e6d1f 100644 ---- a/sftp.c -+++ b/sftp.c -@@ -809,7 +809,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst, +--- a/sftp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp.c (date 1703168795365) +@@ -807,7 +807,7 @@ (rflag || global_rflag)) { if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst, pflag || global_pflag, 1, resume, @@ -177,7 +162,7 @@ index bdedd141..322e6d1f 100644 err = -1; } else { if (sftp_upload(conn, g.gl_pathv[i], abs_dst, -@@ -1644,7 +1644,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, +@@ -1642,7 +1642,7 @@ if (path1 == NULL || *path1 == '\0') path1 = xstrdup(startdir); path1 = sftp_make_absolute(path1, *pwd); @@ -186,15 +171,12 @@ index bdedd141..322e6d1f 100644 err = 1; break; } -@@ -2249,7 +2249,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) +@@ -2247,7 +2247,7 @@ } #endif /* USE_LIBEDIT */ - + - if ((remote_path = sftp_realpath(conn, ".")) == NULL) + if ((remote_path = sftp_realpath(conn, ".", 0)) == NULL) fatal("Need cwd"); startdir = xstrdup(remote_path); - --- -2.49.0 diff --git a/0010-openssh-8.7p1-redhat.patch b/openssh-8.7p1-redhat.patch similarity index 64% rename from 0010-openssh-8.7p1-redhat.patch rename to openssh-8.7p1-redhat.patch index cb3d140..4e9d108 100644 --- a/0010-openssh-8.7p1-redhat.patch +++ b/openssh-8.7p1-redhat.patch @@ -1,26 +1,7 @@ -From 5f21983f6472b26693babea4d6ca6b95a7dc7b05 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 10/50] openssh-8.7p1-redhat - ---- - ssh_config | 7 +++++++ - ssh_config_redhat | 18 ++++++++++++++++++ - sshd_config | 8 ++++++++ - sshd_config.0 | 6 +++--- - sshd_config.5 | 2 +- - sshd_config_redhat | 18 ++++++++++++++++++ - sshd_config_redhat_cp | 7 +++++++ - 7 files changed, 62 insertions(+), 4 deletions(-) - create mode 100644 ssh_config_redhat - create mode 100644 sshd_config_redhat - create mode 100644 sshd_config_redhat_cp - -diff --git a/ssh_config b/ssh_config -index cc566356..18169187 100644 ---- a/ssh_config -+++ b/ssh_config -@@ -44,3 +44,10 @@ +diff -up openssh/ssh_config.redhat openssh/ssh_config +--- openssh/ssh_config.redhat 2020-02-11 23:28:35.000000000 +0100 ++++ openssh/ssh_config 2020-02-13 18:13:39.180641839 +0100 +@@ -43,3 +43,10 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h # UserKnownHostsFile ~/.ssh/known_hosts.d/%k @@ -31,12 +12,10 @@ index cc566356..18169187 100644 +# included below. For more information, see manual page for +# update-crypto-policies(8) and ssh_config(5). +Include /etc/ssh/ssh_config.d/*.conf -diff --git a/ssh_config_redhat b/ssh_config_redhat -new file mode 100644 -index 00000000..8b1b5902 ---- /dev/null -+++ b/ssh_config_redhat -@@ -0,0 +1,18 @@ +diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat +--- openssh/ssh_config_redhat.redhat 2020-02-13 18:13:39.180641839 +0100 ++++ openssh/ssh_config_redhat 2020-02-13 18:13:39.180641839 +0100 +@@ -0,0 +1,15 @@ +# The options here are in the "Match final block" to be applied as the last +# options and could be potentially overwritten by the user configuration +Match final all @@ -50,35 +29,12 @@ index 00000000..8b1b5902 +# mode correctly we set this to yes. + ForwardX11Trusted yes + -+# rhbz#2352653 - export COLORTERM -+ SendEnv COLORTERM -+ +# Uncomment this if you want to use .local domain +# Host *.local -diff --git a/sshd_config b/sshd_config -index 0f4a3a72..608203e4 100644 ---- a/sshd_config -+++ b/sshd_config -@@ -10,6 +10,14 @@ - # possible, but leave them commented. Uncommented options override the - # default value. - -+# To modify the system-wide sshd configuration, create a *.conf file under -+# /etc/ssh/sshd_config.d/ which will be automatically included below -+Include /etc/ssh/sshd_config.d/*.conf -+ -+# If you want to change the port on a SELinux system, you have to tell -+# SELinux about this change. -+# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER -+# - #Port 22 - #AddressFamily any - #ListenAddress 0.0.0.0 -diff --git a/sshd_config.0 b/sshd_config.0 -index 2f77b4f4..49349bb3 100644 ---- a/sshd_config.0 -+++ b/sshd_config.0 -@@ -1219,9 +1219,9 @@ DESCRIPTION +diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0 +--- openssh/sshd_config.0.redhat 2020-02-12 14:30:04.000000000 +0100 ++++ openssh/sshd_config.0 2020-02-13 18:13:39.181641855 +0100 +@@ -970,9 +970,9 @@ DESCRIPTION SyslogFacility Gives the facility code that is used when logging messages from @@ -91,11 +47,10 @@ index 2f77b4f4..49349bb3 100644 TCPKeepAlive Specifies whether the system should send TCP keepalive messages -diff --git a/sshd_config.5 b/sshd_config.5 -index c0771737..035a50c8 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -1942,7 +1942,7 @@ By default no subsystems are defined. +diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5 +--- openssh/sshd_config.5.redhat 2020-02-11 23:28:35.000000000 +0100 ++++ openssh/sshd_config.5 2020-02-13 18:13:39.181641855 +0100 +@@ -1614,7 +1614,7 @@ By default no subsystems are defined. .It Cm SyslogFacility Gives the facility code that is used when logging messages from .Xr sshd 8 . @@ -104,12 +59,28 @@ index c0771737..035a50c8 100644 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. .It Cm TCPKeepAlive -diff --git a/sshd_config_redhat b/sshd_config_redhat -new file mode 100644 -index 00000000..993a28d5 ---- /dev/null -+++ b/sshd_config_redhat -@@ -0,0 +1,18 @@ +diff -up openssh/sshd_config.redhat openssh/sshd_config +--- openssh/sshd_config.redhat 2020-02-11 23:28:35.000000000 +0100 ++++ openssh/sshd_config 2020-02-13 18:20:16.349913681 +0100 +@@ -10,6 +10,14 @@ + # possible, but leave them commented. Uncommented options override the + # default value. + ++# To modify the system-wide sshd configuration, create a *.conf file under ++# /etc/ssh/sshd_config.d/ which will be automatically included below ++Include /etc/ssh/sshd_config.d/*.conf ++ ++# If you want to change the port on a SELinux system, you have to tell ++# SELinux about this change. ++# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER ++# + #Port 22 + #AddressFamily any + #ListenAddress 0.0.0.0 +diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat +--- openssh/sshd_config_redhat.redhat 2020-02-13 18:14:02.268006439 +0100 ++++ openssh/sshd_config_redhat 2020-02-13 18:19:20.765035947 +0100 +@@ -0,0 +1,15 @@ +SyslogFacility AUTHPRIV + +KbdInteractiveAuthentication no @@ -121,18 +92,13 @@ index 00000000..993a28d5 + +X11Forwarding yes + -+# rhbz#2352653 - accept COLORTERM -+ AcceptEnv COLORTERM -+ +# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd, +# as it is more configurable and versatile than the built-in version. +PrintMotd no + -diff --git a/sshd_config_redhat_cp b/sshd_config_redhat_cp -new file mode 100644 -index 00000000..1d592d13 ---- /dev/null -+++ b/sshd_config_redhat_cp +diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat +--- openssh/sshd_config_redhat_cp.redhat 2020-02-13 18:14:02.268006439 +0100 ++++ openssh/sshd_config_redhat_cp 2020-02-13 18:19:20.765035947 +0100 @@ -0,0 +1,7 @@ +# This system is following system-wide crypto policy. The changes to +# crypto properties (Ciphers, MACs, ...) will not have any effect in @@ -141,6 +107,3 @@ index 00000000..1d592d13 +# Please, see manual pages for update-crypto-policies(8) and sshd_config(5). +Include /etc/crypto-policies/back-ends/opensshserver.config + --- -2.49.0 - diff --git a/0035-openssh-8.7p1-scp-kill-switch.patch b/openssh-8.7p1-scp-kill-switch.patch similarity index 57% rename from 0035-openssh-8.7p1-scp-kill-switch.patch rename to openssh-8.7p1-scp-kill-switch.patch index 58a5036..161ab2d 100644 --- a/0035-openssh-8.7p1-scp-kill-switch.patch +++ b/openssh-8.7p1-scp-kill-switch.patch @@ -1,18 +1,6 @@ -From a68f3741fdc01bf6823a69d2442caba7de9835f9 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 35/50] openssh-8.7p1-scp-kill-switch - ---- - pathnames.h | 1 + - scp.1 | 7 +++++++ - scp.c | 8 ++++++++ - 3 files changed, 16 insertions(+) - -diff --git a/pathnames.h b/pathnames.h -index 1158bec9..43f0c570 100644 ---- a/pathnames.h -+++ b/pathnames.h +diff -up openssh-8.7p1/pathnames.h.kill-scp openssh-8.7p1/pathnames.h +--- openssh-8.7p1/pathnames.h.kill-scp 2021-09-16 11:37:57.240171687 +0200 ++++ openssh-8.7p1/pathnames.h 2021-09-16 11:42:29.183427917 +0200 @@ -42,6 +42,7 @@ #define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" @@ -21,11 +9,10 @@ index 1158bec9..43f0c570 100644 #ifndef _PATH_SSH_PROGRAM #define _PATH_SSH_PROGRAM "/usr/bin/ssh" -diff --git a/scp.1 b/scp.1 -index aa2e2d8b..373d7237 100644 ---- a/scp.1 -+++ b/scp.1 -@@ -331,6 +331,13 @@ during download or upload. +diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1 +--- openssh-8.7p1/scp.1.kill-scp 2021-09-16 12:09:02.646714578 +0200 ++++ openssh-8.7p1/scp.1 2021-09-16 12:26:49.978628226 +0200 +@@ -278,6 +278,13 @@ to print debugging messages about their By default a 32KB buffer is used. .El .El @@ -39,11 +26,10 @@ index aa2e2d8b..373d7237 100644 .Sh EXIT STATUS .Ex -std scp .Sh SEE ALSO -diff --git a/scp.c b/scp.c -index 7f9795a5..7ed1a54c 100644 ---- a/scp.c -+++ b/scp.c -@@ -649,6 +649,14 @@ main(int argc, char **argv) +diff -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c +--- openssh-8.7p1/scp.c.kill-scp 2021-09-16 11:42:56.013650519 +0200 ++++ openssh-8.7p1/scp.c 2021-09-16 11:53:03.249713836 +0200 +@@ -596,6 +596,14 @@ main(int argc, char **argv) if (iamremote) mode = MODE_SCP; @@ -58,6 +44,3 @@ index 7f9795a5..7ed1a54c 100644 if ((pwd = getpwuid(userid = getuid())) == NULL) fatal("unknown user %u", (u_int) userid); --- -2.49.0 - diff --git a/openssh-8.7p1-ssh-manpage.patch b/openssh-8.7p1-ssh-manpage.patch new file mode 100644 index 0000000..c7f6f1e --- /dev/null +++ b/openssh-8.7p1-ssh-manpage.patch @@ -0,0 +1,53 @@ +diff --color -ru a/ssh.1 b/ssh.1 +--- a/ssh.1 2022-07-12 11:47:51.307295880 +0200 ++++ b/ssh.1 2022-07-12 11:50:28.793363263 +0200 +@@ -493,6 +493,7 @@ + .It AddressFamily + .It BatchMode + .It BindAddress ++.It BindInterface + .It CanonicalDomains + .It CanonicalizeFallbackLocal + .It CanonicalizeHostname +@@ -510,6 +511,7 @@ + .It ControlPath + .It ControlPersist + .It DynamicForward ++.It EnableSSHKeysign + .It EnableEscapeCommandline + .It EscapeChar + .It ExitOnForwardFailure +@@ -538,6 +540,8 @@ + .It IdentitiesOnly + .It IdentityAgent + .It IdentityFile ++.It IgnoreUnknown ++.It Include + .It IPQoS + .It KbdInteractiveAuthentication + .It KbdInteractiveDevices +@@ -546,6 +550,7 @@ + .It LocalCommand + .It LocalForward + .It LogLevel ++.It LogVerbose + .It MACs + .It Match + .It NoHostAuthenticationForLocalhost +@@ -566,6 +571,8 @@ + .It RemoteCommand + .It RemoteForward + .It RequestTTY ++.It RevokedHostKeys ++.It SecurityKeyProvider + .It RequiredRSASize + .It SendEnv + .It ServerAliveInterval +@@ -575,6 +582,7 @@ + .It StreamLocalBindMask + .It StreamLocalBindUnlink + .It StrictHostKeyChecking ++.It SyslogFacility + .It TCPKeepAlive + .It Tunnel + .It TunnelDevice diff --git a/0041-openssh-9.0p1-audit-log.patch b/openssh-9.0p1-audit-log.patch similarity index 85% rename from 0041-openssh-9.0p1-audit-log.patch rename to openssh-9.0p1-audit-log.patch index e04f31b..ae9550f 100644 --- a/0041-openssh-9.0p1-audit-log.patch +++ b/openssh-9.0p1-audit-log.patch @@ -1,20 +1,7 @@ -From 80d967a18261156573e7385f8e534a89d2767d67 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 41/50] openssh-9.0p1-audit-log - ---- - audit-bsm.c | 2 +- - audit-linux.c | 76 +++++++++++++++++++++++++++++++++++++++++++-------- - audit.c | 18 +++++++++--- - audit.h | 2 +- - 4 files changed, 81 insertions(+), 17 deletions(-) - -diff --git a/audit-bsm.c b/audit-bsm.c -index a49abb92..c6f56553 100644 ---- a/audit-bsm.c -+++ b/audit-bsm.c -@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li) +diff -up openssh-9.0p1/audit-bsm.c.patch openssh-9.0p1/audit-bsm.c +--- openssh-9.0p1/audit-bsm.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit-bsm.c 2022-10-24 14:51:43.685766639 +0200 +@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li } int @@ -23,10 +10,51 @@ index a49abb92..c6f56553 100644 { /* not implemented */ } -diff --git a/audit-linux.c b/audit-linux.c -index d484b82b..dcfde3a9 100644 ---- a/audit-linux.c -+++ b/audit-linux.c +diff -up openssh-9.0p1/audit.c.patch openssh-9.0p1/audit.c +--- openssh-9.0p1/audit.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit.c 2022-10-24 15:20:38.854548226 +0200 +@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev) + void + audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) + { +- char *fp; ++ char *key_fp = NULL; ++ char *issuer_fp = NULL; ++ struct sshkey_cert *cert = NULL; + +- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); +- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) ++ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) { ++ cert = key->cert; ++ issuer_fp = sshkey_fingerprint(cert->signature_key, ++ options.fingerprint_hash, SSH_FP_DEFAULT); ++ } ++ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0) + *rv = -SSH_ERR_INTERNAL_ERROR; +- free(fp); ++ if (key_fp) ++ free(key_fp); ++ if (issuer_fp) ++ free(issuer_fp); + } + + void +diff -up openssh-9.0p1/audit.h.patch openssh-9.0p1/audit.h +--- openssh-9.0p1/audit.h.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit.h 2022-10-24 14:58:20.887565518 +0200 +@@ -64,7 +64,7 @@ void audit_session_close(struct logininf + int audit_run_command(struct ssh *, const char *); + void audit_end_command(struct ssh *, int, const char *); + ssh_audit_event_t audit_classify_auth(const char *); +-int audit_keyusage(struct ssh *, int, char *, int); ++int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int); + void audit_key(struct ssh *, int, int *, const struct sshkey *); + void audit_unsupported(struct ssh *, int); + void audit_kex(struct ssh *, int, char *, char *, char *, char *); +diff -up openssh-9.9p1/audit-linux.c.xxx openssh-9.9p1/audit-linux.c +--- openssh-9.9p1/audit-linux.c.xxx 2024-10-15 11:49:48.092151974 +0200 ++++ openssh-9.9p1/audit-linux.c 2024-10-15 12:08:17.179158343 +0200 @@ -52,7 +52,7 @@ extern u_int utmp_len; const char *audit_username(void); @@ -36,7 +64,7 @@ index d484b82b..dcfde3a9 100644 const char *ip, const char *ttyn, int success, int event) { int audit_fd, rc, saved_errno; -@@ -66,7 +66,7 @@ linux_audit_user_logxxx(int uid, const char *username, +@@ -66,7 +66,7 @@ linux_audit_user_logxxx(int uid, const c } rc = audit_log_acct_message(audit_fd, event, NULL, "login", username ? username : "(unknown)", @@ -59,7 +87,7 @@ index d484b82b..dcfde3a9 100644 audit_fd = audit_open(); if (audit_fd < 0) { -@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) +@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host else return 0; /* Must prevent login */ } @@ -107,7 +135,7 @@ index d484b82b..dcfde3a9 100644 out: saved_errno = errno; audit_close(audit_fd); -@@ -179,26 +211,34 @@ audit_connection_from(const char *host, int port) +@@ -179,26 +211,34 @@ audit_connection_from(const char *host, int audit_run_command(struct ssh *ssh, const char *command) { @@ -189,7 +217,7 @@ index d484b82b..dcfde3a9 100644 ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; case SSH_AUTH_FAIL_PASSWD: -@@ -255,9 +305,11 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) +@@ -255,9 +305,11 @@ audit_event(struct ssh *ssh, ssh_audit_e if (user_login_count) { while (user_login_count--) linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, @@ -201,7 +229,7 @@ index d484b82b..dcfde3a9 100644 ssh_remote_ipaddr(ssh), "ssh", 1, AUDIT_USER_LOGOUT); } -@@ -266,12 +318,14 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) +@@ -266,12 +318,14 @@ audit_event(struct ssh *ssh, ssh_audit_e case SSH_CONNECTION_ABANDON: case SSH_INVALID_USER: linux_audit_user_logxxx(-1, audit_username(), @@ -216,50 +244,3 @@ index d484b82b..dcfde3a9 100644 } void -diff --git a/audit.c b/audit.c -index d0433c3a..28d51a14 100644 ---- a/audit.c -+++ b/audit.c -@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev) - void - audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) - { -- char *fp; -+ char *key_fp = NULL; -+ char *issuer_fp = NULL; -+ struct sshkey_cert *cert = NULL; - -- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) -+ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); -+ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) { -+ cert = key->cert; -+ issuer_fp = sshkey_fingerprint(cert->signature_key, -+ options.fingerprint_hash, SSH_FP_DEFAULT); -+ } -+ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0) - *rv = -SSH_ERR_INTERNAL_ERROR; -- free(fp); -+ if (key_fp) -+ free(key_fp); -+ if (issuer_fp) -+ free(issuer_fp); - } - - void -diff --git a/audit.h b/audit.h -index 45d66ccf..05ac132c 100644 ---- a/audit.h -+++ b/audit.h -@@ -64,7 +64,7 @@ void audit_session_close(struct logininfo *); - int audit_run_command(struct ssh *, const char *); - void audit_end_command(struct ssh *, int, const char *); - ssh_audit_event_t audit_classify_auth(const char *); --int audit_keyusage(struct ssh *, int, char *, int); -+int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int); - void audit_key(struct ssh *, int, int *, const struct sshkey *); - void audit_unsupported(struct ssh *, int); - void audit_kex(struct ssh *, int, char *, char *, char *, char *); --- -2.49.0 - diff --git a/0045-openssh-9.0p1-evp-fips-kex.patch b/openssh-9.0p1-evp-fips-kex.patch similarity index 90% rename from 0045-openssh-9.0p1-evp-fips-kex.patch rename to openssh-9.0p1-evp-fips-kex.patch index 610cea0..36fd1cf 100644 --- a/0045-openssh-9.0p1-evp-fips-kex.patch +++ b/openssh-9.0p1-evp-fips-kex.patch @@ -1,20 +1,6 @@ -From be23afbab800c9b5ffea56b3f410a04156c08df2 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 45/50] openssh-9.0p1-evp-fips-kex - ---- - dh.c | 98 +++++++++++++++++++++++++++++++++----- - kex.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - kex.h | 6 +++ - kexdh.c | 52 ++++++++++++++++++-- - kexecdh.c | 129 ++++++++++++++++++++++++++++++++++++++++---------- - 5 files changed, 382 insertions(+), 42 deletions(-) - -diff --git a/dh.c b/dh.c -index 8c9a29fa..ea0a0b09 100644 ---- a/dh.c -+++ b/dh.c +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/dh.c openssh-9.0p1-patched/dh.c +--- openssh-9.0p1/dh.c 2023-05-25 09:24:28.730868316 +0200 ++++ openssh-9.0p1-patched/dh.c 2023-05-25 09:23:44.841379532 +0200 @@ -37,6 +37,9 @@ #include #include @@ -25,7 +11,7 @@ index 8c9a29fa..ea0a0b09 100644 #include "dh.h" #include "pathnames.h" -@@ -290,10 +293,15 @@ dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub) +@@ -290,10 +293,15 @@ int dh_gen_key(DH *dh, int need) { @@ -44,7 +30,7 @@ index 8c9a29fa..ea0a0b09 100644 if (need < 0 || dh_p == NULL || (pbits = BN_num_bits(dh_p)) <= 0 || -@@ -301,19 +309,85 @@ dh_gen_key(DH *dh, int need) +@@ -301,19 +309,85 @@ return SSH_ERR_INVALID_ARGUMENT; if (need < 256) need = 256; @@ -139,11 +125,10 @@ index 8c9a29fa..ea0a0b09 100644 } DH * -diff --git a/kex.c b/kex.c -index 71fbe5cb..ce6a7b81 100644 ---- a/kex.c -+++ b/kex.c -@@ -1614,3 +1614,142 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.c openssh-9.0p1-patched/kex.c +--- openssh-9.0p1/kex.c 2023-05-25 09:24:28.731868327 +0200 ++++ openssh-9.0p1-patched/kex.c 2023-05-25 09:23:44.841379532 +0200 +@@ -1623,3 +1623,142 @@ return r; } @@ -286,34 +271,9 @@ index 71fbe5cb..ce6a7b81 100644 + return r; +} +#endif /* WITH_OPENSSL */ -diff --git a/kex.h b/kex.h -index 6a55aadf..48f3bb87 100644 ---- a/kex.h -+++ b/kex.h -@@ -37,6 +37,9 @@ - # include - # include - # include -+# include -+# include -+# include - # ifdef OPENSSL_HAS_ECC - # include - # else /* OPENSSL_HAS_ECC */ -@@ -311,6 +314,9 @@ int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], - const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) - __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) - __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); -+int kex_create_evp_dh(EVP_PKEY **, const BIGNUM *, const BIGNUM *, -+ const BIGNUM *, const BIGNUM *, const BIGNUM *); -+int kex_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey); - - #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) - void dump_digest(const char *, const u_char *, int); -diff --git a/kexdh.c b/kexdh.c -index 0faab21b..32e1de51 100644 ---- a/kexdh.c -+++ b/kexdh.c +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kexdh.c openssh-9.0p1-patched/kexdh.c +--- openssh-9.0p1/kexdh.c 2023-05-25 09:24:28.674867692 +0200 ++++ openssh-9.0p1-patched/kexdh.c 2023-05-25 09:25:28.494533889 +0200 @@ -35,6 +35,10 @@ #include "openbsd-compat/openssl-compat.h" @@ -325,7 +285,7 @@ index 0faab21b..32e1de51 100644 #include "sshkey.h" #include "kex.h" -@@ -83,9 +87,12 @@ int +@@ -83,9 +87,12 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) { BIGNUM *shared_secret = NULL; @@ -339,7 +299,7 @@ index 0faab21b..32e1de51 100644 #ifdef DEBUG_KEXDH fprintf(stderr, "dh_pub= "); -@@ -100,24 +107,59 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) +@@ -100,24 +107,59 @@ r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } @@ -403,10 +363,32 @@ index 0faab21b..32e1de51 100644 return r; } -diff --git a/kexecdh.c b/kexecdh.c -index efb2e55a..d92ba54f 100644 ---- a/kexecdh.c -+++ b/kexecdh.c +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.h openssh-9.0p1-patched/kex.h +--- openssh-9.0p1/kex.h 2023-05-25 09:24:28.725868260 +0200 ++++ openssh-9.0p1-patched/kex.h 2023-05-25 09:23:44.841379532 +0200 +@@ -33,6 +33,9 @@ + # include + # include + # include ++# include ++# include ++# include + # ifdef OPENSSL_HAS_ECC + # include + # else /* OPENSSL_HAS_ECC */ +@@ -283,6 +286,9@@ + const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); ++int kex_create_evp_dh(EVP_PKEY **, const BIGNUM *, const BIGNUM *, ++ const BIGNUM *, const BIGNUM *, const BIGNUM *); ++int kex_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey); + + #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) + void dump_digest(const char *, const u_char *, int); +diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../openssh-8.7p1/kexecdh.c ./kexecdh.c +--- ../openssh-8.7p1/kexecdh.c 2021-08-20 06:03:49.000000000 +0200 ++++ ./kexecdh.c 2023-04-13 14:30:14.882449593 +0200 @@ -35,17 +35,57 @@ #include @@ -465,7 +447,7 @@ index efb2e55a..d92ba54f 100644 int kex_ecdh_keypair(struct kex *kex) { -@@ -55,11 +95,7 @@ kex_ecdh_keypair(struct kex *kex) +@@ -55,11 +95,7 @@ struct sshbuf *buf = NULL; int r; @@ -478,7 +460,7 @@ index efb2e55a..d92ba54f 100644 r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -@@ -101,11 +137,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, +@@ -101,11 +137,7 @@ *server_blobp = NULL; *shared_secretp = NULL; @@ -491,7 +473,7 @@ index efb2e55a..d92ba54f 100644 r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -@@ -140,11 +172,21 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, +@@ -140,11 +172,21 @@ { struct sshbuf *buf = NULL; BIGNUM *shared_secret = NULL; @@ -516,7 +498,7 @@ index efb2e55a..d92ba54f 100644 *shared_secretp = NULL; if ((buf = sshbuf_new()) == NULL) { -@@ -153,45 +195,82 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, +@@ -153,45 +195,82 @@ } if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0) goto out; @@ -611,6 +593,3 @@ index efb2e55a..d92ba54f 100644 sshbuf_free(buf); return r; } --- -2.49.0 - diff --git a/0012-openssh-9.6p1-gssapi-keyex.patch b/openssh-9.6p1-gssapi-keyex.patch similarity index 89% rename from 0012-openssh-9.6p1-gssapi-keyex.patch rename to openssh-9.6p1-gssapi-keyex.patch index f5f54f7..ef1f97e 100644 --- a/0012-openssh-9.6p1-gssapi-keyex.patch +++ b/openssh-9.6p1-gssapi-keyex.patch @@ -1,111 +1,25 @@ -From 754b023b92aa68742258c55243a6ae8f30ed5a17 Mon Sep 17 00:00:00 2001 -From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 12/50] openssh-9.6p1-gssapi-keyex - ---- - Makefile.in | 7 +- - auth.c | 3 +- - auth2-gss.c | 52 +++- - auth2-methods.c | 6 + - auth2.c | 2 + - canohost.c | 93 +++++++ - canohost.h | 3 + - clientloop.c | 12 + - configure.ac | 24 ++ - gss-genr.c | 302 ++++++++++++++++++++- - gss-serv-krb5.c | 97 ++++++- - gss-serv.c | 200 ++++++++++++-- - kex-names.c | 62 ++++- - kex.c | 35 ++- - kex.h | 34 +++ - kexdh.c | 10 + - kexgen.c | 2 +- - kexgssc.c | 706 ++++++++++++++++++++++++++++++++++++++++++++++++ - kexgsss.c | 601 +++++++++++++++++++++++++++++++++++++++++ - monitor.c | 147 +++++++++- - 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 | 64 ++++- - ssh.1 | 8 + - ssh.c | 6 +- - ssh_config | 2 + - ssh_config.5 | 58 ++++ - sshconnect2.c | 154 ++++++++++- - sshd-auth.c | 53 ++++ - sshd-session.c | 9 +- - sshd.c | 3 +- - sshd_config | 2 + - sshd_config.5 | 31 +++ - sshkey.c | 72 ++++- - sshkey.h | 1 + - 41 files changed, 2984 insertions(+), 76 deletions(-) - create mode 100644 kexgssc.c - create mode 100644 kexgsss.c - -diff --git a/Makefile.in b/Makefile.in -index 438efc51..78f65948 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -117,6 +117,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ - kexgexc.o kexgexs.o \ - kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ -+ kexgssc.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o +diff --color -ruNp a/auth2.c b/auth2.c +--- a/auth2.c 2024-09-16 11:45:56.858133241 +0200 ++++ b/auth2.c 2024-09-16 11:46:34.688939755 +0200 +@@ -71,6 +71,7 @@ extern Authmethod method_passwd; + extern Authmethod method_kbdint; + extern Authmethod method_hostbased; + #ifdef GSSAPI ++extern Authmethod method_gsskeyex; + extern Authmethod method_gssapi; + #endif -@@ -138,7 +139,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ - auth2-chall.o groupaccess.o \ - auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ -- monitor.o monitor_wrap.o auth-krb5.o \ -+ monitor.o monitor_wrap.o auth-krb5.o kexgsss.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ - sftp-server.o sftp-common.o \ -@@ -150,7 +151,7 @@ SSHD_AUTH_OBJS=sshd-auth.o \ - serverloop.o auth.o auth2.o auth-options.o session.o auth2-chall.o \ - groupaccess.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ -- auth2-gss.o gss-serv.o gss-serv-krb5.o \ -+ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ - monitor_wrap.o auth-krb5.o \ - audit.o audit-bsm.o audit-linux.o platform.o \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ -@@ -563,7 +564,7 @@ regress-prep: - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile - - REGRESSLIBS=libssh.a $(LIBCOMPAT) --TESTLIBS=$(LIBS) $(CHANNELLIBS) -+TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) - - regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ -diff --git a/auth.c b/auth.c -index 9a6e5a31..e4578169 100644 ---- a/auth.c -+++ b/auth.c -@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) - case PERMIT_NO_PASSWD: - if (strcmp(method, "publickey") == 0 || - strcmp(method, "hostbased") == 0 || -- strcmp(method, "gssapi-with-mic") == 0) -+ strcmp(method, "gssapi-with-mic") == 0 || -+ strcmp(method, "gssapi-keyex") == 0) - return 1; - break; - case PERMIT_FORCED_ONLY: -diff --git a/auth2-gss.c b/auth2-gss.c -index f7898ab3..5b1b9cde 100644 ---- a/auth2-gss.c -+++ b/auth2-gss.c +@@ -78,6 +79,7 @@ Authmethod *authmethods[] = { + &method_none, + &method_pubkey, + #ifdef GSSAPI ++ &method_gsskeyex, + &method_gssapi, + #endif + &method_passwd, +diff --color -ruNp a/auth2-gss.c b/auth2-gss.c +--- a/auth2-gss.c 2024-09-16 11:45:56.858133241 +0200 ++++ b/auth2-gss.c 2024-09-16 11:46:34.689939776 +0200 @@ -51,6 +51,7 @@ #define SSH_GSSAPI_MAX_MECHS 2048 @@ -114,11 +28,10 @@ index f7898ab3..5b1b9cde 100644 extern struct authmethod_cfg methodcfg_gssapi; static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); -@@ -58,6 +59,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); +@@ -59,6 +60,48 @@ static int input_gssapi_exchange_complet static int input_gssapi_errtok(int, u_int32_t, struct ssh *); -+/* + /* + * The 'gssapi_keyex' userauth mechanism. + */ +static int @@ -160,10 +73,11 @@ index f7898ab3..5b1b9cde 100644 + return (authenticated); +} + - /* ++/* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -267,7 +310,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) + */ +@@ -267,7 +310,7 @@ input_gssapi_exchange_complete(int type, if ((r = sshpkt_get_end(ssh)) != 0) fatal_fr(r, "parse packet"); @@ -172,7 +86,7 @@ index f7898ab3..5b1b9cde 100644 authctxt->postponed = 0; ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -315,7 +358,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -315,7 +358,7 @@ input_gssapi_mic(int type, u_int32_t ple gssbuf.length = sshbuf_len(b); if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))) @@ -181,7 +95,7 @@ index f7898ab3..5b1b9cde 100644 else logit("GSSAPI MIC check failed"); -@@ -333,6 +376,11 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -333,6 +376,11 @@ input_gssapi_mic(int type, u_int32_t ple return 0; } @@ -193,11 +107,10 @@ index f7898ab3..5b1b9cde 100644 Authmethod method_gssapi = { &methodcfg_gssapi, userauth_gssapi, -diff --git a/auth2-methods.c b/auth2-methods.c -index 99637a89..a05908cf 100644 ---- a/auth2-methods.c -+++ b/auth2-methods.c -@@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = { +diff --color -ruNp a/auth2-methods.c b/auth2-methods.c +--- a/auth2-methods.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/auth2-methods.c 2024-09-16 11:46:34.689939776 +0200 +@@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = &options.pubkey_authentication }; #ifdef GSSAPI @@ -209,7 +122,7 @@ index 99637a89..a05908cf 100644 struct authmethod_cfg methodcfg_gssapi = { "gssapi-with-mic", NULL, -@@ -76,6 +81,7 @@ static struct authmethod_cfg *authmethod_cfgs[] = { +@@ -76,6 +81,7 @@ static struct authmethod_cfg *authmethod &methodcfg_none, &methodcfg_pubkey, #ifdef GSSAPI @@ -217,30 +130,22 @@ index 99637a89..a05908cf 100644 &methodcfg_gssapi, #endif &methodcfg_passwd, -diff --git a/auth2.c b/auth2.c -index 5ba45c12..8ec41de2 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -71,6 +71,7 @@ extern Authmethod method_passwd; - extern Authmethod method_kbdint; - extern Authmethod method_hostbased; - #ifdef GSSAPI -+extern Authmethod method_gsskeyex; - extern Authmethod method_gssapi; - #endif - -@@ -78,6 +79,7 @@ Authmethod *authmethods[] = { - &method_none, - &method_pubkey, - #ifdef GSSAPI -+ &method_gsskeyex, - &method_gssapi, - #endif - &method_passwd, -diff --git a/canohost.c b/canohost.c -index 28f086e5..875805c9 100644 ---- a/canohost.c -+++ b/canohost.c +diff --color -ruNp a/auth.c b/auth.c +--- a/auth.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/auth.c 2024-09-16 11:46:34.690939798 +0200 +@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || +- strcmp(method, "gssapi-with-mic") == 0) ++ strcmp(method, "gssapi-with-mic") == 0 || ++ strcmp(method, "gssapi-keyex") == 0) + return 1; + break; + case PERMIT_FORCED_ONLY: +diff --color -ruNp a/canohost.c b/canohost.c +--- a/canohost.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/canohost.c 2024-09-16 11:46:34.690939798 +0200 @@ -35,6 +35,99 @@ #include "canohost.h" #include "misc.h" @@ -341,10 +246,9 @@ index 28f086e5..875805c9 100644 void ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) { -diff --git a/canohost.h b/canohost.h -index 26d62855..0cadc9f1 100644 ---- a/canohost.h -+++ b/canohost.h +diff --color -ruNp a/canohost.h b/canohost.h +--- a/canohost.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/canohost.h 2024-09-16 11:46:34.690939798 +0200 @@ -15,6 +15,9 @@ #ifndef _CANOHOST_H #define _CANOHOST_H @@ -355,10 +259,9 @@ index 26d62855..0cadc9f1 100644 char *get_peer_ipaddr(int); int get_peer_port(int); char *get_local_ipaddr(int); -diff --git a/clientloop.c b/clientloop.c -index 916fc077..4655f91f 100644 ---- a/clientloop.c -+++ b/clientloop.c +diff --color -ruNp a/clientloop.c b/clientloop.c +--- a/clientloop.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/clientloop.c 2024-09-16 11:46:34.690939798 +0200 @@ -115,6 +115,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -370,7 +273,7 @@ index 916fc077..4655f91f 100644 /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -@@ -1591,6 +1595,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, +@@ -1590,6 +1594,14 @@ client_loop(struct ssh *ssh, int have_pt /* Do channel operations. */ channel_after_poll(ssh, pfd, npfd_active); @@ -385,11 +288,10 @@ index 916fc077..4655f91f 100644 /* Buffer input from the connection. */ if (conn_in_ready) client_process_net_input(ssh); -diff --git a/configure.ac b/configure.ac -index d546788c..13c70a98 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -786,6 +786,30 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +diff --color -ruNp a/configure.ac b/configure.ac +--- a/configure.ac 2024-09-16 11:45:56.870133497 +0200 ++++ b/configure.ac 2024-09-16 11:46:34.691939819 +0200 +@@ -774,6 +774,30 @@ int main(void) { if (NSVersionOfRunTimeL [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -420,10 +322,9 @@ index d546788c..13c70a98 100644 m4_pattern_allow([AU_IPv]) 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 aa34b71c..3034370c 100644 ---- a/gss-genr.c -+++ b/gss-genr.c +diff --color -ruNp a/gss-genr.c b/gss-genr.c +--- a/gss-genr.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/gss-genr.c 2024-09-16 11:46:34.708940181 +0200 @@ -42,9 +42,33 @@ #include "sshbuf.h" #include "log.h" @@ -458,7 +359,7 @@ index aa34b71c..3034370c 100644 /* sshbuf_get for gss_buffer_desc */ int 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) +@@ -60,6 +84,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf return 0; } @@ -639,7 +540,7 @@ index aa34b71c..3034370c 100644 free(*ctx); *ctx = NULL; -@@ -216,7 +400,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, +@@ -216,7 +400,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -648,11 +549,10 @@ index aa34b71c..3034370c 100644 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -245,9 +429,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) - return (ctx->major); +@@ -246,8 +430,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } -+OM_uint32 + OM_uint32 +ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) +{ + gss_buffer_desc gssbuf; @@ -683,7 +583,7 @@ index aa34b71c..3034370c 100644 + return(ctx->major); +} + - OM_uint32 ++OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) { + if (ctx == NULL) @@ -692,7 +592,7 @@ index aa34b71c..3034370c 100644 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -255,6 +473,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) +@@ -255,6 +473,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -712,7 +612,7 @@ index aa34b71c..3034370c 100644 void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context, const struct sshbuf *session_id) -@@ -271,11 +502,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, +@@ -271,11 +502,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, co } int @@ -730,7 +630,7 @@ index aa34b71c..3034370c 100644 /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -285,6 +521,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -285,6 +521,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -741,7 +641,7 @@ index aa34b71c..3034370c 100644 if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -294,10 +534,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -294,10 +534,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx GSS_C_NO_BUFFER); } @@ -809,150 +709,9 @@ index aa34b71c..3034370c 100644 +} + #endif /* GSSAPI */ -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index a151bc1e..8d2b677f 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c -@@ -1,7 +1,7 @@ - /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */ - - /* -- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. -+ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions -@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - krb5_error_code problem; - krb5_principal princ; - OM_uint32 maj_status, min_status; -- int len; -+ const char *new_ccname, *new_cctype; - const char *errmsg; - - if (client->creds == NULL) { -@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - return; - } - -- client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); -+ new_cctype = krb5_cc_get_type(krb_context, ccache); -+ new_ccname = krb5_cc_get_name(krb_context, ccache); -+ - client->store.envvar = "KRB5CCNAME"; -- len = strlen(client->store.filename) + 6; -- client->store.envval = xmalloc(len); -- snprintf(client->store.envval, len, "FILE:%s", client->store.filename); -+#ifdef USE_CCAPI -+ xasprintf(&client->store.envval, "API:%s", new_ccname); -+ client->store.filename = NULL; -+#else -+ if (new_ccname[0] == ':') -+ new_ccname++; -+ xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); -+ if (strcmp(new_cctype, "DIR") == 0) { -+ char *p; -+ p = strrchr(client->store.envval, '/'); -+ if (p) -+ *p = '\0'; -+ } -+ if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) -+ client->store.filename = xstrdup(new_ccname); -+#endif - - #ifdef USE_PAM - if (options.use_pam) -@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) - - krb5_cc_close(krb_context, ccache); - -+ client->store.data = krb_context; -+ - return; - } - -+int -+ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, -+ ssh_gssapi_client *client) -+{ -+ krb5_ccache ccache = NULL; -+ krb5_principal principal = NULL; -+ char *name = NULL; -+ krb5_error_code problem; -+ OM_uint32 maj_status, min_status; -+ -+ if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { -+ logit("krb5_cc_resolve(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ return 0; -+ } -+ -+ /* Find out who the principal in this cache is */ -+ if ((problem = krb5_cc_get_principal(krb_context, ccache, -+ &principal))) { -+ logit("krb5_cc_get_principal(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ if ((problem = krb5_unparse_name(krb_context, principal, &name))) { -+ logit("krb5_unparse_name(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ -+ if (strcmp(name,client->exportedname.value)!=0) { -+ debug("Name in local credentials cache differs. Not storing"); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ krb5_free_unparsed_name(krb_context, name); -+ return 0; -+ } -+ krb5_free_unparsed_name(krb_context, name); -+ -+ /* Name matches, so lets get on with it! */ -+ -+ if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { -+ logit("krb5_cc_initialize(): %.100s", -+ krb5_get_err_text(krb_context, problem)); -+ krb5_free_principal(krb_context, principal); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ krb5_free_principal(krb_context, principal); -+ -+ if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, -+ ccache))) { -+ logit("gss_krb5_copy_ccache() failed. Sorry!"); -+ krb5_cc_close(krb_context, ccache); -+ return 0; -+ } -+ -+ return 1; -+} -+ - ssh_gssapi_mech gssapi_kerberos_mech = { - "toWM5Slw5Ew8Mqkay+al2g==", - "Kerberos", -@@ -203,7 +285,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { - NULL, - &ssh_gssapi_krb5_userok, - NULL, -- &ssh_gssapi_krb5_storecreds -+ &ssh_gssapi_krb5_storecreds, -+ &ssh_gssapi_krb5_updatecreds - }; - - #endif /* KRB5 */ -diff --git a/gss-serv.c b/gss-serv.c -index 025a118f..a5cca797 100644 ---- a/gss-serv.c -+++ b/gss-serv.c +diff --color -ruNp a/gss-serv.c b/gss-serv.c +--- a/gss-serv.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/gss-serv.c 2024-09-16 11:46:34.692939840 +0200 @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ @@ -962,7 +721,7 @@ index 025a118f..a5cca797 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -45,17 +45,19 @@ +@@ -44,17 +44,19 @@ #include "session.h" #include "misc.h" #include "servconf.h" @@ -985,11 +744,10 @@ index 025a118f..a5cca797 100644 #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -141,6 +143,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) - return (ssh_gssapi_acquire_cred(*ctx)); +@@ -141,6 +143,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss } -+/* Unprivileged */ + /* Unprivileged */ +char * +ssh_gssapi_server_mechanisms(void) { + if (supported_oids == NULL) @@ -1012,10 +770,11 @@ index 025a118f..a5cca797 100644 + return (res); +} + - /* Unprivileged */ ++/* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) -@@ -151,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) + { +@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -1026,7 +785,7 @@ index 025a118f..a5cca797 100644 while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -277,8 +304,48 @@ OM_uint32 +@@ -276,8 +303,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; @@ -1076,7 +835,7 @@ index 025a118f..a5cca797 100644 client->mech = NULL; -@@ -293,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g if (client->mech == NULL) return GSS_S_FAILURE; @@ -1090,7 +849,7 @@ index 025a118f..a5cca797 100644 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -310,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g return (ctx->major); } @@ -1099,7 +858,7 @@ index 025a118f..a5cca797 100644 /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -320,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g void ssh_gssapi_cleanup_creds(void) { @@ -1125,7 +884,7 @@ index 025a118f..a5cca797 100644 } } -@@ -357,19 +442,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) +@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int /* Privileged */ int @@ -1152,7 +911,7 @@ index 025a118f..a5cca797 100644 /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -383,14 +472,85 @@ ssh_gssapi_userok(char *user) +@@ -382,14 +471,85 @@ ssh_gssapi_userok(char *user) return (0); } @@ -1244,114 +1003,148 @@ index 025a118f..a5cca797 100644 } /* Privileged */ -diff --git a/kex-names.c b/kex-names.c -index ec840c1f..6c0b7c2b 100644 ---- a/kex-names.c -+++ b/kex-names.c -@@ -45,6 +45,10 @@ - #include "ssherr.h" - #include "xmalloc.h" +diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c +--- a/gss-serv-krb5.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/gss-serv-krb5.c 2024-09-16 11:46:34.692939840 +0200 +@@ -1,7 +1,7 @@ + /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */ -+#ifdef GSSAPI -+#include "ssh-gss.h" -+#endif -+ - struct kexalg { - char *name; - u_int type; -@@ -89,15 +93,28 @@ static const struct kexalg kexalgs[] = { - #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, 0, -1, -1}, - }; -+static const struct kexalg gss_kexalgs[] = { -+#ifdef GSSAPI -+ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, -+ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, -+ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, -+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, -+#endif -+ { NULL, 0, -1, -1}, -+}; + /* +- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. ++ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl + krb5_error_code problem; + krb5_principal princ; + OM_uint32 maj_status, min_status; +- int len; ++ const char *new_ccname, *new_cctype; + const char *errmsg; --char * --kex_alg_list(char sep) -+static char * -+kex_alg_list_internal(char sep, const struct kexalg *algs) - { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; - const struct kexalg *k; - -- for (k = kexalgs; k->name != NULL; k++) { -+ for (k = algs; k->name != NULL; k++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(k->name); -@@ -112,6 +129,18 @@ kex_alg_list(char sep) - return ret; - } - -+char * -+kex_alg_list(char sep) -+{ -+ return kex_alg_list_internal(sep, kexalgs); -+} -+ -+char * -+kex_gss_alg_list(char sep) -+{ -+ return kex_alg_list_internal(sep, gss_kexalgs); -+} -+ - static const struct kexalg * - kex_alg_by_name(const char *name) - { -@@ -121,6 +150,10 @@ kex_alg_by_name(const char *name) - if (strcmp(k->name, name) == 0) - return k; + if (client->creds == NULL) { +@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl + return; } -+ for (k = gss_kexalgs; k->name != NULL; k++) { -+ if (strncmp(k->name, name, strlen(k->name)) == 0) -+ return k; + +- client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); ++ new_cctype = krb5_cc_get_type(krb_context, ccache); ++ new_ccname = krb5_cc_get_name(krb_context, ccache); ++ + client->store.envvar = "KRB5CCNAME"; +- len = strlen(client->store.filename) + 6; +- client->store.envval = xmalloc(len); +- snprintf(client->store.envval, len, "FILE:%s", client->store.filename); ++#ifdef USE_CCAPI ++ xasprintf(&client->store.envval, "API:%s", new_ccname); ++ client->store.filename = NULL; ++#else ++ if (new_ccname[0] == ':') ++ new_ccname++; ++ xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); ++ if (strcmp(new_cctype, "DIR") == 0) { ++ char *p; ++ p = strrchr(client->store.envval, '/'); ++ if (p) ++ *p = '\0'; + } - return NULL; ++ if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) ++ client->store.filename = xstrdup(new_ccname); ++#endif + + #ifdef USE_PAM + if (options.use_pam) +@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl + + krb5_cc_close(krb_context, ccache); + ++ client->store.data = krb_context; ++ + return; } -@@ -334,3 +367,26 @@ kex_assemble_names(char **listp, const char *def, const char *all) - free(ret); - return r; - } -+ -+/* Validate GSS KEX method name list */ +int -+kex_gss_names_valid(const char *names) ++ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ++ ssh_gssapi_client *client) +{ -+ char *s, *cp, *p; ++ krb5_ccache ccache = NULL; ++ krb5_principal principal = NULL; ++ char *name = NULL; ++ krb5_error_code problem; ++ OM_uint32 maj_status, min_status; + -+ if (names == NULL || *names == '\0') -+ return 0; -+ s = cp = xstrdup(names); -+ for ((p = strsep(&cp, ",")); p && *p != '\0'; -+ (p = strsep(&cp, ","))) { -+ if (strncmp(p, "gss-", 4) != 0 -+ || kex_alg_by_name(p) == NULL) { -+ error("Unsupported KEX algorithm \"%.100s\"", p); -+ free(s); -+ return 0; -+ } ++ if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { ++ logit("krb5_cc_resolve(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ return 0; + } -+ debug3("gss kex names ok: [%s]", names); -+ free(s); ++ ++ /* Find out who the principal in this cache is */ ++ if ((problem = krb5_cc_get_principal(krb_context, ccache, ++ &principal))) { ++ logit("krb5_cc_get_principal(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ if ((problem = krb5_unparse_name(krb_context, principal, &name))) { ++ logit("krb5_unparse_name(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ ++ if (strcmp(name,client->exportedname.value)!=0) { ++ debug("Name in local credentials cache differs. Not storing"); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ krb5_free_unparsed_name(krb_context, name); ++ return 0; ++ } ++ krb5_free_unparsed_name(krb_context, name); ++ ++ /* Name matches, so lets get on with it! */ ++ ++ if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { ++ logit("krb5_cc_initialize(): %.100s", ++ krb5_get_err_text(krb_context, problem)); ++ krb5_free_principal(krb_context, principal); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ ++ krb5_free_principal(krb_context, principal); ++ ++ if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ++ ccache))) { ++ logit("gss_krb5_copy_ccache() failed. Sorry!"); ++ krb5_cc_close(krb_context, ccache); ++ return 0; ++ } ++ + return 1; +} -diff --git a/kex.c b/kex.c -index 6b957e5e..19a56e8e 100644 ---- a/kex.c -+++ b/kex.c ++ + ssh_gssapi_mech gssapi_kerberos_mech = { + "toWM5Slw5Ew8Mqkay+al2g==", + "Kerberos", +@@ -203,7 +285,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { + NULL, + &ssh_gssapi_krb5_userok, + NULL, +- &ssh_gssapi_krb5_storecreds ++ &ssh_gssapi_krb5_storecreds, ++ &ssh_gssapi_krb5_updatecreds + }; + + #endif /* KRB5 */ +diff --color -ruNp a/kex.c b/kex.c +--- a/kex.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/kex.c 2024-09-16 11:46:34.692939840 +0200 @@ -297,17 +297,37 @@ static int kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m) { @@ -1406,92 +1199,9 @@ index 6b957e5e..19a56e8e 100644 sshbuf_free(kex->initial_sig); sshkey_free(kex->initial_hostkey); free(kex->failed_choice); -diff --git a/kex.h b/kex.h -index d08988b3..0e080ea3 100644 ---- a/kex.h -+++ b/kex.h -@@ -29,6 +29,10 @@ - #include "mac.h" - #include "crypto_api.h" - -+#ifdef GSSAPI -+# include "ssh-gss.h" /* Gssctxt */ -+#endif -+ - #ifdef WITH_OPENSSL - # include - # include -@@ -103,6 +107,15 @@ enum kex_exchange { - KEX_C25519_SHA256, - KEX_KEM_SNTRUP761X25519_SHA512, - KEX_KEM_MLKEM768X25519_SHA256, -+#ifdef GSSAPI -+ KEX_GSS_GRP1_SHA1, -+ KEX_GSS_GRP14_SHA1, -+ KEX_GSS_GRP14_SHA256, -+ KEX_GSS_GRP16_SHA512, -+ KEX_GSS_GEX_SHA1, -+ KEX_GSS_NISTP256_SHA256, -+ KEX_GSS_C25519_SHA256, -+#endif - KEX_MAX - }; - -@@ -165,6 +178,13 @@ struct kex { - u_int flags; - int hash_alg; - int ec_nid; -+#ifdef GSSAPI -+ Gssctxt *gss; -+ int gss_deleg_creds; -+ int gss_trust_dns; -+ char *gss_host; -+ char *gss_client; -+#endif - char *failed_choice; - int (*verify_host_key)(struct sshkey *, struct ssh *); - struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -191,8 +211,10 @@ int kex_hash_from_name(const char *); - int kex_nid_from_name(const char *); - int kex_names_valid(const char *); - char *kex_alg_list(char); -+char *kex_gss_alg_list(char); - char *kex_names_cat(const char *, const char *); - int kex_has_any_alg(const char *, const char *); -+int kex_gss_names_valid(const char *); - int kex_assemble_names(char **, const char *, const char *); - void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], - const char *, const char *, const char *, const char *, const char *); -@@ -226,6 +248,12 @@ int kexgex_client(struct ssh *); - int kexgex_server(struct ssh *); - int kex_gen_client(struct ssh *); - int kex_gen_server(struct ssh *); -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+int kexgssgex_client(struct ssh *); -+int kexgssgex_server(struct ssh *); -+int kexgss_client(struct ssh *); -+int kexgss_server(struct ssh *); -+#endif - - int kex_dh_keypair(struct kex *); - int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -264,6 +292,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, - const BIGNUM *, const u_char *, size_t, - u_char *, size_t *); - -+int kex_gen_hash(int hash_alg, const struct sshbuf *client_version, -+ const struct sshbuf *server_version, const struct sshbuf *client_kexinit, -+ const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob, -+ const struct sshbuf *client_pub, const struct sshbuf *server_pub, -+ const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen); -+ - void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) - __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) - __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); -diff --git a/kexdh.c b/kexdh.c -index c1084f21..0faab21b 100644 ---- a/kexdh.c -+++ b/kexdh.c +diff --color -ruNp a/kexdh.c b/kexdh.c +--- a/kexdh.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/kexdh.c 2024-09-16 11:46:34.693939862 +0200 @@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { @@ -1516,10 +1226,9 @@ index c1084f21..0faab21b 100644 kex->dh = dh_new_group16(); break; case KEX_DH_GRP18_SHA512: -diff --git a/kexgen.c b/kexgen.c -index 40d688d6..15df591c 100644 ---- a/kexgen.c -+++ b/kexgen.c +diff --color -ruNp a/kexgen.c b/kexgen.c +--- a/kexgen.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/kexgen.c 2024-09-16 11:46:34.693939862 +0200 @@ -44,7 +44,7 @@ static int input_kex_gen_init(int, u_int32_t, struct ssh *); static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); @@ -1529,11 +1238,9 @@ index 40d688d6..15df591c 100644 kex_gen_hash( int hash_alg, const struct sshbuf *client_version, -diff --git a/kexgssc.c b/kexgssc.c -new file mode 100644 -index 00000000..96f7b6f5 ---- /dev/null -+++ b/kexgssc.c +diff --color -ruNp a/kexgssc.c b/kexgssc.c +--- a/kexgssc.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/kexgssc.c 2024-10-14 15:18:02.491798105 +0200 @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2241,11 +1948,9 @@ index 00000000..96f7b6f5 +} + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --git a/kexgsss.c b/kexgsss.c -new file mode 100644 -index 00000000..8362081e ---- /dev/null -+++ b/kexgsss.c +diff --color -ruNp a/kexgsss.c b/kexgsss.c +--- a/kexgsss.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/kexgsss.c 2024-10-14 15:18:02.491798105 +0200 @@ -0,0 +1,601 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2848,11 +2553,223 @@ index 00000000..8362081e +} + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --git a/monitor.c b/monitor.c -index 02b3eaaa..2ef16cc8 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -147,6 +147,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); +diff --color -ruNp a/kex.h b/kex.h +--- a/kex.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/kex.h 2024-09-16 11:46:34.710940224 +0200 +@@ -29,6 +29,10 @@ + #include "mac.h" + #include "crypto_api.h" + ++#ifdef GSSAPI ++# include "ssh-gss.h" /* Gssctxt */ ++#endif ++ + #ifdef WITH_OPENSSL + # include + # include +@@ -102,6 +106,15 @@ enum kex_exchange { + KEX_C25519_SHA256, + KEX_KEM_SNTRUP761X25519_SHA512, + KEX_KEM_MLKEM768X25519_SHA256, ++#ifdef GSSAPI ++ KEX_GSS_GRP1_SHA1, ++ KEX_GSS_GRP14_SHA1, ++ KEX_GSS_GRP14_SHA256, ++ KEX_GSS_GRP16_SHA512, ++ KEX_GSS_GEX_SHA1, ++ KEX_GSS_NISTP256_SHA256, ++ KEX_GSS_C25519_SHA256, ++#endif + KEX_MAX + }; + +@@ -164,6 +177,13 @@ struct kex { + u_int flags; + int hash_alg; + int ec_nid; ++#ifdef GSSAPI ++ Gssctxt *gss; ++ int gss_deleg_creds; ++ int gss_trust_dns; ++ char *gss_host; ++ char *gss_client; ++#endif + char *failed_choice; + int (*verify_host_key)(struct sshkey *, struct ssh *); + struct sshkey *(*load_host_public_key)(int, int, struct ssh *); +@@ -189,8 +209,10 @@ int kex_hash_from_name(const char *); + int kex_nid_from_name(const char *); + int kex_names_valid(const char *); + char *kex_alg_list(char); ++char *kex_gss_alg_list(char); + char *kex_names_cat(const char *, const char *); + int kex_has_any_alg(const char *, const char *); ++int kex_gss_names_valid(const char *); + int kex_assemble_names(char **, const char *, const char *); + void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], + const char *, const char *, const char *, const char *, const char *); +@@ -224,6 +246,12 @@ int kexgex_client(struct ssh *); + int kexgex_server(struct ssh *); + int kex_gen_client(struct ssh *); + int kex_gen_server(struct ssh *); ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++int kexgssgex_client(struct ssh *); ++int kexgssgex_server(struct ssh *); ++int kexgss_client(struct ssh *); ++int kexgss_server(struct ssh *); ++#endif + + int kex_dh_keypair(struct kex *); + int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, +@@ -256,6 +284,12 @@ int kexgex_hash(int, const struct sshbu + const BIGNUM *, const u_char *, size_t, + u_char *, size_t *); + ++int kex_gen_hash(int hash_alg, const struct sshbuf *client_version, ++ const struct sshbuf *server_version, const struct sshbuf *client_kexinit, ++ const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob, ++ const struct sshbuf *client_pub, const struct sshbuf *server_pub, ++ const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen); ++ + void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) + __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) + __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); +diff --color -ruNp a/kex-names.c b/kex-names.c +--- a/kex-names.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/kex-names.c 2024-09-16 11:46:34.694939883 +0200 +@@ -45,6 +45,10 @@ + #include "ssherr.h" + #include "xmalloc.h" + ++#ifdef GSSAPI ++#include "ssh-gss.h" ++#endif ++ + struct kexalg { + char *name; + u_int type; +@@ -83,15 +87,28 @@ static const struct kexalg kexalgs[] = { + #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ + { NULL, 0, -1, -1}, + }; ++static const struct kexalg gss_kexalgs[] = { ++#ifdef GSSAPI ++ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, ++ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, ++ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, ++#endif ++ { NULL, 0, -1, -1}, ++}; + +-char * +-kex_alg_list(char sep) ++static char * ++kex_alg_list_internal(char sep, const struct kexalg *algs) + { + char *ret = NULL, *tmp; + size_t nlen, rlen = 0; + const struct kexalg *k; + +- for (k = kexalgs; k->name != NULL; k++) { ++ for (k = algs; k->name != NULL; k++) { + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(k->name); +@@ -106,6 +123,18 @@ kex_alg_list(char sep) + return ret; + } + ++char * ++kex_alg_list(char sep) ++{ ++ return kex_alg_list_internal(sep, kexalgs); ++} ++ ++char * ++kex_gss_alg_list(char sep) ++{ ++ return kex_alg_list_internal(sep, gss_kexalgs); ++} ++ + static const struct kexalg * + kex_alg_by_name(const char *name) + { +@@ -115,6 +144,10 @@ kex_alg_by_name(const char *name) + if (strcmp(k->name, name) == 0) + return k; + } ++ for (k = gss_kexalgs; k->name != NULL; k++) { ++ if (strncmp(k->name, name, strlen(k->name)) == 0) ++ return k; ++ } + return NULL; + } + +@@ -328,3 +361,26 @@ kex_assemble_names(char **listp, const c + free(ret); + return r; + } ++ ++/* Validate GSS KEX method name list */ ++int ++kex_gss_names_valid(const char *names) ++{ ++ char *s, *cp, *p; ++ ++ if (names == NULL || *names == '\0') ++ return 0; ++ s = cp = xstrdup(names); ++ for ((p = strsep(&cp, ",")); p && *p != '\0'; ++ (p = strsep(&cp, ","))) { ++ if (strncmp(p, "gss-", 4) != 0 ++ || kex_alg_by_name(p) == NULL) { ++ error("Unsupported KEX algorithm \"%.100s\"", p); ++ free(s); ++ return 0; ++ } ++ } ++ debug3("gss kex names ok: [%s]", names); ++ free(s); ++ return 1; ++} +diff --color -ruNp a/Makefile.in b/Makefile.in +--- a/Makefile.in 2024-09-16 11:45:56.868133454 +0200 ++++ b/Makefile.in 2024-09-16 11:46:34.695939904 +0200 +@@ -114,6 +114,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexgexc.o kexgexs.o \ + kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ ++ kexgssc.o \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ + sshbuf-io.o + +@@ -135,7 +136,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rh + auth2-chall.o groupaccess.o \ + auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ +- monitor.o monitor_wrap.o auth-krb5.o \ ++ monitor.o monitor_wrap.o auth-krb5.o kexgsss.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ + sftp-server.o sftp-common.o \ +@@ -529,7 +530,7 @@ regress-prep: + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile + + REGRESSLIBS=libssh.a $(LIBCOMPAT) +-TESTLIBS=$(LIBS) $(CHANNELLIBS) ++TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) + + regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ +diff --color -ruNp a/monitor.c b/monitor.c +--- a/monitor.c 2024-09-16 11:45:56.861133305 +0200 ++++ b/monitor.c 2024-09-16 11:46:34.696939926 +0200 +@@ -143,6 +143,8 @@ int mm_answer_gss_setup_ctx(struct ssh * int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -2861,7 +2778,7 @@ index 02b3eaaa..2ef16cc8 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -224,11 +226,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -219,11 +221,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}, @@ -2877,11 +2794,11 @@ index 02b3eaaa..2ef16cc8 100644 + {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, + {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, +#endif - {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, -@@ -299,6 +308,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) - monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); + #endif +@@ -292,6 +301,10 @@ monitor_child_preauth(struct ssh *ssh, s + /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); +#ifdef GSSAPI @@ -2891,7 +2808,7 @@ index 02b3eaaa..2ef16cc8 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -351,8 +364,15 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -344,8 +357,15 @@ monitor_child_preauth(struct ssh *ssh, s if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { auth_log(ssh, authenticated, partial, auth_method, auth_submethod); @@ -2908,7 +2825,7 @@ index 02b3eaaa..2ef16cc8 100644 if (authenticated || partial) { auth2_update_session_info(authctxt, auth_method, auth_submethod); -@@ -421,6 +441,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -413,6 +433,10 @@ monitor_child_postauth(struct ssh *ssh, monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2919,7 +2836,7 @@ index 02b3eaaa..2ef16cc8 100644 if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1890,6 +1914,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1793,6 +1817,17 @@ monitor_apply_keystate(struct ssh *ssh, # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2937,7 +2854,7 @@ index 02b3eaaa..2ef16cc8 100644 #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -@@ -1981,8 +2016,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1885,8 +1920,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, u_char *p; int r; @@ -2948,7 +2865,7 @@ index 02b3eaaa..2ef16cc8 100644 if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal_fr(r, "parse"); -@@ -2014,8 +2049,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1918,8 +1953,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2959,7 +2876,7 @@ index 02b3eaaa..2ef16cc8 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal_fr(r, "ssh_gssapi_get_buffer_desc"); -@@ -2035,6 +2070,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1939,6 +1974,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2967,7 +2884,7 @@ index 02b3eaaa..2ef16cc8 100644 } return (0); } -@@ -2046,8 +2082,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1950,8 +1986,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, OM_uint32 ret; int r; @@ -2978,7 +2895,7 @@ index 02b3eaaa..2ef16cc8 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -2073,13 +2109,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1977,13 +2013,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -2990,17 +2907,17 @@ index 02b3eaaa..2ef16cc8 100644 - fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) + fatal_f("GSSAPI not enabled"); -+ -+ if ((r = sshbuf_get_u32(m, &kex)) != 0) -+ fatal_fr(r, "buffer error"); - authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); ++ if ((r = sshbuf_get_u32(m, &kex)) != 0) ++ fatal_fr(r, "buffer error"); ++ + authenticated = authctxt->valid && + ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -2088,7 +2128,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1992,7 +2032,11 @@ mm_answer_gss_userok(struct ssh *ssh, in debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -3013,7 +2930,7 @@ index 02b3eaaa..2ef16cc8 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -2096,5 +2140,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2000,5 +2044,84 @@ mm_answer_gss_userok(struct ssh *ssh, in /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -3098,11 +3015,10 @@ index 02b3eaaa..2ef16cc8 100644 + #endif /* GSSAPI */ -diff --git a/monitor.h b/monitor.h -index 9dcd9c29..dbc7e003 100644 ---- a/monitor.h -+++ b/monitor.h -@@ -68,6 +68,8 @@ enum monitor_reqtype { +diff --color -ruNp a/monitor.h b/monitor.h +--- a/monitor.h 2024-09-16 11:45:56.861133305 +0200 ++++ b/monitor.h 2024-09-16 11:46:34.696939926 +0200 +@@ -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, @@ -3111,11 +3027,10 @@ index 9dcd9c29..dbc7e003 100644 }; struct ssh; -diff --git a/monitor_wrap.c b/monitor_wrap.c -index ef3ab1b1..b6e3b3f3 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -1131,13 +1131,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +diff --color -ruNp a/monitor_wrap.c b/monitor_wrap.c +--- a/monitor_wrap.c 2024-09-16 11:45:56.862133326 +0200 ++++ b/monitor_wrap.c 2024-09-16 11:46:34.697939947 +0200 +@@ -1075,13 +1075,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -3132,7 +3047,7 @@ index ef3ab1b1..b6e3b3f3 100644 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, -@@ -1150,6 +1152,59 @@ mm_ssh_gssapi_userok(char *user) +@@ -1094,6 +1096,59 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -3192,11 +3107,10 @@ index ef3ab1b1..b6e3b3f3 100644 #endif /* GSSAPI */ /* -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 38a280c8..672dce52 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -67,8 +67,10 @@ void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); +diff --color -ruNp a/monitor_wrap.h b/monitor_wrap.h +--- a/monitor_wrap.h 2024-09-16 11:45:56.862133326 +0200 ++++ b/monitor_wrap.h 2024-09-16 11:46:34.697939947 +0200 +@@ -67,8 +67,10 @@ void mm_decode_activate_server_options(s 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 *); @@ -3208,19 +3122,18 @@ index 38a280c8..672dce52 100644 #endif #ifdef USE_PAM -diff --git a/readconf.c b/readconf.c -index 7cbe7d2c..6c04ed43 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -71,6 +71,7 @@ +diff --color -ruNp a/readconf.c b/readconf.c +--- a/readconf.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/readconf.c 2024-09-16 11:46:34.699939990 +0200 +@@ -70,6 +70,7 @@ + #include "uidswap.h" #include "myproposal.h" #include "digest.h" - #include "version.h" +#include "ssh-gss.h" /* Format of the configuration file: -@@ -165,6 +166,8 @@ typedef enum { +@@ -164,6 +165,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -3229,7 +3142,7 @@ index 7cbe7d2c..6c04ed43 100644 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -212,10 +215,22 @@ static struct { +@@ -210,10 +213,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -3252,7 +3165,7 @@ index 7cbe7d2c..6c04ed43 100644 #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1320,10 +1335,42 @@ parse_time: +@@ -1227,10 +1242,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -3295,7 +3208,7 @@ index 7cbe7d2c..6c04ed43 100644 case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -2662,7 +2709,13 @@ initialize_options(Options * options) +@@ -2542,7 +2589,13 @@ initialize_options(Options * options) options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; options->gss_authentication = -1; @@ -3309,7 +3222,7 @@ index 7cbe7d2c..6c04ed43 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2826,8 +2879,18 @@ fill_default_options(Options * options) +@@ -2705,8 +2758,18 @@ fill_default_options(Options * options) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3328,7 +3241,7 @@ index 7cbe7d2c..6c04ed43 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -3656,7 +3719,14 @@ dump_client_config(Options *o, const char *host) +@@ -3533,7 +3596,14 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -3343,11 +3256,10 @@ index 7cbe7d2c..6c04ed43 100644 #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff --git a/readconf.h b/readconf.h -index cd49139b..368523dd 100644 ---- a/readconf.h -+++ b/readconf.h -@@ -39,7 +39,13 @@ typedef struct { +diff --color -ruNp a/readconf.h b/readconf.h +--- a/readconf.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/readconf.h 2024-09-16 11:46:34.699939990 +0200 +@@ -40,7 +40,13 @@ typedef struct { int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ int gss_authentication; /* Try GSS authentication */ @@ -3361,19 +3273,18 @@ index cd49139b..368523dd 100644 int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff --git a/servconf.c b/servconf.c -index f7bc9237..d4f7fd66 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -69,6 +69,7 @@ +diff --color -ruNp a/servconf.c b/servconf.c +--- a/servconf.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/servconf.c 2024-09-16 11:46:34.700940011 +0200 +@@ -68,6 +68,7 @@ + #include "auth.h" #include "myproposal.h" #include "digest.h" - #include "version.h" +#include "ssh-gss.h" #if !defined(SSHD_PAM_SERVICE) # define SSHD_PAM_SERVICE "sshd" -@@ -138,8 +139,11 @@ initialize_server_options(ServerOptions *options) +@@ -137,8 +138,11 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3385,7 +3296,7 @@ index f7bc9237..d4f7fd66 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -380,10 +384,18 @@ fill_default_server_options(ServerOptions *options) +@@ -376,10 +380,18 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3404,7 +3315,7 @@ index f7bc9237..d4f7fd66 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -568,6 +580,7 @@ typedef enum { +@@ -558,6 +570,7 @@ typedef enum { sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -3412,7 +3323,7 @@ index f7bc9237..d4f7fd66 100644 sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -653,12 +666,22 @@ static struct { +@@ -643,12 +656,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3435,7 +3346,7 @@ index f7bc9237..d4f7fd66 100644 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ -@@ -1649,6 +1672,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1585,6 +1608,10 @@ process_server_config_line_depth(ServerO intptr = &options->gss_authentication; goto parse_flag; @@ -3446,7 +3357,7 @@ index f7bc9237..d4f7fd66 100644 case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1657,6 +1684,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1593,6 +1620,22 @@ process_server_config_line_depth(ServerO intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3469,7 +3380,7 @@ index f7bc9237..d4f7fd66 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3254,6 +3297,10 @@ dump_config(ServerOptions *o) +@@ -3178,6 +3221,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -3480,11 +3391,10 @@ index f7bc9237..d4f7fd66 100644 #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff --git a/servconf.h b/servconf.h -index 9beb90fa..c3f50140 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -150,8 +150,11 @@ typedef struct { +diff --color -ruNp a/servconf.h b/servconf.h +--- a/servconf.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/servconf.h 2024-09-16 11:46:34.700940011 +0200 +@@ -149,8 +149,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 */ @@ -3496,11 +3406,10 @@ index 9beb90fa..c3f50140 100644 int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff --git a/session.c b/session.c -index e4657cef..cbfbcee8 100644 ---- a/session.c -+++ b/session.c -@@ -2670,13 +2670,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +diff --color -ruNp a/session.c b/session.c +--- a/session.c 2024-09-16 11:45:56.866133411 +0200 ++++ b/session.c 2024-09-16 11:46:34.701940032 +0200 +@@ -2674,13 +2674,19 @@ do_cleanup(struct ssh *ssh, Authctxt *au #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3522,10 +3431,542 @@ index e4657cef..cbfbcee8 100644 #endif /* remove agent socket */ -diff --git a/ssh-gss.h b/ssh-gss.h -index 7b14e74a..8ec45192 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h +diff --color -ruNp a/ssh.1 b/ssh.1 +--- a/ssh.1 2024-09-16 11:45:56.875133603 +0200 ++++ b/ssh.1 2024-09-16 11:46:34.701940032 +0200 +@@ -536,7 +536,13 @@ For full details of the options listed b + .It GatewayPorts + .It GlobalKnownHostsFile + .It GSSAPIAuthentication ++.It GSSAPIKeyExchange ++.It GSSAPIClientIdentity + .It GSSAPIDelegateCredentials ++.It GSSAPIKexAlgorithms ++.It GSSAPIRenewalForcesRekey ++.It GSSAPIServerIdentity ++.It GSSAPITrustDns + .It HashKnownHosts + .It Host + .It HostbasedAcceptedAlgorithms +@@ -624,6 +630,8 @@ flag), + (supported message integrity codes), + .Ar kex + (key exchange algorithms), ++.Ar kex-gss ++(GSSAPI key exchange algorithms), + .Ar key + (key types), + .Ar key-ca-sign +diff --color -ruNp a/ssh.c b/ssh.c +--- a/ssh.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/ssh.c 2024-09-16 11:46:34.702940054 +0200 +@@ -827,6 +827,8 @@ main(int ac, char **av) + else if (strcmp(optarg, "kex") == 0 || + strcasecmp(optarg, "KexAlgorithms") == 0) + cp = kex_alg_list('\n'); ++ else if (strcmp(optarg, "kex-gss") == 0) ++ cp = kex_gss_alg_list('\n'); + else if (strcmp(optarg, "key") == 0) + cp = sshkey_alg_list(0, 0, 0, '\n'); + else if (strcmp(optarg, "key-cert") == 0) +@@ -857,8 +859,8 @@ main(int ac, char **av) + } else if (strcmp(optarg, "help") == 0) { + cp = xstrdup( + "cipher\ncipher-auth\ncompression\nkex\n" +- "key\nkey-cert\nkey-plain\nkey-sig\nmac\n" +- "protocol-version\nsig"); ++ "kex-gss\nkey\nkey-cert\nkey-plain\n" ++ "key-sig\nmac\nprotocol-version\nsig"); + } + if (cp == NULL) + fatal("Unsupported query \"%s\"", optarg); +diff --color -ruNp a/ssh_config b/ssh_config +--- a/ssh_config 2024-09-16 11:45:56.884133795 +0200 ++++ b/ssh_config 2024-09-16 11:46:34.702940054 +0200 +@@ -24,6 +24,8 @@ + # HostbasedAuthentication no + # GSSAPIAuthentication no + # GSSAPIDelegateCredentials no ++# GSSAPIKeyExchange no ++# GSSAPITrustDNS no + # BatchMode no + # CheckHostIP no + # AddressFamily any +diff --color -ruNp a/ssh_config.5 b/ssh_config.5 +--- a/ssh_config.5 2024-07-01 06:36:28.000000000 +0200 ++++ b/ssh_config.5 2024-09-16 11:46:34.703940075 +0200 +@@ -938,10 +938,68 @@ The default is + Specifies whether user authentication based on GSSAPI is allowed. + The default is + .Cm no . ++.It Cm GSSAPIClientIdentity ++If set, specifies the GSSAPI client identity that ssh should use when ++connecting to the server. The default is unset, which means that the default ++identity will be used. + .It Cm GSSAPIDelegateCredentials + Forward (delegate) credentials to the server. + The default is + .Cm no . ++.It Cm GSSAPIKeyExchange ++Specifies whether key exchange based on GSSAPI may be used. When using ++GSSAPI key exchange the server need not have a host key. ++The default is ++.Dq no . ++.It Cm GSSAPIRenewalForcesRekey ++If set to ++.Dq yes ++then renewal of the client's GSSAPI credentials will force the rekeying of the ++ssh connection. With a compatible server, this will delegate the renewed ++credentials to a session on the server. ++.Pp ++Checks are made to ensure that credentials are only propagated when the new ++credentials match the old ones on the originating client and where the ++receiving server still has the old set in its cache. ++.Pp ++The default is ++.Dq no . ++.Pp ++For this to work ++.Cm GSSAPIKeyExchange ++needs to be enabled in the server and also used by the client. ++.It Cm GSSAPIServerIdentity ++If set, specifies the GSSAPI server identity that ssh should expect when ++connecting to the server. The default is unset, which means that the ++expected GSSAPI server identity will be determined from the target ++hostname. ++.It Cm GSSAPITrustDns ++Set to ++.Dq yes ++to indicate that the DNS is trusted to securely canonicalize ++the name of the host being connected to. If ++.Dq no , ++the hostname entered on the ++command line will be passed untouched to the GSSAPI library. ++The default is ++.Dq no . ++.It Cm GSSAPIKexAlgorithms ++The list of key exchange algorithms that are offered for GSSAPI ++key exchange. Possible values are ++.Bd -literal -offset 3n ++gss-gex-sha1-, ++gss-group1-sha1-, ++gss-group14-sha1-, ++gss-group14-sha256-, ++gss-group16-sha512-, ++gss-nistp256-sha256-, ++gss-curve25519-sha256- ++.Ed ++.Pp ++The default is ++.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, ++gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . ++This option only applies to connections using GSSAPI. + .It Cm HashKnownHosts + Indicates that + .Xr ssh 1 +diff --color -ruNp a/sshconnect2.c b/sshconnect2.c +--- a/sshconnect2.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/sshconnect2.c 2024-09-16 11:46:34.703940075 +0200 +@@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, st + char *all_key, *hkalgs = NULL; + int r, use_known_hosts_order = 0; + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ char *orig = NULL, *gss = NULL; ++ char *gss_host = NULL; ++#endif ++ + xxx_host = host; + xxx_hostaddr = hostaddr; + xxx_conn_info = cinfo; +@@ -255,6 +260,42 @@ ssh_kex2(struct ssh *ssh, char *host, st + compression_alg_list(options.compression), + hkalgs ? hkalgs : options.hostkeyalgorithms); + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ if (options.gss_keyex) { ++ /* Add the GSSAPI mechanisms currently supported on this ++ * client to the key exchange algorithm proposal */ ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ ++ if (options.gss_server_identity) { ++ gss_host = xstrdup(options.gss_server_identity); ++ } else if (options.gss_trust_dns) { ++ gss_host = remote_hostname(ssh); ++ /* Fall back to specified host if we are using proxy command ++ * and can not use DNS on that socket */ ++ if (strcmp(gss_host, "UNKNOWN") == 0) { ++ free(gss_host); ++ gss_host = xstrdup(host); ++ } ++ } else { ++ gss_host = xstrdup(host); ++ } ++ ++ gss = ssh_gssapi_client_mechanisms(gss_host, ++ options.gss_client_identity, options.gss_kex_algorithms); ++ if (gss) { ++ debug("Offering GSSAPI proposal: %s", gss); ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ ++ /* If we've got GSSAPI algorithms, then we also support the ++ * 'null' hostkey, as a last resort */ ++ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], ++ "%s,null", orig); ++ } ++ } ++#endif ++ + free(hkalgs); + + /* start key exchange */ +@@ -271,15 +312,45 @@ ssh_kex2(struct ssh *ssh, char *host, st + # ifdef OPENSSL_HAS_ECC + ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; + # endif +-#endif ++# ifdef GSSAPI ++ if (options.gss_keyex) { ++ ssh->kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_client; ++ ssh->kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_client; ++ ssh->kex->kex[KEX_GSS_C25519_SHA256] = kexgss_client; ++ } ++# 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_MLKEM768X25519_SHA256] = kex_gen_client; + ssh->kex->verify_host_key=&verify_host_key_callback; + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ if (options.gss_keyex) { ++ ssh->kex->gss_deleg_creds = options.gss_deleg_creds; ++ ssh->kex->gss_trust_dns = options.gss_trust_dns; ++ ssh->kex->gss_client = options.gss_client_identity; ++ ssh->kex->gss_host = gss_host; ++ } ++#endif ++ + ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); + kex_proposal_free_entries(myproposal); + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ /* repair myproposal after it was crumpled by the */ ++ /* ext-info removal above */ ++ if (gss) { ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ "%s,%s", gss, orig); ++ free(gss); ++ } ++#endif + #ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || +@@ -368,6 +439,7 @@ static int input_gssapi_response(int typ + 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 *); ++static int userauth_gsskeyex(struct ssh *); + #endif + + void userauth(struct ssh *, char *); +@@ -384,6 +456,11 @@ static char *authmethods_get(void); + + Authmethod authmethods[] = { + #ifdef GSSAPI ++ {"gssapi-keyex", ++ userauth_gsskeyex, ++ NULL, ++ &options.gss_keyex, ++ NULL}, + {"gssapi-with-mic", + userauth_gssapi, + userauth_gssapi_cleanup, +@@ -755,12 +832,32 @@ userauth_gssapi(struct ssh *ssh) + OM_uint32 min; + int r, ok = 0; + gss_OID mech = NULL; ++ char *gss_host = NULL; ++ ++ if (options.gss_server_identity) { ++ gss_host = xstrdup(options.gss_server_identity); ++ } else if (options.gss_trust_dns) { ++ gss_host = remote_hostname(ssh); ++ /* Fall back to specified host if we are using proxy command ++ * and can not use DNS on that socket */ ++ if (strcmp(gss_host, "UNKNOWN") == 0) { ++ free(gss_host); ++ gss_host = xstrdup(authctxt->host); ++ } ++ } else { ++ gss_host = xstrdup(authctxt->host); ++ } + + /* Try one GSSAPI method at a time, rather than sending them all at + * once. */ + + if (authctxt->gss_supported_mechs == NULL) +- gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); ++ if (GSS_ERROR(gss_indicate_mechs(&min, ++ &authctxt->gss_supported_mechs))) { ++ authctxt->gss_supported_mechs = NULL; ++ free(gss_host); ++ return 0; ++ } + + /* Check to see whether the mechanism is usable before we offer it */ + while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && +@@ -769,13 +866,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, +- mech, authctxt->host)) { ++ mech, gss_host, options.gss_client_identity)) { + ok = 1; /* Mechanism works */ + } else { + authctxt->mech_tried++; + } + } + ++ free(gss_host); ++ + if (!ok || mech == NULL) + return 0; + +@@ -1009,6 +1108,55 @@ input_gssapi_error(int type, u_int32_t p + free(lang); + return r; + } ++ ++int ++userauth_gsskeyex(struct ssh *ssh) ++{ ++ struct sshbuf *b = NULL; ++ Authctxt *authctxt = ssh->authctxt; ++ gss_buffer_desc gssbuf; ++ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; ++ OM_uint32 ms; ++ int r; ++ ++ static int attempt = 0; ++ if (attempt++ >= 1) ++ return (0); ++ ++ if (gss_kex_context == NULL) { ++ debug("No valid Key exchange context"); ++ return (0); ++ } ++ ++ if ((b = sshbuf_new()) == NULL) ++ fatal_f("sshbuf_new failed"); ++ ++ ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, ++ "gssapi-keyex", ssh->kex->session_id); ++ ++ if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) ++ fatal_f("sshbuf_mutable_ptr failed"); ++ gssbuf.length = sshbuf_len(b); ++ ++ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { ++ sshbuf_free(b); ++ return (0); ++ } ++ ++ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || ++ (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || ++ (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || ++ (r = sshpkt_send(ssh)) != 0) ++ fatal_fr(r, "parsing"); ++ ++ sshbuf_free(b); ++ gss_release_buffer(&ms, &mic); ++ ++ return (1); ++} ++ + #endif /* GSSAPI */ + + static int +diff --color -ruNp a/sshd.c b/sshd.c +--- a/sshd.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/sshd.c 2024-09-16 11:46:34.704940096 +0200 +@@ -1551,7 +1551,8 @@ main(int ac, char **av) + free(fp); + } + accumulate_host_timing_secret(cfg, NULL); +- if (!sensitive_data.have_ssh2_key) { ++ /* The GSSAPI key exchange can run without a host key */ ++ if (!sensitive_data.have_ssh2_key && !options.gss_keyex) { + logit("sshd: no hostkeys available -- exiting."); + exit(1); + } +diff --color -ruNp a/sshd_config b/sshd_config +--- a/sshd_config 2024-09-16 11:45:56.888133880 +0200 ++++ b/sshd_config 2024-09-16 11:46:34.704940096 +0200 +@@ -77,6 +77,8 @@ AuthorizedKeysFile .ssh/authorized_keys + # GSSAPI options + #GSSAPIAuthentication no + #GSSAPICleanupCredentials yes ++#GSSAPIStrictAcceptorCheck yes ++#GSSAPIKeyExchange no + + # Set this to 'yes' to enable PAM authentication, account processing, + # and session processing. If this is enabled, PAM authentication will +diff --color -ruNp a/sshd_config.5 b/sshd_config.5 +--- a/sshd_config.5 2024-09-16 11:45:56.885133816 +0200 ++++ b/sshd_config.5 2024-09-16 11:46:34.704940096 +0200 +@@ -739,6 +739,11 @@ Specifies whether to automatically destr + on logout. + The default is + .Cm yes . ++.It Cm GSSAPIKeyExchange ++Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange ++doesn't rely on ssh keys to verify host identity. ++The default is ++.Cm no . + .It Cm GSSAPIStrictAcceptorCheck + Determines whether to be strict about the identity of the GSSAPI acceptor + a client authenticates against. +@@ -753,6 +758,32 @@ machine's default store. + This facility is provided to assist with operation on multi homed machines. + The default is + .Cm yes . ++.It Cm GSSAPIStoreCredentialsOnRekey ++Controls whether the user's GSSAPI credentials should be updated following a ++successful connection rekeying. This option can be used to accepted renewed ++or updated credentials from a compatible client. The default is ++.Dq no . ++.Pp ++For this to work ++.Cm GSSAPIKeyExchange ++needs to be enabled in the server and also used by the client. ++.It Cm GSSAPIKexAlgorithms ++The list of key exchange algorithms that are accepted by GSSAPI ++key exchange. Possible values are ++.Bd -literal -offset 3n ++gss-gex-sha1-, ++gss-group1-sha1-, ++gss-group14-sha1-, ++gss-group14-sha256-, ++gss-group16-sha512-, ++gss-nistp256-sha256-, ++gss-curve25519-sha256- ++.Ed ++.Pp ++The default is ++.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, ++gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . ++This option only applies to connections using GSSAPI. + .It Cm HostbasedAcceptedAlgorithms + Specifies the signature algorithms that will be accepted for hostbased + authentication as a list of comma-separated patterns. +diff --color -ruNp a/sshd-session.c b/sshd-session.c +--- a/sshd-session.c 2024-09-16 11:45:56.888133880 +0200 ++++ b/sshd-session.c 2024-09-16 11:46:34.705940118 +0200 +@@ -660,8 +660,8 @@ notify_hostkeys(struct ssh *ssh) + } + debug3_f("sent %u hostkeys", nkeys); + if (nkeys == 0) +- fatal_f("no hostkeys"); +- if ((r = sshpkt_send(ssh)) != 0) ++ debug3_f("no hostkeys"); ++ else if ((r = sshpkt_send(ssh)) != 0) + sshpkt_fatal(ssh, r, "%s: send", __func__); + sshbuf_free(buf); + } +@@ -1180,8 +1180,9 @@ main(int ac, char **av) + break; + } + } +- if (!have_key) +- fatal("internal error: monitor received no hostkeys"); ++ /* The GSSAPI key exchange can run without a host key */ ++ if (!have_key && !options.gss_keyex) ++ fatal("internal error: monitor received no hostkeys and GSS KEX is not configured"); + + /* Ensure that umask disallows at least group and world write */ + new_umask = umask(0077) | 0022; +@@ -1462,6 +1463,48 @@ do_ssh2_kex(struct ssh *ssh) + + free(hkalgs); + ++#if defined(GSSAPI) && defined(WITH_OPENSSL) ++ { ++ char *orig; ++ char *gss = NULL; ++ char *newstr = NULL; ++ 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 (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) ++ orig = NULL; ++ ++ if (options.gss_keyex) ++ gss = ssh_gssapi_server_mechanisms(); ++ else ++ gss = NULL; ++ ++ if (gss && orig) ++ xasprintf(&newstr, "%s,%s", gss, orig); ++ else if (gss) ++ xasprintf(&newstr, "%s,%s", gss, "kex-strict-s-v00@openssh.com"); ++ else if (orig) ++ 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 (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) ++ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xstrdup("null"); ++ ++ if (newstr) ++ myproposal[PROPOSAL_KEX_ALGS] = newstr; ++ else ++ fatal("No supported key exchange algorithms"); ++ } ++#endif ++ + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) + fatal_r(r, "kex_setup"); +@@ -1479,7 +1522,18 @@ do_ssh2_kex(struct ssh *ssh) + #ifdef OPENSSL_HAS_ECC + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; + #endif +-#endif ++# ifdef GSSAPI ++ if (options.gss_keyex) { ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; ++ } ++# endif ++#endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; +diff --color -ruNp a/ssh-gss.h b/ssh-gss.h +--- a/ssh-gss.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/ssh-gss.h 2024-09-16 11:46:34.710940224 +0200 @@ -61,10 +61,36 @@ #define SSH_GSS_OIDTYPE 0x06 @@ -3606,7 +4047,7 @@ index 7b14e74a..8ec45192 100644 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -108,6 +149,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); +@@ -108,6 +149,7 @@ OM_uint32 ssh_gssapi_test_oid_supported( struct sshbuf; int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); @@ -3650,557 +4091,10 @@ index 7b14e74a..8ec45192 100644 #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff --git a/ssh.1 b/ssh.1 -index db92ac9a..6a9fbdc5 100644 ---- a/ssh.1 -+++ b/ssh.1 -@@ -539,9 +539,15 @@ For full details of the options listed below, and their possible values, see - .It ForwardX11Timeout - .It ForwardX11Trusted - .It GSSAPIAuthentication -+.It GSSAPIKeyExchange -+.It GSSAPIClientIdentity - .It GSSAPIDelegateCredentials - .It GatewayPorts - .It GlobalKnownHostsFile -+.It GSSAPIKexAlgorithms -+.It GSSAPIRenewalForcesRekey -+.It GSSAPIServerIdentity -+.It GSSAPITrustDns - .It HashKnownHosts - .It Host - .It HostKeyAlgorithms -@@ -636,6 +642,8 @@ flag), - (supported message integrity codes), - .Ar kex - (key exchange algorithms), -+.Ar kex-gss -+(GSSAPI key exchange algorithms), - .Ar key - (key types), - .Ar key-ca-sign -diff --git a/ssh.c b/ssh.c -index dc4886d0..c23d3b9e 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -835,6 +835,8 @@ main(int ac, char **av) - else if (strcmp(optarg, "kex") == 0 || - strcasecmp(optarg, "KexAlgorithms") == 0) - cp = kex_alg_list('\n'); -+ else if (strcmp(optarg, "kex-gss") == 0) -+ cp = kex_gss_alg_list('\n'); - else if (strcmp(optarg, "key") == 0) - cp = sshkey_alg_list(0, 0, 0, '\n'); - else if (strcmp(optarg, "key-cert") == 0) -@@ -865,8 +867,8 @@ main(int ac, char **av) - } else if (strcmp(optarg, "help") == 0) { - cp = xstrdup( - "cipher\ncipher-auth\ncompression\nkex\n" -- "key\nkey-cert\nkey-plain\nkey-sig\nmac\n" -- "protocol-version\nsig"); -+ "kex-gss\nkey\nkey-cert\nkey-plain\n" -+ "key-sig\nmac\nprotocol-version\nsig"); - } - if (cp == NULL) - fatal("Unsupported query \"%s\"", optarg); -diff --git a/ssh_config b/ssh_config -index 18169187..209248d6 100644 ---- a/ssh_config -+++ b/ssh_config -@@ -24,6 +24,8 @@ - # HostbasedAuthentication no - # GSSAPIAuthentication no - # GSSAPIDelegateCredentials no -+# GSSAPIKeyExchange no -+# GSSAPITrustDNS no - # BatchMode no - # CheckHostIP no - # AddressFamily any -diff --git a/ssh_config.5 b/ssh_config.5 -index 894d7383..3a8e246c 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -976,10 +976,68 @@ The default is - Specifies whether user authentication based on GSSAPI is allowed. - The default is - .Cm no . -+.It Cm GSSAPIClientIdentity -+If set, specifies the GSSAPI client identity that ssh should use when -+connecting to the server. The default is unset, which means that the default -+identity will be used. - .It Cm GSSAPIDelegateCredentials - Forward (delegate) credentials to the server. - The default is - .Cm no . -+.It Cm GSSAPIKeyExchange -+Specifies whether key exchange based on GSSAPI may be used. When using -+GSSAPI key exchange the server need not have a host key. -+The default is -+.Dq no . -+.It Cm GSSAPIRenewalForcesRekey -+If set to -+.Dq yes -+then renewal of the client's GSSAPI credentials will force the rekeying of the -+ssh connection. With a compatible server, this will delegate the renewed -+credentials to a session on the server. -+.Pp -+Checks are made to ensure that credentials are only propagated when the new -+credentials match the old ones on the originating client and where the -+receiving server still has the old set in its cache. -+.Pp -+The default is -+.Dq no . -+.Pp -+For this to work -+.Cm GSSAPIKeyExchange -+needs to be enabled in the server and also used by the client. -+.It Cm GSSAPIServerIdentity -+If set, specifies the GSSAPI server identity that ssh should expect when -+connecting to the server. The default is unset, which means that the -+expected GSSAPI server identity will be determined from the target -+hostname. -+.It Cm GSSAPITrustDns -+Set to -+.Dq yes -+to indicate that the DNS is trusted to securely canonicalize -+the name of the host being connected to. If -+.Dq no , -+the hostname entered on the -+command line will be passed untouched to the GSSAPI library. -+The default is -+.Dq no . -+.It Cm GSSAPIKexAlgorithms -+The list of key exchange algorithms that are offered for GSSAPI -+key exchange. Possible values are -+.Bd -literal -offset 3n -+gss-gex-sha1-, -+gss-group1-sha1-, -+gss-group14-sha1-, -+gss-group14-sha256-, -+gss-group16-sha512-, -+gss-nistp256-sha256-, -+gss-curve25519-sha256- -+.Ed -+.Pp -+The default is -+.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, -+gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . -+This option only applies to connections using GSSAPI. - .It Cm HashKnownHosts - Indicates that - .Xr ssh 1 -diff --git a/sshconnect2.c b/sshconnect2.c -index 1ee6000a..0af15bcc 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - char *all_key, *hkalgs = NULL; - int r, use_known_hosts_order = 0; - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ char *orig = NULL, *gss = NULL; -+ char *gss_host = NULL; -+#endif -+ - xxx_host = host; - xxx_hostaddr = hostaddr; - xxx_conn_info = cinfo; -@@ -255,6 +260,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - compression_alg_list(options.compression), - hkalgs ? hkalgs : options.hostkeyalgorithms); - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ if (options.gss_keyex) { -+ /* Add the GSSAPI mechanisms currently supported on this -+ * client to the key exchange algorithm proposal */ -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ -+ if (options.gss_server_identity) { -+ gss_host = xstrdup(options.gss_server_identity); -+ } else if (options.gss_trust_dns) { -+ gss_host = remote_hostname(ssh); -+ /* Fall back to specified host if we are using proxy command -+ * and can not use DNS on that socket */ -+ if (strcmp(gss_host, "UNKNOWN") == 0) { -+ free(gss_host); -+ gss_host = xstrdup(host); -+ } -+ } else { -+ gss_host = xstrdup(host); -+ } -+ -+ gss = ssh_gssapi_client_mechanisms(gss_host, -+ options.gss_client_identity, options.gss_kex_algorithms); -+ if (gss) { -+ debug("Offering GSSAPI proposal: %s", gss); -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -+ "%s,%s", gss, orig); -+ -+ /* If we've got GSSAPI algorithms, then we also support the -+ * 'null' hostkey, as a last resort */ -+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], -+ "%s,null", orig); -+ } -+ } -+#endif -+ - free(hkalgs); - - /* start key exchange */ -@@ -271,15 +312,45 @@ 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 --#endif -+# ifdef GSSAPI -+ if (options.gss_keyex) { -+ ssh->kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_client; -+ ssh->kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_client; -+ ssh->kex->kex[KEX_GSS_C25519_SHA256] = kexgss_client; -+ } -+# 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_MLKEM768X25519_SHA256] = kex_gen_client; - ssh->kex->verify_host_key=&verify_host_key_callback; - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ if (options.gss_keyex) { -+ ssh->kex->gss_deleg_creds = options.gss_deleg_creds; -+ ssh->kex->gss_trust_dns = options.gss_trust_dns; -+ ssh->kex->gss_client = options.gss_client_identity; -+ ssh->kex->gss_host = gss_host; -+ } -+#endif -+ - ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); - kex_proposal_free_entries(myproposal); - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ /* repair myproposal after it was crumpled by the */ -+ /* ext-info removal above */ -+ if (gss) { -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -+ "%s,%s", gss, orig); -+ free(gss); -+ } -+#endif - #ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || -@@ -369,6 +440,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 *); -+static int userauth_gsskeyex(struct ssh *); - #endif - - void userauth(struct ssh *, char *); -@@ -385,6 +457,11 @@ static char *authmethods_get(void); - - Authmethod authmethods[] = { - #ifdef GSSAPI -+ {"gssapi-keyex", -+ userauth_gsskeyex, -+ NULL, -+ &options.gss_keyex, -+ NULL}, - {"gssapi-with-mic", - userauth_gssapi, - userauth_gssapi_cleanup, -@@ -759,12 +836,32 @@ userauth_gssapi(struct ssh *ssh) - OM_uint32 min; - int r, ok = 0; - gss_OID mech = NULL; -+ char *gss_host = NULL; -+ -+ if (options.gss_server_identity) { -+ gss_host = xstrdup(options.gss_server_identity); -+ } else if (options.gss_trust_dns) { -+ gss_host = remote_hostname(ssh); -+ /* Fall back to specified host if we are using proxy command -+ * and can not use DNS on that socket */ -+ if (strcmp(gss_host, "UNKNOWN") == 0) { -+ free(gss_host); -+ gss_host = xstrdup(authctxt->host); -+ } -+ } else { -+ gss_host = xstrdup(authctxt->host); -+ } - - /* Try one GSSAPI method at a time, rather than sending them all at - * once. */ - - if (authctxt->gss_supported_mechs == NULL) -- gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); -+ if (GSS_ERROR(gss_indicate_mechs(&min, -+ &authctxt->gss_supported_mechs))) { -+ authctxt->gss_supported_mechs = NULL; -+ free(gss_host); -+ return 0; -+ } - - /* Check to see whether the mechanism is usable before we offer it */ - while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && -@@ -773,13 +870,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, -- mech, authctxt->host)) { -+ mech, gss_host, options.gss_client_identity)) { - ok = 1; /* Mechanism works */ - } else { - authctxt->mech_tried++; - } - } - -+ free(gss_host); -+ - if (!ok || mech == NULL) - return 0; - -@@ -1013,6 +1112,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) - free(lang); - return r; - } -+ -+int -+userauth_gsskeyex(struct ssh *ssh) -+{ -+ struct sshbuf *b = NULL; -+ Authctxt *authctxt = ssh->authctxt; -+ gss_buffer_desc gssbuf; -+ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; -+ OM_uint32 ms; -+ int r; -+ -+ static int attempt = 0; -+ if (attempt++ >= 1) -+ return (0); -+ -+ if (gss_kex_context == NULL) { -+ debug("No valid Key exchange context"); -+ return (0); -+ } -+ -+ if ((b = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); -+ -+ ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, -+ "gssapi-keyex", ssh->kex->session_id); -+ -+ if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -+ fatal_f("sshbuf_mutable_ptr failed"); -+ gssbuf.length = sshbuf_len(b); -+ -+ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { -+ sshbuf_free(b); -+ return (0); -+ } -+ -+ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || -+ (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || -+ (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || -+ (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || -+ (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) -+ fatal_fr(r, "parsing"); -+ -+ sshbuf_free(b); -+ gss_release_buffer(&ms, &mic); -+ -+ return (1); -+} -+ - #endif /* GSSAPI */ - - static int -diff --git a/sshd-auth.c b/sshd-auth.c -index f957dc22..d51e4636 100644 ---- a/sshd-auth.c -+++ b/sshd-auth.c -@@ -844,6 +844,48 @@ do_ssh2_kex(struct ssh *ssh) - - free(hkalgs); - -+#if defined(GSSAPI) && defined(WITH_OPENSSL) -+ { -+ char *orig; -+ char *gss = NULL; -+ char *newstr = NULL; -+ 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 (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) -+ orig = NULL; -+ -+ if (options.gss_keyex) -+ gss = ssh_gssapi_server_mechanisms(); -+ else -+ gss = NULL; -+ -+ if (gss && orig) -+ xasprintf(&newstr, "%s,%s", gss, orig); -+ else if (gss) -+ xasprintf(&newstr, "%s,%s", gss, "kex-strict-s-v00@openssh.com"); -+ else if (orig) -+ 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 (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xstrdup("null"); -+ -+ if (newstr) -+ myproposal[PROPOSAL_KEX_ALGS] = newstr; -+ else -+ fatal("No supported key exchange algorithms"); -+ } -+#endif -+ - /* start key exchange */ - if ((r = kex_setup(ssh, myproposal)) != 0) - fatal_r(r, "kex_setup"); -@@ -861,6 +903,17 @@ do_ssh2_kex(struct ssh *ssh) - # ifdef OPENSSL_HAS_ECC - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; - # endif /* OPENSSL_HAS_ECC */ -+# ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; -+ } -+# endif - #endif /* WITH_OPENSSL */ - kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -diff --git a/sshd-session.c b/sshd-session.c -index a70b36c9..f8c8a797 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -616,8 +616,8 @@ notify_hostkeys(struct ssh *ssh) - } - debug3_f("sent %u hostkeys", nkeys); - if (nkeys == 0) -- fatal_f("no hostkeys"); -- if ((r = sshpkt_send(ssh)) != 0) -+ debug3_f("no hostkeys"); -+ else if ((r = sshpkt_send(ssh)) != 0) - sshpkt_fatal(ssh, r, "%s: send", __func__); - sshbuf_free(buf); - } -@@ -1159,8 +1159,9 @@ main(int ac, char **av) - break; - } - } -- if (!have_key) -- fatal("internal error: monitor received no hostkeys"); -+ /* The GSSAPI key exchange can run without a host key */ -+ if (!have_key && !options.gss_keyex) -+ fatal("internal error: monitor received no hostkeys and GSS KEX is not configured"); - - /* Ensure that umask disallows at least group and world write */ - new_umask = umask(0077) | 0022; -diff --git a/sshd.c b/sshd.c -index 4a93e29e..c9ea8e38 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -1676,7 +1676,8 @@ main(int ac, char **av) - free(fp); - } - accumulate_host_timing_secret(cfg, NULL); -- if (!sensitive_data.have_ssh2_key) { -+ /* The GSSAPI key exchange can run without a host key */ -+ if (!sensitive_data.have_ssh2_key && !options.gss_keyex) { - logit("sshd: no hostkeys available -- exiting."); - exit(1); - } -diff --git a/sshd_config b/sshd_config -index 48af6321..8db9f0fb 100644 ---- a/sshd_config -+++ b/sshd_config -@@ -79,6 +79,8 @@ AuthorizedKeysFile .ssh/authorized_keys - # GSSAPI options - #GSSAPIAuthentication no - #GSSAPICleanupCredentials yes -+#GSSAPIStrictAcceptorCheck yes -+#GSSAPIKeyExchange no - - # 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 035a50c8..8bc6586e 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -739,6 +739,11 @@ Specifies whether to automatically destroy the user's credentials cache - on logout. - The default is - .Cm yes . -+.It Cm GSSAPIKeyExchange -+Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange -+doesn't rely on ssh keys to verify host identity. -+The default is -+.Cm no . - .It Cm GSSAPIStrictAcceptorCheck - Determines whether to be strict about the identity of the GSSAPI acceptor - a client authenticates against. -@@ -753,6 +758,32 @@ machine's default store. - This facility is provided to assist with operation on multi homed machines. - The default is - .Cm yes . -+.It Cm GSSAPIStoreCredentialsOnRekey -+Controls whether the user's GSSAPI credentials should be updated following a -+successful connection rekeying. This option can be used to accepted renewed -+or updated credentials from a compatible client. The default is -+.Dq no . -+.Pp -+For this to work -+.Cm GSSAPIKeyExchange -+needs to be enabled in the server and also used by the client. -+.It Cm GSSAPIKexAlgorithms -+The list of key exchange algorithms that are accepted by GSSAPI -+key exchange. Possible values are -+.Bd -literal -offset 3n -+gss-gex-sha1-, -+gss-group1-sha1-, -+gss-group14-sha1-, -+gss-group14-sha256-, -+gss-group16-sha512-, -+gss-nistp256-sha256-, -+gss-curve25519-sha256- -+.Ed -+.Pp -+The default is -+.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, -+gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . -+This option only applies to connections using GSSAPI. - .It Cm HostbasedAcceptedAlgorithms - 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 ab80752b..4e41a78c 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -129,6 +129,75 @@ extern const struct sshkey_impl sshkey_xmss_impl; +diff --color -ruNp a/sshkey.c b/sshkey.c +--- a/sshkey.c 2024-07-01 06:36:28.000000000 +0200 ++++ b/sshkey.c 2024-09-16 11:46:34.706940139 +0200 +@@ -131,6 +131,75 @@ extern const struct sshkey_impl sshkey_x extern const struct sshkey_impl sshkey_xmss_cert_impl; #endif @@ -4276,7 +4170,7 @@ index ab80752b..4e41a78c 100644 const struct sshkey_impl * const keyimpls[] = { &sshkey_ed25519_impl, &sshkey_ed25519_cert_impl, -@@ -167,6 +236,7 @@ const struct sshkey_impl * const keyimpls[] = { +@@ -169,6 +238,7 @@ const struct sshkey_impl * const keyimpl &sshkey_xmss_impl, &sshkey_xmss_cert_impl, #endif @@ -4284,7 +4178,7 @@ index ab80752b..4e41a78c 100644 NULL }; -@@ -336,7 +406,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -324,7 +394,7 @@ sshkey_alg_list(int certs_only, int plai for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -4293,11 +4187,10 @@ index ab80752b..4e41a78c 100644 continue; if (!include_sigonly && impl->sigonly) continue; -diff --git a/sshkey.h b/sshkey.h -index 19bbbac7..4a318d05 100644 ---- a/sshkey.h -+++ b/sshkey.h -@@ -75,6 +75,7 @@ enum sshkey_types { +diff --color -ruNp a/sshkey.h b/sshkey.h +--- a/sshkey.h 2024-07-01 06:36:28.000000000 +0200 ++++ b/sshkey.h 2024-09-16 11:46:34.706940139 +0200 +@@ -71,6 +71,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, KEY_ED25519_SK_CERT, @@ -4305,6 +4198,3 @@ index 19bbbac7..4a318d05 100644 KEY_UNSPEC }; --- -2.49.0 - diff --git a/openssh-9.6p1-pam-rhost.patch b/openssh-9.6p1-pam-rhost.patch new file mode 100644 index 0000000..b1b0d04 --- /dev/null +++ b/openssh-9.6p1-pam-rhost.patch @@ -0,0 +1,32 @@ +From 26f366e263e575c4e1a18e2e64ba418f58878b37 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Mon, 20 Mar 2023 20:22:14 +0100 +Subject: [PATCH] Only set PAM_RHOST if the remote host is not "UNKNOWN" + +When using sshd's -i option with stdio that is not a AF_INET/AF_INET6 +socket, auth_get_canonical_hostname() returns "UNKNOWN" which is then +set as the value of PAM_RHOST, causing pam to try to do a reverse DNS +query of "UNKNOWN", which times out multiple times, causing a +substantial slowdown when logging in. + +To fix this, let's only set PAM_RHOST if the hostname is not "UNKNOWN". +--- + auth-pam.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/auth-pam.c b/auth-pam.c +index e143304e3..39b4e4563 100644 +--- a/auth-pam.c ++++ b/auth-pam.c +@@ -735,7 +735,7 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt) + sshpam_laddr = get_local_ipaddr( + ssh_packet_get_connection_in(ssh)); + } +- if (sshpam_rhost != NULL) { ++ if (sshpam_rhost != NULL && strcmp(sshpam_rhost, "UNKNOWN") != 0) { + debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); + sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, + sshpam_rhost); +-- +2.44.0 + diff --git a/openssh-9.9p1-disable-forwarding.patch b/openssh-9.9p1-disable-forwarding.patch new file mode 100644 index 0000000..45a021e --- /dev/null +++ b/openssh-9.9p1-disable-forwarding.patch @@ -0,0 +1,22 @@ +diff --color -ruNp a/session.c b/session.c +--- a/session.c 2025-04-29 11:20:59.475107377 +0200 ++++ b/session.c 2025-04-29 11:23:16.638538968 +0200 +@@ -2284,7 +2284,8 @@ session_auth_agent_req(struct ssh *ssh, + if ((r = sshpkt_get_end(ssh)) != 0) + sshpkt_fatal(ssh, r, "%s: parse packet", __func__); + if (!auth_opts->permit_agent_forwarding_flag || +- !options.allow_agent_forwarding) { ++ !options.allow_agent_forwarding || ++ options.disable_forwarding) { + debug_f("agent forwarding disabled"); + return 0; + } +@@ -2709,7 +2710,7 @@ session_setup_x11fwd(struct ssh *ssh, Se + ssh_packet_send_debug(ssh, "X11 forwarding disabled by key options."); + return 0; + } +- if (!options.x11_forwarding) { ++ if (!options.x11_forwarding || options.disable_forwarding) { + debug("X11 forwarding disabled in server configuration file."); + return 0; + } diff --git a/2000-openssh-10.0p1-gsissh.patch b/openssh-9.9p1-gsissh.patch similarity index 86% rename from 2000-openssh-10.0p1-gsissh.patch rename to openssh-9.9p1-gsissh.patch index 4a1a329..5e2d011 100644 --- a/2000-openssh-10.0p1-gsissh.patch +++ b/openssh-9.9p1-gsissh.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-10.0p1.orig/auth2.c openssh-10.0p1/auth2.c ---- openssh-10.0p1.orig/auth2.c 2025-06-14 08:24:55.444264765 +0200 -+++ openssh-10.0p1/auth2.c 2025-06-14 08:25:50.314922659 +0200 +diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c +--- openssh-9.9p1.orig/auth2.c 2025-01-20 19:52:47.907052307 +0100 ++++ openssh-9.9p1/auth2.c 2025-01-20 20:23:17.232729940 +0100 @@ -286,7 +286,28 @@ (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) @@ -101,9 +101,9 @@ diff -Nur openssh-10.0p1.orig/auth2.c openssh-10.0p1/auth2.c "not allowed: (%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } -diff -Nur openssh-10.0p1.orig/auth2-gss.c openssh-10.0p1/auth2-gss.c ---- openssh-10.0p1.orig/auth2-gss.c 2025-06-14 08:24:54.946580198 +0200 -+++ openssh-10.0p1/auth2-gss.c 2025-06-14 08:25:50.315696363 +0200 +diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c +--- openssh-9.9p1.orig/auth2-gss.c 2025-01-20 19:52:47.769051955 +0100 ++++ openssh-9.9p1/auth2-gss.c 2025-01-20 20:23:17.233729943 +0100 @@ -54,6 +54,7 @@ extern struct authmethod_cfg methodcfg_gsskeyex; extern struct authmethod_cfg methodcfg_gssapi; @@ -303,9 +303,9 @@ diff -Nur openssh-10.0p1.orig/auth2-gss.c openssh-10.0p1/auth2-gss.c Authmethod method_gsskeyex = { &methodcfg_gsskeyex, userauth_gsskeyex, -diff -Nur openssh-10.0p1.orig/auth.c openssh-10.0p1/auth.c ---- openssh-10.0p1.orig/auth.c 2025-06-14 08:24:55.443524655 +0200 -+++ openssh-10.0p1/auth.c 2025-06-14 08:25:50.316281495 +0200 +diff -Nur openssh-9.9p1.orig/auth.c openssh-9.9p1/auth.c +--- openssh-9.9p1.orig/auth.c 2025-01-20 19:52:47.908052310 +0100 ++++ openssh-9.9p1/auth.c 2025-01-20 20:23:17.233729943 +0100 @@ -298,7 +298,8 @@ method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, @@ -336,9 +336,9 @@ diff -Nur openssh-10.0p1.orig/auth.c openssh-10.0p1/auth.c #ifdef CUSTOM_FAILED_LOGIN record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); -diff -Nur openssh-10.0p1.orig/auth.h openssh-10.0p1/auth.h ---- openssh-10.0p1.orig/auth.h 2025-06-14 08:24:55.443709595 +0200 -+++ openssh-10.0p1/auth.h 2025-06-14 08:25:50.316833592 +0200 +diff -Nur openssh-9.9p1.orig/auth.h openssh-9.9p1/auth.h +--- openssh-9.9p1.orig/auth.h 2025-01-20 19:52:47.909052313 +0100 ++++ openssh-9.9p1/auth.h 2025-01-20 20:23:17.234729946 +0100 @@ -85,6 +85,8 @@ krb5_principal krb5_user; char *krb5_ticket_file; @@ -348,9 +348,9 @@ diff -Nur openssh-10.0p1.orig/auth.h openssh-10.0p1/auth.h int krb5_set_env; #endif struct sshbuf *loginmsg; -diff -Nur openssh-10.0p1.orig/auth-pam.c openssh-10.0p1/auth-pam.c ---- openssh-10.0p1.orig/auth-pam.c 2025-06-14 08:24:55.609208310 +0200 -+++ openssh-10.0p1/auth-pam.c 2025-06-14 08:25:50.317378775 +0200 +diff -Nur openssh-9.9p1.orig/auth-pam.c openssh-9.9p1/auth-pam.c +--- openssh-9.9p1.orig/auth-pam.c 2025-01-20 19:52:47.954052427 +0100 ++++ openssh-9.9p1/auth-pam.c 2025-01-20 20:23:17.264730023 +0100 @@ -248,6 +248,7 @@ static const char *sshpam_password = NULL; static char *sshpam_rhost = NULL; @@ -511,9 +511,9 @@ diff -Nur openssh-10.0p1.orig/auth-pam.c openssh-10.0p1/auth-pam.c sshpam_password = NULL; free(fake); if (sshpam_err == PAM_MAXTRIES) -diff -Nur openssh-10.0p1.orig/auth-pam.h openssh-10.0p1/auth-pam.h ---- openssh-10.0p1.orig/auth-pam.h 2025-06-14 08:24:54.755199761 +0200 -+++ openssh-10.0p1/auth-pam.h 2025-06-14 08:25:50.318085082 +0200 +diff -Nur openssh-9.9p1.orig/auth-pam.h openssh-9.9p1/auth-pam.h +--- openssh-9.9p1.orig/auth-pam.h 2025-01-20 19:52:47.713051809 +0100 ++++ openssh-9.9p1/auth-pam.h 2025-01-20 20:23:17.264730023 +0100 @@ -43,5 +43,6 @@ int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); @@ -521,9 +521,9 @@ diff -Nur openssh-10.0p1.orig/auth-pam.h openssh-10.0p1/auth-pam.h +struct passwd *sshpam_getpw(const char *); #endif /* USE_PAM */ -diff -Nur openssh-10.0p1.orig/canohost.c openssh-10.0p1/canohost.c ---- openssh-10.0p1.orig/canohost.c 2025-06-14 08:24:54.947106244 +0200 -+++ openssh-10.0p1/canohost.c 2025-06-14 08:25:50.318537655 +0200 +diff -Nur openssh-9.9p1.orig/canohost.c openssh-9.9p1/canohost.c +--- openssh-9.9p1.orig/canohost.c 2025-01-20 19:52:47.770051957 +0100 ++++ openssh-9.9p1/canohost.c 2025-01-20 20:23:17.265730026 +0100 @@ -17,6 +17,7 @@ #include #include @@ -566,9 +566,9 @@ diff -Nur openssh-10.0p1.orig/canohost.c openssh-10.0p1/canohost.c + } + } +} -diff -Nur openssh-10.0p1.orig/canohost.h openssh-10.0p1/canohost.h ---- openssh-10.0p1.orig/canohost.h 2025-06-14 08:24:54.947234403 +0200 -+++ openssh-10.0p1/canohost.h 2025-06-14 08:25:50.318980799 +0200 +diff -Nur openssh-9.9p1.orig/canohost.h openssh-9.9p1/canohost.h +--- openssh-9.9p1.orig/canohost.h 2025-01-20 19:52:47.770051957 +0100 ++++ openssh-9.9p1/canohost.h 2025-01-20 20:23:17.265730026 +0100 @@ -26,4 +26,6 @@ #endif /* _CANOHOST_H */ @@ -576,10 +576,10 @@ diff -Nur openssh-10.0p1.orig/canohost.h openssh-10.0p1/canohost.h +void resolve_localhost(char **host); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); -diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac ---- openssh-10.0p1.orig/configure.ac 2025-06-14 08:24:55.711190794 +0200 -+++ openssh-10.0p1/configure.ac 2025-06-14 08:25:50.319884827 +0200 -@@ -4992,6 +4992,14 @@ +diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac +--- openssh-9.9p1.orig/configure.ac 2025-01-20 19:52:47.872052217 +0100 ++++ openssh-9.9p1/configure.ac 2025-01-20 20:23:17.266730028 +0100 +@@ -4920,6 +4920,14 @@ AC_CHECK_HEADER([gssapi_krb5.h], , [ CPPFLAGS="$oldCPP" ]) @@ -594,7 +594,7 @@ diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac fi fi if test -n "${rpath_opt}" ; then -@@ -5034,6 +5042,40 @@ +@@ -4961,6 +4969,40 @@ AC_SUBST([K5LIBS]) AC_SUBST([CHANNELLIBS]) @@ -635,9 +635,9 @@ diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac # Looking for programs, paths and files PRIVSEP_PATH=/var/empty -diff -Nur openssh-10.0p1.orig/gss-genr.c openssh-10.0p1/gss-genr.c ---- openssh-10.0p1.orig/gss-genr.c 2025-06-14 08:24:55.730946369 +0200 -+++ openssh-10.0p1/gss-genr.c 2025-06-14 08:25:50.321274952 +0200 +diff -Nur openssh-9.9p1.orig/gss-genr.c openssh-9.9p1/gss-genr.c +--- openssh-9.9p1.orig/gss-genr.c 2025-01-20 19:52:47.962052448 +0100 ++++ openssh-9.9p1/gss-genr.c 2025-01-20 20:23:17.267730031 +0100 @@ -41,6 +41,7 @@ #include "ssherr.h" #include "sshbuf.h" @@ -674,10 +674,10 @@ diff -Nur openssh-10.0p1.orig/gss-genr.c openssh-10.0p1/gss-genr.c free(gssbuf.value); return (ctx->major); } -diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c ---- openssh-10.0p1.orig/gss-serv.c 2025-06-14 08:24:55.712377680 +0200 -+++ openssh-10.0p1/gss-serv.c 2025-06-14 14:29:38.679799497 +0200 -@@ -51,10 +51,12 @@ +diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c +--- openssh-9.9p1.orig/gss-serv.c 2025-01-20 19:52:47.802052038 +0100 ++++ openssh-9.9p1/gss-serv.c 2025-01-20 20:23:17.268730033 +0100 +@@ -50,10 +50,12 @@ #include "monitor_wrap.h" extern ServerOptions options; @@ -685,14 +685,14 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c static ssh_gssapi_client gssapi_client = - { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, -- GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0, NULL}; +- GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0}; + { {0, NULL}, GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, + GSS_C_NO_NAME, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, -+ GSS_C_NO_CONTEXT, 0, 0, NULL}; ++ GSS_C_NO_CONTEXT, 0, 0}; ssh_gssapi_mech gssapi_null_mech = { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; -@@ -62,14 +64,26 @@ +@@ -61,14 +63,26 @@ #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; #endif @@ -719,7 +719,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c /* * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the * list of supported mechanisms before privsep is set up. -@@ -230,6 +244,10 @@ +@@ -229,6 +243,10 @@ (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { if (ssh_gssapi_getclient(ctx, &gssapi_client)) fatal("Couldn't convert client name"); @@ -730,7 +730,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c } return (status); -@@ -249,6 +267,20 @@ +@@ -248,6 +266,20 @@ tok = ename->value; @@ -751,23 +751,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct -@@ -297,6 +329,7 @@ - } - - -+#ifdef KRB5 - /* Extract authentication indicators from the Kerberos ticket. Authentication - * indicators are GSSAPI name attributes for the name "auth-indicators". - * Multiple indicators might be present in the ticket. -@@ -380,6 +413,7 @@ - (void) gss_release_buffer_set(&ctx->minor, &attrs); - return (ctx->major); - } -+#endif - - - /* Extract the client details from a given context. This can only reliably -@@ -395,21 +429,24 @@ +@@ -308,21 +340,24 @@ gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; if (options.gss_store_rekey && client->used && ctx->client_creds) { @@ -797,7 +781,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c new_name, &equal); if (GSS_ERROR(ctx->major)) { -@@ -424,9 +461,9 @@ +@@ -337,9 +372,9 @@ debug("Marking rekeyed credentials for export"); @@ -809,7 +793,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; client->updated = 1; -@@ -443,12 +480,17 @@ +@@ -356,12 +391,17 @@ i++; } @@ -829,7 +813,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c ssh_gssapi_error(ctx); return (ctx->major); } -@@ -465,22 +507,33 @@ +@@ -378,16 +418,25 @@ return (ctx->major); } @@ -845,14 +829,6 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c + return ctx->major; + gss_release_buffer(&ctx->minor, &ename); -+#ifdef KRB5 - /* Retrieve authentication indicators, if they exist */ - if ((ctx->major = ssh_gssapi_getindicators(ctx, - ctx->client, client))) { - ssh_gssapi_error(ctx); - return (ctx->major); - } -+#endif /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; @@ -864,7 +840,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c return (ctx->major); } -@@ -488,6 +541,7 @@ +@@ -395,6 +444,7 @@ void ssh_gssapi_cleanup_creds(void) { @@ -872,7 +848,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c krb5_ccache ccache = NULL; krb5_error_code problem; -@@ -503,6 +557,14 @@ +@@ -410,6 +460,14 @@ gssapi_client.store.data = NULL; } } @@ -887,7 +863,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c } /* As user */ -@@ -510,6 +572,11 @@ +@@ -417,6 +475,11 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { @@ -899,7 +875,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c return (*gssapi_client.mech->storecreds)(&gssapi_client); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -@@ -543,11 +610,13 @@ +@@ -449,11 +512,13 @@ (void) kex; /* used in privilege separation */ @@ -916,15 +892,15 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c if (gssapi_client.mech && gssapi_client.mech->userok) if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { gssapi_client.used = 1; -@@ -558,6 +627,7 @@ +@@ -464,6 +529,7 @@ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); gss_release_cred(&lmin, &gssapi_client.creds); + gss_release_name(&lmin, &gssapi_client.ctx_name); - - if (gssapi_client.indicators != NULL) { - for(i = 0; gssapi_client.indicators[i] != NULL; i++) { -@@ -575,6 +645,24 @@ + explicit_bzero(&gssapi_client, + sizeof(ssh_gssapi_client)); + return 0; +@@ -473,6 +539,24 @@ return (0); } @@ -949,7 +925,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c /* These bits are only used for rekeying. The unpriviledged child is running * as the user, the monitor is root. * -@@ -601,9 +689,11 @@ +@@ -499,9 +583,11 @@ pam_handle_t *pamh = NULL; struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; char *envstr; @@ -962,7 +938,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c return; ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); -@@ -623,6 +713,18 @@ +@@ -521,6 +607,18 @@ if (ret) return; @@ -981,9 +957,9 @@ diff -Nur openssh-10.0p1.orig/gss-serv.c openssh-10.0p1/gss-serv.c xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, gssapi_client.store.envval); -diff -Nur openssh-10.0p1.orig/gss-serv-gsi.c openssh-10.0p1/gss-serv-gsi.c ---- openssh-10.0p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/gss-serv-gsi.c 2025-06-14 08:25:50.323228698 +0200 +diff -Nur openssh-9.9p1.orig/gss-serv-gsi.c openssh-9.9p1/gss-serv-gsi.c +--- openssh-9.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/gss-serv-gsi.c 2025-01-20 20:23:17.268730033 +0100 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1313,10 +1289,10 @@ diff -Nur openssh-10.0p1.orig/gss-serv-gsi.c openssh-10.0p1/gss-serv-gsi.c + +#endif /* GSI */ +#endif /* GSSAPI */ -diff -Nur openssh-10.0p1.orig/gss-serv-krb5.c openssh-10.0p1/gss-serv-krb5.c ---- openssh-10.0p1.orig/gss-serv-krb5.c 2025-06-14 08:24:55.712149299 +0200 -+++ openssh-10.0p1/gss-serv-krb5.c 2025-06-14 08:25:50.323586985 +0200 -@@ -431,6 +431,34 @@ +diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c +--- openssh-9.9p1.orig/gss-serv-krb5.c 2025-01-20 19:52:47.824052094 +0100 ++++ openssh-9.9p1/gss-serv-krb5.c 2025-01-20 20:23:17.269730036 +0100 +@@ -379,6 +379,34 @@ return found_principal; } @@ -1351,7 +1327,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv-krb5.c openssh-10.0p1/gss-serv-krb5.c /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ -@@ -525,7 +553,7 @@ +@@ -473,7 +501,7 @@ return set_env; } @@ -1360,7 +1336,7 @@ diff -Nur openssh-10.0p1.orig/gss-serv-krb5.c openssh-10.0p1/gss-serv-krb5.c ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { -@@ -596,7 +624,7 @@ +@@ -544,7 +572,7 @@ {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, @@ -1369,9 +1345,9 @@ diff -Nur openssh-10.0p1.orig/gss-serv-krb5.c openssh-10.0p1/gss-serv-krb5.c &ssh_gssapi_krb5_storecreds, &ssh_gssapi_krb5_updatecreds }; -diff -Nur openssh-10.0p1.orig/kexgsss.c openssh-10.0p1/kexgsss.c ---- openssh-10.0p1.orig/kexgsss.c 2025-06-14 08:24:54.950961355 +0200 -+++ openssh-10.0p1/kexgsss.c 2025-06-14 08:25:50.324355451 +0200 +diff -Nur openssh-9.9p1.orig/kexgsss.c openssh-9.9p1/kexgsss.c +--- openssh-9.9p1.orig/kexgsss.c 2025-01-20 19:52:47.785051995 +0100 ++++ openssh-9.9p1/kexgsss.c 2025-01-21 07:14:03.079570547 +0100 @@ -48,6 +48,7 @@ #include "digest.h" #include "ssherr.h" @@ -1435,31 +1411,21 @@ diff -Nur openssh-10.0p1.orig/kexgsss.c openssh-10.0p1/kexgsss.c +} + #endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in ---- openssh-10.0p1.orig/Makefile.in 2025-06-14 08:24:55.442297261 +0200 -+++ openssh-10.0p1/Makefile.in 2025-06-14 14:49:48.752490751 +0200 -@@ -140,7 +140,7 @@ - auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ +diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in +--- openssh-9.9p1.orig/Makefile.in 2025-01-20 19:52:47.911052318 +0100 ++++ openssh-9.9p1/Makefile.in 2025-01-20 20:23:17.270730038 +0100 +@@ -138,6 +138,7 @@ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ monitor.o monitor_wrap.o auth-krb5.o kexgsss.o \ -- auth2-gss.o gss-serv.o gss-serv-krb5.o \ -+ auth2-gss.o gss-serv.o gss-serv-krb5.o gss-serv-gsi.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o \ ++ gss-serv-gsi.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ sftp-server.o sftp-common.o \ - uidswap.o platform-listen.o $(SKOBJS) -@@ -151,7 +151,7 @@ - serverloop.o auth.o auth2.o auth-options.o session.o auth2-chall.o \ - groupaccess.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ -- auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ -+ auth2-gss.o gss-serv.o gss-serv-krb5.o gss-serv-gsi.o kexgsss.o \ - monitor_wrap.o auth-krb5.o \ - audit.o audit-bsm.o audit-linux.o platform.o \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ -diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c ---- openssh-10.0p1.orig/misc.c 2025-06-14 08:24:55.731834474 +0200 -+++ openssh-10.0p1/misc.c 2025-06-14 08:25:50.325895875 +0200 -@@ -440,11 +440,14 @@ + sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ +diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c +--- openssh-9.9p1.orig/misc.c 2025-01-20 19:52:47.963052451 +0100 ++++ openssh-9.9p1/misc.c 2025-01-20 20:23:17.271730041 +0100 +@@ -419,11 +419,14 @@ #define WHITESPACE " \t\r\n" #define QUOTE "\"" @@ -1475,7 +1441,7 @@ diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c int wspace = 0; if (*s == NULL) -@@ -452,6 +455,21 @@ +@@ -431,6 +434,21 @@ old = *s; @@ -1497,7 +1463,7 @@ diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c *s = strpbrk(*s, split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) -@@ -527,6 +545,20 @@ +@@ -506,6 +524,20 @@ return copy; } @@ -1518,10 +1484,10 @@ diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. -diff -Nur openssh-10.0p1.orig/misc.h openssh-10.0p1/misc.h ---- openssh-10.0p1.orig/misc.h 2025-06-14 08:24:55.216960866 +0200 -+++ openssh-10.0p1/misc.h 2025-06-14 08:25:50.326898660 +0200 -@@ -112,6 +112,7 @@ +diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h +--- openssh-9.9p1.orig/misc.h 2025-01-20 19:52:47.840052135 +0100 ++++ openssh-9.9p1/misc.h 2025-01-20 20:23:17.272730043 +0100 +@@ -111,6 +111,7 @@ void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); @@ -1529,10 +1495,10 @@ diff -Nur openssh-10.0p1.orig/misc.h openssh-10.0p1/misc.h const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); -diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c ---- openssh-10.0p1.orig/monitor.c 2025-06-14 08:24:55.732232011 +0200 -+++ openssh-10.0p1/monitor.c 2025-06-14 08:25:50.327682491 +0200 -@@ -151,6 +151,9 @@ +diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c +--- openssh-9.9p1.orig/monitor.c 2025-01-20 19:52:47.964052453 +0100 ++++ openssh-9.9p1/monitor.c 2025-01-20 20:23:17.273730046 +0100 +@@ -148,6 +148,9 @@ int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); @@ -1542,7 +1508,7 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #endif -@@ -205,7 +208,7 @@ +@@ -201,7 +204,7 @@ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, @@ -1551,7 +1517,7 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, #ifdef WITH_SELINUX {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -@@ -213,7 +216,7 @@ +@@ -209,7 +212,7 @@ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -1560,7 +1526,7 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, -@@ -237,8 +240,11 @@ +@@ -233,8 +236,11 @@ {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, @@ -1573,7 +1539,7 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c #endif {0, 0, NULL} }; -@@ -248,6 +254,8 @@ +@@ -244,6 +250,8 @@ {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, @@ -1581,8 +1547,8 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c + {MONITOR_REQ_GSSMECHS, 0, mm_answer_gss_indicate_mechs}, {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, #endif - {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, -@@ -328,6 +336,8 @@ + #ifdef WITH_OPENSSL +@@ -324,6 +332,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1591,7 +1557,7 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c #endif /* The first few requests do not require asynchronous access */ -@@ -461,6 +471,8 @@ +@@ -458,6 +468,8 @@ #ifdef GSSAPI /* and for the GSSAPI key exchange */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); @@ -1600,7 +1566,7 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c #endif if (auth_opts->permit_pty_flag) { -@@ -895,14 +907,17 @@ +@@ -812,14 +824,17 @@ debug3_f("entering"); @@ -1621,7 +1587,7 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c setproctitle("%s [priv]", pwent ? authctxt->user : "unknown"); sshbuf_reset(m); -@@ -2249,6 +2264,79 @@ +@@ -2170,6 +2185,79 @@ } int @@ -1701,10 +1667,10 @@ diff -Nur openssh-10.0p1.orig/monitor.c openssh-10.0p1/monitor.c mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) { gss_buffer_desc data; -diff -Nur openssh-10.0p1.orig/monitor.h openssh-10.0p1/monitor.h ---- openssh-10.0p1.orig/monitor.h 2025-06-14 08:24:55.446043209 +0200 -+++ openssh-10.0p1/monitor.h 2025-06-14 08:25:50.328788501 +0200 -@@ -76,6 +76,10 @@ +diff -Nur openssh-9.9p1.orig/monitor.h openssh-9.9p1/monitor.h +--- openssh-9.9p1.orig/monitor.h 2025-01-20 19:52:47.912052320 +0100 ++++ openssh-9.9p1/monitor.h 2025-01-20 20:23:17.273730046 +0100 +@@ -75,6 +75,10 @@ MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, @@ -1715,10 +1681,10 @@ diff -Nur openssh-10.0p1.orig/monitor.h openssh-10.0p1/monitor.h }; struct ssh; -diff -Nur openssh-10.0p1.orig/monitor_wrap.c openssh-10.0p1/monitor_wrap.c ---- openssh-10.0p1.orig/monitor_wrap.c 2025-06-14 08:24:55.468434323 +0200 -+++ openssh-10.0p1/monitor_wrap.c 2025-06-14 08:25:50.329256997 +0200 -@@ -1195,6 +1195,94 @@ +diff -Nur openssh-9.9p1.orig/monitor_wrap.c openssh-9.9p1/monitor_wrap.c +--- openssh-9.9p1.orig/monitor_wrap.c 2025-01-20 19:52:47.918052335 +0100 ++++ openssh-9.9p1/monitor_wrap.c 2025-01-20 20:23:17.274730049 +0100 +@@ -1139,6 +1139,94 @@ return (authenticated); } @@ -1813,9 +1779,9 @@ diff -Nur openssh-10.0p1.orig/monitor_wrap.c openssh-10.0p1/monitor_wrap.c OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { -diff -Nur openssh-10.0p1.orig/monitor_wrap.h openssh-10.0p1/monitor_wrap.h ---- openssh-10.0p1.orig/monitor_wrap.h 2025-06-14 08:24:55.468730870 +0200 -+++ openssh-10.0p1/monitor_wrap.h 2025-06-14 08:25:50.329790028 +0200 +diff -Nur openssh-9.9p1.orig/monitor_wrap.h openssh-9.9p1/monitor_wrap.h +--- openssh-9.9p1.orig/monitor_wrap.h 2025-01-20 19:52:47.918052335 +0100 ++++ openssh-9.9p1/monitor_wrap.h 2025-01-20 20:23:17.274730049 +0100 @@ -72,6 +72,10 @@ int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); @@ -1827,10 +1793,10 @@ diff -Nur openssh-10.0p1.orig/monitor_wrap.h openssh-10.0p1/monitor_wrap.h int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); #endif -diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c ---- openssh-10.0p1.orig/readconf.c 2025-06-14 08:24:55.733023595 +0200 -+++ openssh-10.0p1/readconf.c 2025-06-14 08:25:50.330266207 +0200 -@@ -2881,11 +2881,11 @@ +diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c +--- openssh-9.9p1.orig/readconf.c 2025-01-20 19:52:47.966052458 +0100 ++++ openssh-9.9p1/readconf.c 2025-01-20 20:23:17.275730051 +0100 +@@ -2794,11 +2794,11 @@ if (options->pubkey_authentication == -1) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) @@ -1845,10 +1811,10 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c if (options->gss_trust_dns == -1) options->gss_trust_dns = 0; if (options->gss_renewal_rekey == -1) -diff -Nur openssh-10.0p1.orig/readconf.h openssh-10.0p1/readconf.h ---- openssh-10.0p1.orig/readconf.h 2025-06-14 08:24:54.953487731 +0200 -+++ openssh-10.0p1/readconf.h 2025-06-14 08:25:50.330993746 +0200 -@@ -79,6 +79,8 @@ +diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h +--- openssh-9.9p1.orig/readconf.h 2025-01-20 19:52:47.790052008 +0100 ++++ openssh-9.9p1/readconf.h 2025-01-20 20:23:17.276730054 +0100 +@@ -80,6 +80,8 @@ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ char *proxy_command; /* Proxy command for connecting the host. */ char *user; /* User to log in as. */ @@ -1857,10 +1823,10 @@ diff -Nur openssh-10.0p1.orig/readconf.h openssh-10.0p1/readconf.h int escape_char; /* Escape character; -2 = none */ u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ -diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c ---- openssh-10.0p1.orig/servconf.c 2025-06-14 08:24:55.733579673 +0200 -+++ openssh-10.0p1/servconf.c 2025-06-14 08:25:50.331610935 +0200 -@@ -96,6 +96,7 @@ +diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c +--- openssh-9.9p1.orig/servconf.c 2025-01-20 19:52:47.966052458 +0100 ++++ openssh-9.9p1/servconf.c 2025-01-20 20:23:17.277730056 +0100 +@@ -95,6 +95,7 @@ /* Portable-specific options */ options->use_pam = -1; options->pam_service_name = NULL; @@ -1868,7 +1834,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c /* Standard Options */ options->num_ports = 0; -@@ -142,9 +143,11 @@ +@@ -141,9 +142,11 @@ options->kerberos_get_afs_token = -1; options->kerberos_unique_ccache = -1; options->gss_authentication=-1; @@ -1879,8 +1845,8 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c + options->gsi_allow_limited_proxy = -1; options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; - options->gss_indicators = NULL; -@@ -317,6 +320,8 @@ + options->use_kuserok = -1; +@@ -314,6 +317,8 @@ options->use_pam = 0; if (options->pam_service_name == NULL) options->pam_service_name = xstrdup(SSHD_PAM_SERVICE); @@ -1889,7 +1855,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c /* Standard Options */ if (options->num_host_key_files == 0) { -@@ -398,13 +403,17 @@ +@@ -395,13 +400,17 @@ if (options->kerberos_unique_ccache == -1) options->kerberos_unique_ccache = 0; if (options->gss_authentication == -1) @@ -1909,7 +1875,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c if (options->gss_store_rekey == -1) options->gss_store_rekey = 0; #ifdef GSSAPI -@@ -578,7 +587,7 @@ +@@ -573,7 +582,7 @@ typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ @@ -1918,7 +1884,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -598,6 +607,9 @@ +@@ -593,6 +602,9 @@ sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -1926,9 +1892,9 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c + sGssCredsPath, + sGsiAllowLimitedProxy, sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, - sGssKeyEx, sGssIndicators, sGssKexAlgorithms, sGssStoreRekey, + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, -@@ -633,9 +645,11 @@ +@@ -628,9 +640,11 @@ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, { "pamservicename", sPAMServiceName, SSHCFG_ALL }, @@ -1940,7 +1906,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ -@@ -688,8 +702,15 @@ +@@ -683,8 +697,15 @@ { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, @@ -1956,8 +1922,8 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, -@@ -698,8 +719,11 @@ - { "gssapiindicators", sGssIndicators, SSHCFG_ALL }, +@@ -692,8 +713,11 @@ + { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL }, @@ -1968,7 +1934,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, -@@ -774,6 +798,8 @@ +@@ -767,6 +791,8 @@ { "permitlisten", sPermitListen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, @@ -1977,7 +1943,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, -@@ -1454,6 +1480,10 @@ +@@ -1407,6 +1433,10 @@ *charptr = xstrdup(arg); break; @@ -1988,7 +1954,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c /* Standard Options */ case sBadOption: goto out; -@@ -1705,6 +1735,10 @@ +@@ -1658,6 +1688,10 @@ intptr = &options->gss_authentication; goto parse_flag; @@ -1999,7 +1965,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c case sGssKeyEx: intptr = &options->gss_keyex; goto parse_flag; -@@ -1713,6 +1747,10 @@ +@@ -1666,6 +1700,10 @@ intptr = &options->gss_cleanup_creds; goto parse_flag; @@ -2010,8 +1976,8 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; -@@ -1742,6 +1780,12 @@ - options->gss_indicators = xstrdup(arg); +@@ -1686,6 +1724,12 @@ + options->gss_kex_algorithms = xstrdup(arg); break; +#ifdef GSI @@ -2023,7 +1989,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3012,6 +3056,7 @@ +@@ -2950,6 +2994,7 @@ M_CP_INTOPT(password_authentication); M_CP_INTOPT(gss_authentication); @@ -2031,9 +1997,9 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c M_CP_INTOPT(pubkey_authentication); M_CP_INTOPT(pubkey_auth_options); M_CP_INTOPT(kerberos_authentication); -diff -Nur openssh-10.0p1.orig/servconf.h openssh-10.0p1/servconf.h ---- openssh-10.0p1.orig/servconf.h 2025-06-14 08:24:55.713201111 +0200 -+++ openssh-10.0p1/servconf.h 2025-06-14 08:25:50.332635999 +0200 +diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h +--- openssh-9.9p1.orig/servconf.h 2025-01-20 19:52:47.836052125 +0100 ++++ openssh-9.9p1/servconf.h 2025-01-20 20:23:17.278730059 +0100 @@ -155,9 +155,12 @@ * be stored in per-session ccache */ int use_kuserok; @@ -2047,7 +2013,7 @@ diff -Nur openssh-10.0p1.orig/servconf.h openssh-10.0p1/servconf.h int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int gss_store_rekey; char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ -@@ -222,6 +225,7 @@ +@@ -221,6 +224,7 @@ int use_pam; /* Enable auth via PAM */ char *pam_service_name; @@ -2055,10 +2021,10 @@ diff -Nur openssh-10.0p1.orig/servconf.h openssh-10.0p1/servconf.h int permit_tun; -diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 ---- openssh-10.0p1.orig/ssh.1 2025-06-14 08:24:55.527924262 +0200 -+++ openssh-10.0p1/ssh.1 2025-06-14 08:25:50.333158134 +0200 -@@ -1528,6 +1528,18 @@ +diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 +--- openssh-9.9p1.orig/ssh.1 2025-01-20 19:52:47.941052394 +0100 ++++ openssh-9.9p1/ssh.1 2025-01-20 20:23:17.279730061 +0100 +@@ -1523,6 +1523,18 @@ on to new connections). .It Ev USER Set to the name of the user logging in. @@ -2077,10 +2043,10 @@ diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 .El .Pp Additionally, -diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c ---- openssh-10.0p1.orig/ssh.c 2025-06-14 08:24:55.693276450 +0200 -+++ openssh-10.0p1/ssh.c 2025-06-14 13:58:47.186170059 +0200 -@@ -578,6 +578,38 @@ +diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c +--- openssh-9.9p1.orig/ssh.c 2025-01-20 19:52:47.926052356 +0100 ++++ openssh-9.9p1/ssh.c 2025-01-20 20:23:17.280730064 +0100 +@@ -573,6 +573,38 @@ fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -2096,14 +2062,14 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_name, cmd, ++ (void)read_config_file(buf, pw, host, host_name, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#ifdef GSI + r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_name, cmd, ++ (void)read_config_file(buf, pw, host, host_name, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#endif @@ -2111,7 +2077,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c + r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir, + _PATH_SSH_USER_CONFFILE); + if (r > 0 && (size_t)r < sizeof(buf)) -+ (void)read_config_file(buf, pw, host, host_name, cmd, ++ (void)read_config_file(buf, pw, host, host_name, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); +#endif @@ -2119,7 +2085,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) -@@ -1313,8 +1345,12 @@ +@@ -1299,8 +1331,12 @@ if (fill_default_options(&options) != 0) cleanup_exit(255); @@ -2133,9 +2099,9 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c /* * If ProxyJump option specified, then construct a ProxyCommand now. -diff -Nur openssh-10.0p1.orig/ssh_config openssh-10.0p1/ssh_config ---- openssh-10.0p1.orig/ssh_config 2025-06-14 08:24:54.955694862 +0200 -+++ openssh-10.0p1/ssh_config 2025-06-14 08:25:50.334427503 +0200 +diff -Nur openssh-9.9p1.orig/ssh_config openssh-9.9p1/ssh_config +--- openssh-9.9p1.orig/ssh_config 2025-01-20 19:52:47.793052015 +0100 ++++ openssh-9.9p1/ssh_config 2025-01-20 20:23:17.281730067 +0100 @@ -22,9 +22,9 @@ # ForwardX11 no # PasswordAuthentication yes @@ -2149,9 +2115,9 @@ diff -Nur openssh-10.0p1.orig/ssh_config openssh-10.0p1/ssh_config # GSSAPITrustDNS no # BatchMode no # CheckHostIP no -diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 ---- openssh-10.0p1.orig/ssh_config.5 2025-06-14 08:24:55.625225410 +0200 -+++ openssh-10.0p1/ssh_config.5 2025-06-14 08:25:50.334845923 +0200 +diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 +--- openssh-9.9p1.orig/ssh_config.5 2025-01-20 19:52:47.956052433 +0100 ++++ openssh-9.9p1/ssh_config.5 2025-01-20 20:23:17.282730069 +0100 @@ -52,6 +52,12 @@ user's configuration file .Pq Pa ~/.ssh/config @@ -2165,7 +2131,7 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 system-wide configuration file .Pq Pa /etc/ssh/ssh_config .El -@@ -969,7 +975,7 @@ +@@ -931,7 +937,7 @@ .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is @@ -2174,7 +2140,7 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 .It Cm GSSAPIClientIdentity If set, specifies the GSSAPI client identity that ssh should use when connecting to the server. The default is unset, which means that the default -@@ -977,12 +983,12 @@ +@@ -939,12 +945,12 @@ .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is @@ -2189,7 +2155,7 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 .It Cm GSSAPIRenewalForcesRekey If set to .Dq yes -@@ -1645,7 +1651,7 @@ +@@ -1600,7 +1606,7 @@ .Cm password ) . The default is: .Bd -literal -offset indent @@ -2198,10 +2164,10 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 keyboard-interactive,password .Ed .It Cm ProxyCommand -diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c ---- openssh-10.0p1.orig/sshconnect2.c 2025-06-14 08:24:55.591449573 +0200 -+++ openssh-10.0p1/sshconnect2.c 2025-06-14 08:25:50.335562288 +0200 -@@ -858,6 +858,11 @@ +diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c +--- openssh-9.9p1.orig/sshconnect2.c 2025-01-20 19:52:47.951052420 +0100 ++++ openssh-9.9p1/sshconnect2.c 2025-01-20 20:23:17.283730071 +0100 +@@ -855,6 +855,11 @@ gss_OID mech = NULL; char *gss_host = NULL; @@ -2213,7 +2179,7 @@ diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c if (options.gss_server_identity) { gss_host = xstrdup(options.gss_server_identity); } else if (options.gss_trust_dns) { -@@ -966,7 +971,8 @@ +@@ -963,7 +968,8 @@ if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ @@ -2223,7 +2189,7 @@ diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || (r = sshpkt_send(ssh)) != 0) -@@ -1133,6 +1139,20 @@ +@@ -1130,6 +1136,20 @@ return r; } @@ -2244,7 +2210,7 @@ diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c int userauth_gsskeyex(struct ssh *ssh) { -@@ -1155,6 +1175,12 @@ +@@ -1152,6 +1172,12 @@ if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -2257,7 +2223,7 @@ diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, "gssapi-keyex", ssh->kex->session_id); -@@ -1168,7 +1194,9 @@ +@@ -1165,7 +1191,9 @@ } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -2268,9 +2234,9 @@ diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || -diff -Nur openssh-10.0p1.orig/sshd.8 openssh-10.0p1/sshd.8 ---- openssh-10.0p1.orig/sshd.8 2025-06-14 08:24:55.024336971 +0200 -+++ openssh-10.0p1/sshd.8 2025-06-14 08:25:50.336280328 +0200 +diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8 +--- openssh-9.9p1.orig/sshd.8 2025-01-20 19:52:47.807052051 +0100 ++++ openssh-9.9p1/sshd.8 2025-01-20 20:23:17.283730071 +0100 @@ -840,6 +840,29 @@ # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W... @@ -2301,10 +2267,10 @@ diff -Nur openssh-10.0p1.orig/sshd.8 openssh-10.0p1/sshd.8 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.hushlogin -diff -Nur openssh-10.0p1.orig/sshd_config openssh-10.0p1/sshd_config ---- openssh-10.0p1.orig/sshd_config 2025-06-14 08:24:55.129477337 +0200 -+++ openssh-10.0p1/sshd_config 2025-06-14 08:25:50.336709644 +0200 -@@ -78,10 +78,11 @@ +diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config +--- openssh-9.9p1.orig/sshd_config 2025-01-20 19:52:47.826052099 +0100 ++++ openssh-9.9p1/sshd_config 2025-01-20 20:23:17.284730074 +0100 +@@ -76,10 +76,11 @@ #KerberosUseKuserok yes # GSSAPI options @@ -2318,7 +2284,7 @@ diff -Nur openssh-10.0p1.orig/sshd_config openssh-10.0p1/sshd_config #GSSAPIEnablek5users no # Set this to 'yes' to enable PAM authentication, account processing, -@@ -97,6 +98,10 @@ +@@ -95,6 +96,10 @@ # problems. #UsePAM no @@ -2329,9 +2295,9 @@ diff -Nur openssh-10.0p1.orig/sshd_config openssh-10.0p1/sshd_config #AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no -diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 ---- openssh-10.0p1.orig/sshd_config.5 2025-06-14 08:24:55.713605773 +0200 -+++ openssh-10.0p1/sshd_config.5 2025-06-14 08:25:50.337207823 +0200 +diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 +--- openssh-9.9p1.orig/sshd_config.5 2025-01-20 19:52:47.870052212 +0100 ++++ openssh-9.9p1/sshd_config.5 2025-01-20 20:23:17.284730074 +0100 @@ -724,15 +724,34 @@ to allow the client to select the address to which the forwarding is bound. The default is @@ -2377,7 +2343,7 @@ diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -2100,6 +2119,12 @@ +@@ -2041,6 +2060,12 @@ as a non-root user. The default is .Cm no . @@ -2390,9 +2356,9 @@ diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. -diff -Nur openssh-10.0p1.orig/sshd_config_redhat openssh-10.0p1/sshd_config_redhat ---- openssh-10.0p1.orig/sshd_config_redhat 2025-06-14 08:24:54.911947266 +0200 -+++ openssh-10.0p1/sshd_config_redhat 2025-06-14 08:25:50.337806574 +0200 +diff -Nur openssh-9.9p1.orig/sshd_config_redhat openssh-9.9p1/sshd_config_redhat +--- openssh-9.9p1.orig/sshd_config_redhat 2025-01-20 19:52:47.764051942 +0100 ++++ openssh-9.9p1/sshd_config_redhat 2025-01-20 20:23:17.285730077 +0100 @@ -2,9 +2,6 @@ KbdInteractiveAuthentication no @@ -2403,10 +2369,10 @@ diff -Nur openssh-10.0p1.orig/sshd_config_redhat openssh-10.0p1/sshd_config_redh UsePAM yes X11Forwarding yes -diff -Nur openssh-10.0p1.orig/sshd-session.c openssh-10.0p1/sshd-session.c ---- openssh-10.0p1.orig/sshd-session.c 2025-06-14 08:24:55.591819733 +0200 -+++ openssh-10.0p1/sshd-session.c 2025-06-14 08:25:50.338154455 +0200 -@@ -1448,7 +1448,7 @@ +diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c +--- openssh-9.9p1.orig/sshd-session.c 2025-01-20 19:52:47.968052463 +0100 ++++ openssh-9.9p1/sshd-session.c 2025-01-20 20:23:17.285730077 +0100 +@@ -1487,7 +1487,7 @@ #endif #ifdef GSSAPI @@ -2415,10 +2381,10 @@ diff -Nur openssh-10.0p1.orig/sshd-session.c openssh-10.0p1/sshd-session.c temporarily_use_uid(authctxt->pw); authctxt->krb5_set_env = ssh_gssapi_storecreds(); restore_uid(); -diff -Nur openssh-10.0p1.orig/ssh-gss.h openssh-10.0p1/ssh-gss.h ---- openssh-10.0p1.orig/ssh-gss.h 2025-06-14 08:24:55.713368522 +0200 -+++ openssh-10.0p1/ssh-gss.h 2025-06-14 08:25:50.338720590 +0200 -@@ -105,12 +105,14 @@ +diff -Nur openssh-9.9p1.orig/ssh-gss.h openssh-9.9p1/ssh-gss.h +--- openssh-9.9p1.orig/ssh-gss.h 2025-01-20 19:52:47.805052046 +0100 ++++ openssh-9.9p1/ssh-gss.h 2025-01-20 20:23:17.286730079 +0100 +@@ -99,12 +99,14 @@ } ssh_gssapi_ccache; typedef struct { @@ -2433,8 +2399,8 @@ diff -Nur openssh-10.0p1.orig/ssh-gss.h openssh-10.0p1/ssh-gss.h + gss_ctx_id_t context; /* needed for globus_gss_assist_map_and_authorize() */ int used; int updated; - char **indicators; /* auth indicators */ -@@ -132,7 +134,7 @@ + } ssh_gssapi_client; +@@ -125,7 +127,7 @@ OM_uint32 minor; /* both */ gss_ctx_id_t context; /* both */ gss_name_t name; /* both */ @@ -2443,7 +2409,7 @@ diff -Nur openssh-10.0p1.orig/ssh-gss.h openssh-10.0p1/ssh-gss.h gss_cred_id_t creds; /* server */ gss_name_t client; /* server */ gss_cred_id_t client_creds; /* both */ -@@ -179,6 +181,9 @@ +@@ -172,6 +174,9 @@ OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); int ssh_gssapi_credentials_updated(Gssctxt *); @@ -2453,12 +2419,12 @@ diff -Nur openssh-10.0p1.orig/ssh-gss.h openssh-10.0p1/ssh-gss.h /* In the server */ typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, const char *); -diff -Nur openssh-10.0p1.orig/version.h openssh-10.0p1/version.h ---- openssh-10.0p1.orig/version.h 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/version.h 2025-06-14 08:41:29.417798618 +0200 +diff -Nur openssh-9.9p1.orig/version.h openssh-9.9p1/version.h +--- openssh-9.9p1.orig/version.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/version.h 2025-01-20 20:23:17.286730079 +0100 @@ -2,5 +2,19 @@ - #define SSH_VERSION "OpenSSH_10.0" + #define SSH_VERSION "OpenSSH_9.9" +#ifdef GSI +#define GSI_VERSION " GSI" @@ -2472,7 +2438,7 @@ diff -Nur openssh-10.0p1.orig/version.h openssh-10.0p1/version.h +#define KRB5_VERSION "" +#endif + - #define SSH_PORTABLE "p2" + #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define GSI_PORTABLE "c-GSI" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ diff --git a/2001-openssh-10.0p1-hpn-18.7.0.patch b/openssh-9.9p1-hpn-18.6.0.patch similarity index 94% rename from 2001-openssh-10.0p1-hpn-18.7.0.patch rename to openssh-9.9p1-hpn-18.6.0.patch index 8349a52..da663c9 100644 --- a/2001-openssh-10.0p1-hpn-18.7.0.patch +++ b/openssh-9.9p1-hpn-18.6.0.patch @@ -1,6 +1,6 @@ -diff -Nur openssh-10.0p1.orig/auth2.c openssh-10.0p1/auth2.c ---- openssh-10.0p1.orig/auth2.c 2025-06-14 10:53:02.012331859 +0200 -+++ openssh-10.0p1/auth2.c 2025-06-14 11:42:37.929224784 +0200 +diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c +--- openssh-9.9p1.orig/auth2.c 2025-01-20 20:48:33.444582227 +0100 ++++ openssh-9.9p1/auth2.c 2025-01-20 21:54:08.570687857 +0100 @@ -52,6 +52,8 @@ #include "dispatch.h" #include "pathnames.h" @@ -41,9 +41,9 @@ diff -Nur openssh-10.0p1.orig/auth2.c openssh-10.0p1/auth2.c debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); #ifdef WITH_SELINUX -diff -Nur openssh-10.0p1.orig/binn.c openssh-10.0p1/binn.c ---- openssh-10.0p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/binn.c 2025-06-14 10:54:01.301771902 +0200 +diff -Nur openssh-9.9p1.orig/binn.c openssh-9.9p1/binn.c +--- openssh-9.9p1.orig/binn.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/binn.c 2025-01-20 20:50:04.564813761 +0100 @@ -0,0 +1,3541 @@ +#include +#include @@ -3586,9 +3586,9 @@ diff -Nur openssh-10.0p1.orig/binn.c openssh-10.0p1/binn.c +} + +/*************************************************************************************/ -diff -Nur openssh-10.0p1.orig/binn.h openssh-10.0p1/binn.h ---- openssh-10.0p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/binn.h 2025-06-14 10:54:01.303905629 +0200 +diff -Nur openssh-9.9p1.orig/binn.h openssh-9.9p1/binn.h +--- openssh-9.9p1.orig/binn.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/binn.h 2025-01-20 20:50:04.565813763 +0100 @@ -0,0 +1,945 @@ + +// TO ENABLE INLINE FUNCTIONS: @@ -4535,12 +4535,12 @@ diff -Nur openssh-10.0p1.orig/binn.h openssh-10.0p1/binn.h +#endif + +#endif //BINN_H -diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c ---- openssh-10.0p1.orig/channels.c 2025-06-14 10:53:01.614387370 +0200 -+++ openssh-10.0p1/channels.c 2025-06-14 11:44:14.886309096 +0200 -@@ -99,6 +99,11 @@ - /* Maximum number of fake X11 displays to try. */ - #define MAX_DISPLAYS 1000 +diff -Nur openssh-9.9p1.orig/channels.c openssh-9.9p1/channels.c +--- openssh-9.9p1.orig/channels.c 2025-01-20 20:48:33.373582047 +0100 ++++ openssh-9.9p1/channels.c 2025-01-20 21:55:22.938880541 +0100 +@@ -97,6 +97,11 @@ + /* Minimum port number for X11 forwarding */ + #define X11_PORT_MIN 6000 +/* in version of OpenSSH later than 8.8 if we advertise a window + * 16MB or larger is causes a pathological behaviour that reduces @@ -4550,7 +4550,7 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c /* Per-channel callback for pre/post IO actions */ typedef void chan_fn(struct ssh *, Channel *c); -@@ -227,6 +232,9 @@ +@@ -225,6 +230,9 @@ /* Setup helper */ static void channel_handler_init(struct ssh_channels *sc); @@ -4560,7 +4560,7 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c /* -- channel core */ void -@@ -521,6 +529,16 @@ +@@ -519,6 +527,16 @@ (c->output = sshbuf_new()) == NULL || (c->extended = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -4577,7 +4577,7 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0) fatal_fr(r, "sshbuf_set_max_size"); c->ostate = CHAN_OUTPUT_OPEN; -@@ -532,6 +550,7 @@ +@@ -530,6 +548,7 @@ c->local_window = window; c->local_window_max = window; c->local_maxpacket = maxpack; @@ -4585,7 +4585,7 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c c->remote_name = xstrdup(remote_name); c->ctl_chan = -1; c->delayed = 1; /* prevent call to channel_post handler */ -@@ -1259,6 +1278,33 @@ +@@ -1257,6 +1276,33 @@ c->io_want = SSH_CHAN_IO_SOCK_W; } @@ -4619,7 +4619,7 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c static void channel_pre_open(struct ssh *ssh, Channel *c) { -@@ -2366,18 +2412,29 @@ +@@ -2364,18 +2410,29 @@ c->local_maxpacket*3) || c->local_window < c->local_window_max/2) && c->local_consumed > 0) { @@ -4652,7 +4652,7 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c c->local_consumed = 0; } return 1; -@@ -2963,9 +3020,7 @@ +@@ -2961,9 +3018,7 @@ * in use. */ if (CHANNEL_EFD_INPUT_ACTIVE(c)) @@ -4663,7 +4663,7 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c else chan_ibuf_empty(ssh, c); } -@@ -3674,7 +3729,7 @@ +@@ -3672,7 +3727,7 @@ error_fr(r, "parse adjust"); ssh_packet_disconnect(ssh, "Invalid window adjust message"); } @@ -4672,7 +4672,7 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c if ((new_rwin = c->remote_window + adjust) < c->remote_window) { fatal("channel %d: adjust %u overflows remote window %u", c->self, adjust, c->remote_window); -@@ -3789,6 +3844,13 @@ +@@ -3787,6 +3842,13 @@ return addr; } @@ -4686,9 +4686,9 @@ diff -Nur openssh-10.0p1.orig/channels.c openssh-10.0p1/channels.c static int channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type, struct Forward *fwd, int *allocated_listen_port, -diff -Nur openssh-10.0p1.orig/channels.h openssh-10.0p1/channels.h ---- openssh-10.0p1.orig/channels.h 2025-06-14 10:53:01.467785388 +0200 -+++ openssh-10.0p1/channels.h 2025-06-14 10:54:01.306120024 +0200 +diff -Nur openssh-9.9p1.orig/channels.h openssh-9.9p1/channels.h +--- openssh-9.9p1.orig/channels.h 2025-01-20 20:48:33.343581971 +0100 ++++ openssh-9.9p1/channels.h 2025-01-20 20:50:04.567813768 +0100 @@ -175,6 +175,7 @@ u_int local_window_max; u_int local_consumed; @@ -4706,16 +4706,16 @@ diff -Nur openssh-10.0p1.orig/channels.h openssh-10.0p1/channels.h /* Maximum size for direct reads to buffers */ #define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT -@@ -399,4 +400,6 @@ +@@ -398,4 +399,6 @@ void chan_write_failed(struct ssh *, Channel *); void chan_obuf_empty(struct ssh *, Channel *); +/* hpn handler */ +void channel_set_hpn_disabled(int); #endif -diff -Nur openssh-10.0p1.orig/cipher.c openssh-10.0p1/cipher.c ---- openssh-10.0p1.orig/cipher.c 2025-06-14 10:53:01.716919856 +0200 -+++ openssh-10.0p1/cipher.c 2025-06-14 12:01:51.076334585 +0200 +diff -Nur openssh-9.9p1.orig/cipher.c openssh-9.9p1/cipher.c +--- openssh-9.9p1.orig/cipher.c 2025-01-20 20:48:33.392582095 +0100 ++++ openssh-9.9p1/cipher.c 2025-01-20 21:56:16.253016900 +0100 @@ -48,23 +48,39 @@ #include "sshbuf.h" #include "ssherr.h" @@ -5011,9 +5011,9 @@ diff -Nur openssh-10.0p1.orig/cipher.c openssh-10.0p1/cipher.c #endif freezero(cc, sizeof(*cc)); } -diff -Nur openssh-10.0p1.orig/cipher-chachapoly.c openssh-10.0p1/cipher-chachapoly.c ---- openssh-10.0p1.orig/cipher-chachapoly.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/cipher-chachapoly.c 2025-06-14 10:54:01.307925846 +0200 +diff -Nur openssh-9.9p1.orig/cipher-chachapoly.c openssh-9.9p1/cipher-chachapoly.c +--- openssh-9.9p1.orig/cipher-chachapoly.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/cipher-chachapoly.c 2025-01-20 20:50:04.569813773 +0100 @@ -88,7 +88,7 @@ if (!do_encrypt) { const u_char *tag = src + aadlen + len; @@ -5032,14 +5032,13 @@ diff -Nur openssh-10.0p1.orig/cipher-chachapoly.c openssh-10.0p1/cipher-chachapo poly_key); } r = 0; -diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c openssh-10.0p1/cipher-chachapoly-libcrypto.c ---- openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/cipher-chachapoly-libcrypto.c 2025-06-14 10:54:01.308400139 +0200 -@@ -34,8 +34,18 @@ +diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c openssh-9.9p1/cipher-chachapoly-libcrypto.c +--- openssh-9.9p1.orig/cipher-chachapoly-libcrypto.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/cipher-chachapoly-libcrypto.c 2025-01-20 21:59:09.157459134 +0100 +@@ -34,8 +34,17 @@ #include "ssherr.h" #include "cipher-chachapoly.h" -+ +/* using the EVP_MAC interface for poly1305 is significantly + * faster than the version bundled with OpenSSH. However, + * this interface is only available in OpenSSL 3.0+ @@ -5054,7 +5053,7 @@ diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c openssh-10.0p1/ciphe }; struct chachapoly_ctx * -@@ -56,6 +66,15 @@ +@@ -56,6 +65,15 @@ goto fail; if (EVP_CIPHER_CTX_iv_length(ctx->header_evp) != 16) goto fail; @@ -5070,7 +5069,7 @@ diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c openssh-10.0p1/ciphe return ctx; fail: chachapoly_free(ctx); -@@ -69,6 +88,9 @@ +@@ -69,6 +87,9 @@ return; EVP_CIPHER_CTX_free(cpctx->main_evp); EVP_CIPHER_CTX_free(cpctx->header_evp); @@ -5080,7 +5079,7 @@ diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c openssh-10.0p1/ciphe freezero(cpctx, sizeof(*cpctx)); } -@@ -107,7 +129,7 @@ +@@ -107,7 +128,7 @@ if (!do_encrypt) { const u_char *tag = src + aadlen + len; @@ -5089,7 +5088,7 @@ diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c openssh-10.0p1/ciphe if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) { r = SSH_ERR_MAC_INVALID; goto out; -@@ -133,7 +155,7 @@ +@@ -133,7 +154,7 @@ /* If encrypting, calculate and append tag */ if (do_encrypt) { @@ -5098,9 +5097,9 @@ diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto.c openssh-10.0p1/ciphe poly_key); } r = 0; -diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-10.0p1/cipher-chachapoly-libcrypto-mt.c ---- openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/cipher-chachapoly-libcrypto-mt.c 2025-06-14 10:54:01.309077322 +0200 +diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-9.9p1/cipher-chachapoly-libcrypto-mt.c +--- openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-chachapoly-libcrypto-mt.c 2025-01-20 20:50:04.570813776 +0100 @@ -0,0 +1,695 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -5797,9 +5796,9 @@ diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.c openssh-10.0p1/ci +#endif +} +#endif /* defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) */ -diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-10.0p1/cipher-chachapoly-libcrypto-mt.h ---- openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/cipher-chachapoly-libcrypto-mt.h 2025-06-14 10:54:01.309455724 +0200 +diff -Nur openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-9.9p1/cipher-chachapoly-libcrypto-mt.h +--- openssh-9.9p1.orig/cipher-chachapoly-libcrypto-mt.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-chachapoly-libcrypto-mt.h 2025-01-20 20:50:04.571813779 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -5846,9 +5845,9 @@ diff -Nur openssh-10.0p1.orig/cipher-chachapoly-libcrypto-mt.h openssh-10.0p1/ci + __attribute__((__bounded__(__buffer__, 4, 5))); + +#endif /* CHACHA_POLY_LIBCRYPTO_MT_H */ -diff -Nur openssh-10.0p1.orig/cipher-ctr-mt.c openssh-10.0p1/cipher-ctr-mt.c ---- openssh-10.0p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/cipher-ctr-mt.c 2025-06-14 10:54:01.309949084 +0200 +diff -Nur openssh-9.9p1.orig/cipher-ctr-mt.c openssh-9.9p1/cipher-ctr-mt.c +--- openssh-9.9p1.orig/cipher-ctr-mt.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-ctr-mt.c 2025-01-20 20:50:04.571813779 +0100 @@ -0,0 +1,677 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher @@ -6527,9 +6526,9 @@ diff -Nur openssh-10.0p1.orig/cipher-ctr-mt.c openssh-10.0p1/cipher-ctr-mt.c + return aes_ctr; +} +#endif /* OSSL Check */ -diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-functions.c openssh-10.0p1/cipher-ctr-mt-functions.c ---- openssh-10.0p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/cipher-ctr-mt-functions.c 2025-06-14 10:54:01.310535264 +0200 +diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-functions.c openssh-9.9p1/cipher-ctr-mt-functions.c +--- openssh-9.9p1.orig/cipher-ctr-mt-functions.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-ctr-mt-functions.c 2025-01-20 20:50:04.572813781 +0100 @@ -0,0 +1,668 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7199,9 +7198,9 @@ diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-functions.c openssh-10.0p1/cipher-ct +} + +#endif /*WITH_OPENSSL3*/ -diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-functions.h openssh-10.0p1/cipher-ctr-mt-functions.h ---- openssh-10.0p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/cipher-ctr-mt-functions.h 2025-06-14 10:54:01.310937760 +0200 +diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-functions.h openssh-9.9p1/cipher-ctr-mt-functions.h +--- openssh-9.9p1.orig/cipher-ctr-mt-functions.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-ctr-mt-functions.h 2025-01-20 20:50:04.572813781 +0100 @@ -0,0 +1,142 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7345,9 +7344,9 @@ diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-functions.h openssh-10.0p1/cipher-ct + +#endif /* WITH OPENSSL */ +#endif /* CTR_MT_FUNCS */ -diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-provider.c openssh-10.0p1/cipher-ctr-mt-provider.c ---- openssh-10.0p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/cipher-ctr-mt-provider.c 2025-06-14 10:54:01.311329711 +0200 +diff -Nur openssh-9.9p1.orig/cipher-ctr-mt-provider.c openssh-9.9p1/cipher-ctr-mt-provider.c +--- openssh-9.9p1.orig/cipher-ctr-mt-provider.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-ctr-mt-provider.c 2025-01-20 20:50:04.572813781 +0100 @@ -0,0 +1,390 @@ +/* + * OpenSSH Multi-threaded AES-CTR Cipher Provider for OpenSSL 3 @@ -7739,9 +7738,9 @@ diff -Nur openssh-10.0p1.orig/cipher-ctr-mt-provider.c openssh-10.0p1/cipher-ctr +} + +#endif /*WITH_OPENSSL3*/ -diff -Nur openssh-10.0p1.orig/cipher.h openssh-10.0p1/cipher.h ---- openssh-10.0p1.orig/cipher.h 2025-06-14 10:53:01.717078466 +0200 -+++ openssh-10.0p1/cipher.h 2025-06-14 13:45:10.880862884 +0200 +diff -Nur openssh-9.9p1.orig/cipher.h openssh-9.9p1/cipher.h +--- openssh-9.9p1.orig/cipher.h 2025-01-20 20:48:33.392582095 +0100 ++++ openssh-9.9p1/cipher.h 2025-01-20 20:59:21.957234646 +0100 @@ -42,11 +42,17 @@ #include #endif @@ -7798,9 +7797,9 @@ diff -Nur openssh-10.0p1.orig/cipher.h openssh-10.0p1/cipher.h u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); -diff -Nur openssh-10.0p1.orig/cipher-switch.c openssh-10.0p1/cipher-switch.c ---- openssh-10.0p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/cipher-switch.c 2025-06-14 10:54:01.312566045 +0200 +diff -Nur openssh-9.9p1.orig/cipher-switch.c openssh-9.9p1/cipher-switch.c +--- openssh-9.9p1.orig/cipher-switch.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-switch.c 2025-01-20 20:50:04.573813784 +0100 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 The Board of Trustees of Carnegie Mellon University. @@ -7875,9 +7874,9 @@ diff -Nur openssh-10.0p1.orig/cipher-switch.c openssh-10.0p1/cipher-switch.c + } +#endif +} -diff -Nur openssh-10.0p1.orig/cipher-switch.h openssh-10.0p1/cipher-switch.h ---- openssh-10.0p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/cipher-switch.h 2025-06-14 10:54:01.312822014 +0200 +diff -Nur openssh-9.9p1.orig/cipher-switch.h openssh-9.9p1/cipher-switch.h +--- openssh-9.9p1.orig/cipher-switch.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/cipher-switch.h 2025-01-20 20:50:04.574813786 +0100 @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 The Board of Trustees of Carnegie Mellon University. @@ -7897,9 +7896,9 @@ diff -Nur openssh-10.0p1.orig/cipher-switch.h openssh-10.0p1/cipher-switch.h + */ + +void cipher_switch (struct ssh *); -diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c ---- openssh-10.0p1.orig/clientloop.c 2025-06-14 10:53:01.223339310 +0200 -+++ openssh-10.0p1/clientloop.c 2025-06-14 10:54:01.313407565 +0200 +diff -Nur openssh-9.9p1.orig/clientloop.c openssh-9.9p1/clientloop.c +--- openssh-9.9p1.orig/clientloop.c 2025-01-20 20:48:33.290581837 +0100 ++++ openssh-9.9p1/clientloop.c 2025-01-20 20:50:04.575813789 +0100 @@ -114,6 +114,7 @@ #include "msg.h" #include "ssherr.h" @@ -7928,7 +7927,7 @@ diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c static void quit_message(const char *fmt, ...) __attribute__((__format__ (printf, 1, 2))); -@@ -1453,6 +1460,7 @@ +@@ -1452,6 +1459,7 @@ double start_time, total_time; int channel_did_enqueue = 0, r; u_int64_t ibytes, obytes; @@ -7936,7 +7935,7 @@ diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c int conn_in_ready, conn_out_ready; sigset_t bsigset, osigset; -@@ -1494,6 +1502,7 @@ +@@ -1493,6 +1501,7 @@ client_repledge(); start_time = monotime_double(); @@ -7944,7 +7943,7 @@ diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c /* Initialize variables. */ last_was_cr = 1; -@@ -1535,6 +1544,8 @@ +@@ -1534,6 +1543,8 @@ } schedule_server_alive_check(); @@ -7953,7 +7952,7 @@ diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGHUP) == -1 || -@@ -1545,6 +1556,12 @@ +@@ -1544,6 +1555,12 @@ /* Main loop of the client for the interactive session mode. */ while (!quit_pending) { @@ -7966,7 +7965,7 @@ diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c channel_did_enqueue = 0; /* Process buffered packets sent by the server. */ -@@ -1637,6 +1654,10 @@ +@@ -1636,6 +1653,10 @@ } } } @@ -7977,7 +7976,7 @@ diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c free(pfd); /* Terminate the session. */ -@@ -2648,6 +2669,167 @@ +@@ -2647,6 +2668,167 @@ return 1; } @@ -8145,7 +8144,7 @@ diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c static int client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) { -@@ -2773,6 +2955,43 @@ +@@ -2772,6 +2954,43 @@ len = sshbuf_len(cmd); if (len > 0) { @@ -8189,9 +8188,9 @@ diff -Nur openssh-10.0p1.orig/clientloop.c openssh-10.0p1/clientloop.c if (len > 900) len = 900; if (want_subsystem) { -diff -Nur openssh-10.0p1.orig/compat.c openssh-10.0p1/compat.c ---- openssh-10.0p1.orig/compat.c 2025-06-14 10:53:01.849953032 +0200 -+++ openssh-10.0p1/compat.c 2025-06-14 12:24:07.747714342 +0200 +diff -Nur openssh-9.9p1.orig/compat.c openssh-9.9p1/compat.c +--- openssh-9.9p1.orig/compat.c 2025-01-20 20:48:33.422582171 +0100 ++++ openssh-9.9p1/compat.c 2025-01-20 22:39:30.315877553 +0100 @@ -135,6 +135,35 @@ ssh->compat = check[i].bugs; if (forbid_ssh_rsa) @@ -8228,10 +8227,10 @@ diff -Nur openssh-10.0p1.orig/compat.c openssh-10.0p1/compat.c return; } } -diff -Nur openssh-10.0p1.orig/compat.h openssh-10.0p1/compat.h ---- openssh-10.0p1.orig/compat.h 2025-06-14 10:53:01.850139160 +0200 -+++ openssh-10.0p1/compat.h 2025-06-14 12:25:55.470697341 +0200 -@@ -46,17 +46,18 @@ +diff -Nur openssh-9.9p1.orig/compat.h openssh-9.9p1/compat.h +--- openssh-9.9p1.orig/compat.h 2025-01-20 20:48:33.423582174 +0100 ++++ openssh-9.9p1/compat.h 2025-01-20 22:36:35.778448062 +0100 +@@ -46,12 +46,12 @@ /* #define unused 0x00010000 */ /* #define unused 0x00020000 */ /* #define unused 0x00040000 */ @@ -8247,56 +8246,10 @@ diff -Nur openssh-10.0p1.orig/compat.h openssh-10.0p1/compat.h #define SSH_NEW_OPENSSH 0x04000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000 #define SSH_BUG_CURVE25519PAD 0x10000000 - #define SSH_BUG_HOSTKEYS 0x20000000 - #define SSH_BUG_DHGEX_LARGE 0x40000000 -+/* #define unused 0x80000000 */ - - struct ssh; - -diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac ---- openssh-10.0p1.orig/configure.ac 2025-06-14 10:53:02.015907743 +0200 -+++ openssh-10.0p1/configure.ac 2025-06-14 10:54:01.316233073 +0200 -@@ -2621,6 +2621,39 @@ - ) - fi - -+ -+# Testing MPTCP Support -+# Does the OS support MPTCP? -+# We don't use this at the moment -+# but I am holding it in resrve -cjr 04/04/2025 -+ AC_MSG_CHECKING([whether the OS supports MPTCP]) -+ AC_RUN_IFELSE( -+ [AC_LANG_PROGRAM([[ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ ]], [[ -+ int sock = -1; -+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); -+ if (sock < 0) { -+ exit(1); -+ } -+ ]])], -+ [ -+ AC_MSG_RESULT([yes]) -+ AC_DEFINE([HAVE_MPTCP], [1], -+ [OS Supports MPTCP]) -+ ], -+ [ -+ AC_MSG_RESULT([no]) -+ ] -+ ) -+ - if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ - test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then - AC_MSG_CHECKING([if getaddrinfo seems to work]) -@@ -3029,8 +3062,8 @@ +diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac +--- openssh-9.9p1.orig/configure.ac 2025-01-20 20:48:33.447582234 +0100 ++++ openssh-9.9p1/configure.ac 2025-01-20 20:50:04.577813794 +0100 +@@ -2945,8 +2945,8 @@ 200*) # LibreSSL lver=`echo "$sslver" | sed 's/.*libressl-//'` case "$lver" in @@ -8307,7 +8260,7 @@ diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac ;; *) ;; # Assume all other versions are good. esac -@@ -3039,6 +3072,7 @@ +@@ -2955,6 +2955,7 @@ # OpenSSL 3; we use the 1.1x API # https://openssl.org/policies/general/versioning-policy.html CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" @@ -8315,7 +8268,7 @@ diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac ;; *) AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_showver")]) -@@ -3158,6 +3192,29 @@ +@@ -3074,6 +3075,30 @@ EVP_CIPHER_CTX_set_iv \ ]) @@ -8341,42 +8294,26 @@ diff -Nur openssh-10.0p1.orig/configure.ac openssh-10.0p1/configure.ac + AC_MSG_RESULT([no]) + ] + ) ++ + if test "x$openssl_engine" = "xyes" ; then AC_MSG_CHECKING([for OpenSSL ENGINE support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -diff -Nur openssh-10.0p1.orig/defines.h openssh-10.0p1/defines.h ---- openssh-10.0p1.orig/defines.h 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/defines.h 2025-06-14 10:54:01.317208898 +0200 -@@ -931,7 +931,11 @@ +diff -Nur openssh-9.9p1.orig/defines.h openssh-9.9p1/defines.h +--- openssh-9.9p1.orig/defines.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/defines.h 2025-01-20 20:50:04.578813797 +0100 +@@ -889,7 +889,7 @@ #endif #ifndef SSH_IOBUFSZ -# define SSH_IOBUFSZ 8192 +# define SSH_IOBUFSZ (32*1024) -+#endif -+ -+#ifndef IPPROTO_MPTCP -+#define IPPROTO_MPTCP 262 #endif /* -@@ -987,3 +991,12 @@ - # define USE_MLKEM768X25519 1 - #endif - #endif /* _DEFINES_H */ -+ -+/* used to enable checking linux kernel versions */ -+#if defined(__linux__) && !defined(__alpine__) -+#include -+#endif -+ -+#ifndef KERNEL_VERSION /* shouldn't be necessary to define this */ -+#define KERNEL_VERSION(a,b,c) (((a) <<16) + ((b) << 8) +(c)) -+#endif -diff -Nur openssh-10.0p1.orig/digest.h openssh-10.0p1/digest.h ---- openssh-10.0p1.orig/digest.h 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/digest.h 2025-06-14 10:54:01.317584436 +0200 +diff -Nur openssh-9.9p1.orig/digest.h openssh-9.9p1/digest.h +--- openssh-9.9p1.orig/digest.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/digest.h 2025-01-20 20:50:04.578813797 +0100 @@ -27,7 +27,8 @@ #define SSH_DIGEST_SHA256 2 #define SSH_DIGEST_SHA384 3 @@ -8387,9 +8324,9 @@ diff -Nur openssh-10.0p1.orig/digest.h openssh-10.0p1/digest.h struct sshbuf; struct ssh_digest_ctx; -diff -Nur openssh-10.0p1.orig/digest-openssl.c openssh-10.0p1/digest-openssl.c ---- openssh-10.0p1.orig/digest-openssl.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/digest-openssl.c 2025-06-14 10:54:01.317859402 +0200 +diff -Nur openssh-9.9p1.orig/digest-openssl.c openssh-9.9p1/digest-openssl.c +--- openssh-9.9p1.orig/digest-openssl.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/digest-openssl.c 2025-01-20 20:50:04.578813797 +0100 @@ -61,6 +61,7 @@ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, @@ -8398,9 +8335,9 @@ diff -Nur openssh-10.0p1.orig/digest-openssl.c openssh-10.0p1/digest-openssl.c { -1, NULL, 0, NULL }, }; -diff -Nur openssh-10.0p1.orig/FUNDING.yml openssh-10.0p1/FUNDING.yml ---- openssh-10.0p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/FUNDING.yml 2025-06-14 10:54:01.318133600 +0200 +diff -Nur openssh-9.9p1.orig/FUNDING.yml openssh-9.9p1/FUNDING.yml +--- openssh-9.9p1.orig/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/FUNDING.yml 2025-01-20 20:50:04.578813797 +0100 @@ -0,0 +1,12 @@ +# These are supported funding model platforms + @@ -8414,22 +8351,12 @@ diff -Nur openssh-10.0p1.orig/FUNDING.yml openssh-10.0p1/FUNDING.yml +#issuehunt: # Replace with a single IssueHunt username +#otechie: # Replace with a single Otechie username +#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] -diff -Nur openssh-10.0p1.orig/HPN-README openssh-10.0p1/HPN-README ---- openssh-10.0p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/HPN-README 2025-06-14 10:54:01.318366032 +0200 -@@ -0,0 +1,180 @@ +diff -Nur openssh-9.9p1.orig/HPN-README openssh-9.9p1/HPN-README +--- openssh-9.9p1.orig/HPN-README 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/HPN-README 2025-01-20 20:50:04.578813797 +0100 +@@ -0,0 +1,170 @@ +Notes: + -+MPTCP Support in 18.7.0: -+Multipath TCP is now available as a runtime option for HPN-SSH. MPTCP -+is available only on Linux and Mac OSX operating systems. Using MPTCP on a system that -+doesn't support it will result in a notice and failure. The use cases for MPTCP include -+seamless handovers when changing networks and aggregating multiple interfaces to improve -+available bandwidth. As of 18.7.0 this options should be considered somewhat experimental. -+ -+Usage: -+-oUseMPTCP=[Yes|No] will enable MPTCP. The default is no. -+ +LibreSSL Support: +Changes in LibreSSL version 3.5 and 3.6 prevent the use of the threaded AES CTR cipher. +In those cases HPNSSH will fallback to the serial version of the AES CTR cipher. A warning @@ -8598,9 +8525,9 @@ diff -Nur openssh-10.0p1.orig/HPN-README openssh-10.0p1/HPN-README + + +Edited: October 11, 2023 -diff -Nur openssh-10.0p1.orig/HPNSSHInstallation.txt openssh-10.0p1/HPNSSHInstallation.txt ---- openssh-10.0p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/HPNSSHInstallation.txt 2025-06-14 10:54:01.318659925 +0200 +diff -Nur openssh-9.9p1.orig/HPNSSHInstallation.txt openssh-9.9p1/HPNSSHInstallation.txt +--- openssh-9.9p1.orig/HPNSSHInstallation.txt 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/HPNSSHInstallation.txt 2025-01-20 20:50:04.579813799 +0100 @@ -0,0 +1,354 @@ +HPN-SSH Installation + @@ -8956,9 +8883,9 @@ diff -Nur openssh-10.0p1.orig/HPNSSHInstallation.txt openssh-10.0p1/HPNSSHInstal +restorecon /usr/bin/hpnssh-agent +restorecon /usr/bin/hpnssh-keygen +restorecon /etc/pam.d/hpnsshd -diff -Nur openssh-10.0p1.orig/kex.c openssh-10.0p1/kex.c ---- openssh-10.0p1.orig/kex.c 2025-06-14 10:53:01.833082539 +0200 -+++ openssh-10.0p1/kex.c 2025-06-14 10:54:01.319010460 +0200 +diff -Nur openssh-9.9p1.orig/kex.c openssh-9.9p1/kex.c +--- openssh-9.9p1.orig/kex.c 2025-01-20 20:48:33.420582166 +0100 ++++ openssh-9.9p1/kex.c 2025-01-20 20:50:04.579813799 +0100 @@ -67,6 +67,7 @@ #include "ssherr.h" @@ -9176,32 +9103,9 @@ diff -Nur openssh-10.0p1.orig/kex.c openssh-10.0p1/kex.c mismatch = 0; switch (remote_major) { -diff -Nur openssh-10.0p1.orig/log.c openssh-10.0p1/log.c ---- openssh-10.0p1.orig/log.c 2025-06-14 10:53:01.364646329 +0200 -+++ openssh-10.0p1/log.c 2025-06-14 10:54:01.319781160 +0200 -@@ -48,6 +48,10 @@ - #include - #include - #include -+#include "packet.h" /* needed for host and port look ups */ -+#ifdef HAVE_SYS_TIME_H -+# include /* to get current time */ -+#endif - #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) - # include - #endif -@@ -67,6 +71,8 @@ - - extern char *__progname; - -+extern struct ssh *active_state; -+ - #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) - #define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) - -diff -Nur openssh-10.0p1.orig/mac.c openssh-10.0p1/mac.c ---- openssh-10.0p1.orig/mac.c 2025-06-14 10:53:01.717727014 +0200 -+++ openssh-10.0p1/mac.c 2025-06-14 10:54:01.320122336 +0200 +diff -Nur openssh-9.9p1.orig/mac.c openssh-9.9p1/mac.c +--- openssh-9.9p1.orig/mac.c 2025-01-20 20:48:33.394582100 +0100 ++++ openssh-9.9p1/mac.c 2025-01-20 20:50:04.580813802 +0100 @@ -63,6 +63,7 @@ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, @@ -9210,10 +9114,10 @@ diff -Nur openssh-10.0p1.orig/mac.c openssh-10.0p1/mac.c { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in ---- openssh-10.0p1.orig/Makefile.in 2025-06-14 14:54:57.417594122 +0200 -+++ openssh-10.0p1/Makefile.in 2025-06-14 14:54:42.451734455 +0200 -@@ -53,7 +53,7 @@ +diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in +--- openssh-9.9p1.orig/Makefile.in 2025-01-20 20:48:33.449582239 +0100 ++++ openssh-9.9p1/Makefile.in 2025-01-20 21:02:30.432714955 +0100 +@@ -51,7 +51,7 @@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ PICFLAG=@PICFLAG@ @@ -9222,7 +9126,7 @@ diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in CHANNELLIBS=@CHANNELLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ -@@ -102,7 +102,7 @@ +@@ -99,7 +99,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o \ canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ @@ -9231,7 +9135,7 @@ diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in compat.o fatal.o hostfile.o \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ -@@ -112,6 +112,7 @@ +@@ -109,6 +109,7 @@ 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 \ poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ @@ -9239,7 +9143,7 @@ diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in ssh-ed25519.o digest-openssl.o digest-libc.o \ hmac.o ed25519.o hash.o \ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ -@@ -119,12 +120,13 @@ +@@ -116,12 +117,13 @@ kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ @@ -9256,25 +9160,16 @@ diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in SSHDOBJS=sshd.o \ platform-listen.o \ @@ -143,7 +145,7 @@ - auth2-gss.o gss-serv.o gss-serv-krb5.o gss-serv-gsi.o \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ sftp-server.o sftp-common.o \ -- uidswap.o platform-listen.o $(SKOBJS) -+ uidswap.o platform-listen.o cipher-switch.o $(SKOBJS) - - SSHD_AUTH_OBJS=sshd-auth.o \ - auth2-methods.o \ -@@ -158,7 +160,7 @@ - sandbox-null.o sandbox-rlimit.o sandbox-darwin.o \ - sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-solaris.o \ - sftp-server.o sftp-common.o \ -- uidswap.o $(SKOBJS) -+ uidswap.o cipher-switch.o $(SKOBJS) + sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ +- sandbox-solaris.o uidswap.o $(SKOBJS) ++ sandbox-solaris.o uidswap.o cipher-switch.o $(SKOBJS) SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o -@@ -243,7 +245,7 @@ - $(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) +@@ -225,7 +227,7 @@ + $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) - $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -9282,10 +9177,10 @@ diff -Nur openssh-10.0p1.orig/Makefile.in openssh-10.0p1/Makefile.in ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS) $(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) -diff -Nur openssh-10.0p1.orig/metrics.c openssh-10.0p1/metrics.c ---- openssh-10.0p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/metrics.c 2025-06-14 10:54:01.321376410 +0200 -@@ -0,0 +1,439 @@ +diff -Nur openssh-9.9p1.orig/metrics.c openssh-9.9p1/metrics.c +--- openssh-9.9p1.orig/metrics.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/metrics.c 2025-01-20 20:50:04.581813804 +0100 +@@ -0,0 +1,444 @@ +/* + * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. + * @@ -9308,8 +9203,13 @@ diff -Nur openssh-10.0p1.orig/metrics.c openssh-10.0p1/metrics.c +#include "ssherr.h" +#include +#include ++#if defined(__linux__) && !defined(__alpine__) ++#include ++#endif + -+/* kernel version macro moved to defines.h */ ++#ifndef KERNEL_VERSION /* shouldn't be necessary to define this */ ++#define KERNEL_VERSION(a,b,c) (((a) <<16) + ((b) << 8) +(c)) ++#endif + +/* add the information from the tcp_info struct to the + * serialized binary object @@ -9725,9 +9625,9 @@ diff -Nur openssh-10.0p1.orig/metrics.c openssh-10.0p1/metrics.c +#endif /* ifdef __linux__ */ + fprintf(fptr, "\n\n"); +} -diff -Nur openssh-10.0p1.orig/metrics.h openssh-10.0p1/metrics.h ---- openssh-10.0p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/metrics.h 2025-06-14 10:54:01.321618830 +0200 +diff -Nur openssh-9.9p1.orig/metrics.h openssh-9.9p1/metrics.h +--- openssh-9.9p1.orig/metrics.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/metrics.h 2025-01-20 20:50:04.581813804 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 The Board of Trustees of Carnegie Mellon University. @@ -9774,9 +9674,9 @@ diff -Nur openssh-10.0p1.orig/metrics.h openssh-10.0p1/metrics.h + + +#endif /* define metrics_h */ -diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c ---- openssh-10.0p1.orig/misc.c 2025-06-14 10:53:02.019076801 +0200 -+++ openssh-10.0p1/misc.c 2025-06-14 10:54:01.321922850 +0200 +diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c +--- openssh-9.9p1.orig/misc.c 2025-01-20 20:48:33.449582239 +0100 ++++ openssh-9.9p1/misc.c 2025-01-20 20:50:04.582813807 +0100 @@ -77,6 +77,29 @@ #include "ssherr.h" #include "platform.h" @@ -9807,7 +9707,7 @@ diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c /* remove newline at end of string */ char * chop(char *s) -@@ -1670,20 +1693,6 @@ +@@ -1649,20 +1672,6 @@ return (v); } @@ -9828,7 +9728,7 @@ diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c u_int16_t get_u16(const void *vp) { -@@ -1723,17 +1732,6 @@ +@@ -1702,17 +1711,6 @@ } void @@ -9846,10 +9746,10 @@ diff -Nur openssh-10.0p1.orig/misc.c openssh-10.0p1/misc.c put_u16(void *vp, u_int16_t v) { u_char *p = (u_char *)vp; -diff -Nur openssh-10.0p1.orig/misc.h openssh-10.0p1/misc.h ---- openssh-10.0p1.orig/misc.h 2025-06-14 10:53:02.019622613 +0200 -+++ openssh-10.0p1/misc.h 2025-06-14 10:54:01.322621684 +0200 -@@ -167,12 +167,6 @@ +diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h +--- openssh-9.9p1.orig/misc.h 2025-01-20 20:48:33.450582242 +0100 ++++ openssh-9.9p1/misc.h 2025-01-20 20:50:04.582813807 +0100 +@@ -166,12 +166,6 @@ void put_u16(void *, u_int16_t) __attribute__((__bounded__( __minbytes__, 1, 2))); @@ -9862,7 +9762,7 @@ diff -Nur openssh-10.0p1.orig/misc.h openssh-10.0p1/misc.h struct bwlimit { size_t buflen; u_int64_t rate; /* desired rate in kbit/s */ -@@ -259,4 +253,16 @@ +@@ -258,4 +252,16 @@ /* On OpenBSD time_t is int64_t which is long long. */ /* #define SSH_TIME_T_MAX LLONG_MAX */ @@ -9879,20 +9779,22 @@ diff -Nur openssh-10.0p1.orig/misc.h openssh-10.0p1/misc.h +void read_mem_stats(struct statm_t *, int); + #endif /* _MISC_H */ -diff -Nur openssh-10.0p1.orig/myproposal.h openssh-10.0p1/myproposal.h ---- openssh-10.0p1.orig/myproposal.h 2025-06-14 10:53:01.775906378 +0200 -+++ openssh-10.0p1/myproposal.h 2025-06-14 10:54:01.323105546 +0200 -@@ -71,6 +71,7 @@ +diff -Nur openssh-9.9p1.orig/myproposal.h openssh-9.9p1/myproposal.h +--- openssh-9.9p1.orig/myproposal.h 2025-01-20 20:48:33.407582133 +0100 ++++ openssh-9.9p1/myproposal.h 2025-01-20 20:50:04.583813809 +0100 +@@ -71,7 +71,8 @@ "rsa-sha2-256" #define KEX_SERVER_ENCRYPT \ +- "chacha20-poly1305@openssh.com," \ + "chacha20-poly1305-mt@hpnssh.org," \ - "chacha20-poly1305@openssh.com," \ - "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \ - "aes128-ctr,aes192-ctr,aes256-ctr" -diff -Nur openssh-10.0p1.orig/num.c openssh-10.0p1/num.c ---- openssh-10.0p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/num.c 2025-06-14 10:54:01.323584938 +0200 ++ "chacha20-poly1305@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ + "aes128-gcm@openssh.com,aes256-gcm@openssh.com" + +diff -Nur openssh-9.9p1.orig/num.c openssh-9.9p1/num.c +--- openssh-9.9p1.orig/num.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/num.c 2025-01-20 20:50:04.583813809 +0100 @@ -0,0 +1,156 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10050,9 +9952,9 @@ diff -Nur openssh-10.0p1.orig/num.c openssh-10.0p1/num.c +implement_provnum(size_t, OSSL_PARAM_UNSIGNED_INTEGER) + +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-10.0p1.orig/num.h openssh-10.0p1/num.h ---- openssh-10.0p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/num.h 2025-06-14 10:54:01.323769040 +0200 +diff -Nur openssh-9.9p1.orig/num.h openssh-9.9p1/num.h +--- openssh-9.9p1.orig/num.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/num.h 2025-01-20 20:50:04.584813812 +0100 @@ -0,0 +1,15 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10069,9 +9971,9 @@ diff -Nur openssh-10.0p1.orig/num.h openssh-10.0p1/num.h +#define PROVNUM_E_TOOBIG -2 +#define PROVNUM_E_UNSUPPORTED -3 +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-10.0p1.orig/ossl3-provider-err.c openssh-10.0p1/ossl3-provider-err.c ---- openssh-10.0p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/ossl3-provider-err.c 2025-06-14 10:54:01.323964806 +0200 +diff -Nur openssh-9.9p1.orig/ossl3-provider-err.c openssh-9.9p1/ossl3-provider-err.c +--- openssh-9.9p1.orig/ossl3-provider-err.c 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/ossl3-provider-err.c 2025-01-20 20:50:04.584813812 +0100 @@ -0,0 +1,108 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10181,9 +10083,9 @@ diff -Nur openssh-10.0p1.orig/ossl3-provider-err.c openssh-10.0p1/ossl3-provider +} + +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-10.0p1.orig/ossl3-provider-err.h openssh-10.0p1/ossl3-provider-err.h ---- openssh-10.0p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/ossl3-provider-err.h 2025-06-14 10:54:01.324153727 +0200 +diff -Nur openssh-9.9p1.orig/ossl3-provider-err.h openssh-9.9p1/ossl3-provider-err.h +--- openssh-9.9p1.orig/ossl3-provider-err.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/ossl3-provider-err.h 2025-01-20 20:50:04.584813812 +0100 @@ -0,0 +1,73 @@ +/* CC0 license applied, see LICENCE.md */ + @@ -10258,9 +10160,9 @@ diff -Nur openssh-10.0p1.orig/ossl3-provider-err.h openssh-10.0p1/ossl3-provider +void proverr_set_error(const struct proverr_functions_st *handle, + uint32_t reason, const char *fmt, ...); +#endif /* WITH_OPENSSL3 */ -diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c ---- openssh-10.0p1.orig/packet.c 2025-06-14 10:53:01.719334626 +0200 -+++ openssh-10.0p1/packet.c 2025-06-14 10:54:01.324483728 +0200 +diff -Nur openssh-9.9p1.orig/packet.c openssh-9.9p1/packet.c +--- openssh-9.9p1.orig/packet.c 2025-01-20 20:48:33.396582105 +0100 ++++ openssh-9.9p1/packet.c 2025-01-20 20:50:04.585813814 +0100 @@ -63,6 +63,9 @@ #endif #include @@ -10406,17 +10308,20 @@ diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c - *max_blocks = (u_int64_t)1 << (enc->block_size*2); - else - *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; +- if (state->rekey_limit) +- *max_blocks = MINIMUM(*max_blocks, +- state->rekey_limit / enc->block_size); +- debug("rekey %s after %llu blocks", dir, +- (unsigned long long)*max_blocks); + + /* get the maximum number of blocks the cipher can + * handle safely */ + *max_blocks = cipher_rekey_blocks(enc->cipher); + + /* if we have a custom oRekeyLimit use that. */ - if (state->rekey_limit) - *max_blocks = MINIMUM(*max_blocks, - state->rekey_limit / enc->block_size); -- debug("rekey %s after %llu blocks", dir, -- (unsigned long long)*max_blocks); ++ if (state->rekey_limit) ++ *max_blocks = MINIMUM(*max_blocks, ++ state->rekey_limit / enc->block_size); + + /* these lines support the debug */ + strlcpy(blocks_s, "?", sizeof(blocks_s)); @@ -10465,6 +10370,17 @@ diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c /* Time-based rekeying */ if (state->rekey_interval != 0 && (int64_t)state->rekey_time + state->rekey_interval <= monotime()) +@@ -1293,8 +1373,8 @@ + sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) + goto out; + if ((r = cipher_crypt(state->send_context, state->p_send.seqnr, cp, +- sshbuf_ptr(state->outgoing_packet), +- len - aadlen, aadlen, authlen)) != 0) ++ sshbuf_ptr(state->outgoing_packet), len - aadlen, aadlen, authlen)) ++ != 0) + goto out; + /* append unencrypted MAC */ + if (mac && mac->enabled) { @@ -1445,7 +1525,7 @@ struct session_state *state = ssh->state; int len, r, ms_remain = 0; @@ -10533,7 +10449,7 @@ diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c } /* Remove MAC from input buffer */ DBG(debug("MAC #%d ok", state->p_read.seqnr)); -@@ -1938,7 +2018,7 @@ +@@ -1930,7 +2010,7 @@ int r; size_t rlen; @@ -10542,7 +10458,7 @@ diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c return r; if (state->packet_discard) { -@@ -2017,17 +2097,21 @@ +@@ -2009,17 +2089,21 @@ switch (r) { case SSH_ERR_CONN_CLOSED: ssh_packet_clear_keys(ssh); @@ -10564,7 +10480,7 @@ diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c logdie("Connection reset by %s", remote_id); } /* FALLTHROUGH */ -@@ -2069,6 +2153,24 @@ +@@ -2061,6 +2145,24 @@ logdie_f("should have exited"); } @@ -10589,7 +10505,7 @@ diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c /* * Logs the error plus constructs and sends a disconnect packet, closes the * connection, and exits. This function never returns. The error message -@@ -2323,10 +2425,19 @@ +@@ -2315,10 +2417,19 @@ ssh->kex->server = 1; /* XXX unify? */ } @@ -10609,7 +10525,7 @@ diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c } void * -@@ -2949,3 +3060,17 @@ +@@ -2941,3 +3052,17 @@ ssh->state->extra_pad = pad; return 0; } @@ -10627,9 +10543,9 @@ diff -Nur openssh-10.0p1.orig/packet.c openssh-10.0p1/packet.c +{ + return ssh->state->receive_context; +} -diff -Nur openssh-10.0p1.orig/packet.h openssh-10.0p1/packet.h ---- openssh-10.0p1.orig/packet.h 2025-06-14 10:53:01.719644792 +0200 -+++ openssh-10.0p1/packet.h 2025-06-14 10:54:01.325502017 +0200 +diff -Nur openssh-9.9p1.orig/packet.h openssh-9.9p1/packet.h +--- openssh-9.9p1.orig/packet.h 2025-01-20 20:48:33.397582108 +0100 ++++ openssh-9.9p1/packet.h 2025-01-20 20:50:04.585813814 +0100 @@ -88,6 +88,17 @@ /* APP data */ @@ -10671,9 +10587,9 @@ diff -Nur openssh-10.0p1.orig/packet.h openssh-10.0p1/packet.h /* new API */ int sshpkt_start(struct ssh *ssh, u_char type); -diff -Nur openssh-10.0p1.orig/poly1305.c openssh-10.0p1/poly1305.c ---- openssh-10.0p1.orig/poly1305.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/poly1305.c 2025-06-14 10:54:01.325842914 +0200 +diff -Nur openssh-9.9p1.orig/poly1305.c openssh-9.9p1/poly1305.c +--- openssh-9.9p1.orig/poly1305.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/poly1305.c 2025-01-20 20:50:04.586813817 +0100 @@ -13,6 +13,16 @@ #include "poly1305.h" @@ -10705,9 +10621,9 @@ diff -Nur openssh-10.0p1.orig/poly1305.c openssh-10.0p1/poly1305.c U32TO8_LE(&out[12], f3); } +#endif /* OPENSSL_HAVE_POLY_EVP */ -diff -Nur openssh-10.0p1.orig/poly1305.h openssh-10.0p1/poly1305.h ---- openssh-10.0p1.orig/poly1305.h 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/poly1305.h 2025-06-14 10:54:01.326132826 +0200 +diff -Nur openssh-9.9p1.orig/poly1305.h openssh-9.9p1/poly1305.h +--- openssh-9.9p1.orig/poly1305.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/poly1305.h 2025-01-20 20:50:04.586813817 +0100 @@ -13,8 +13,15 @@ #define POLY1305_KEYLEN 32 #define POLY1305_TAGLEN 16 @@ -10725,10 +10641,10 @@ diff -Nur openssh-10.0p1.orig/poly1305.h openssh-10.0p1/poly1305.h __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN))) __attribute__((__bounded__(__buffer__, 2, 3))) __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN))); -diff -Nur openssh-10.0p1.orig/progressmeter.c openssh-10.0p1/progressmeter.c ---- openssh-10.0p1.orig/progressmeter.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/progressmeter.c 2025-06-14 10:54:01.326416661 +0200 -@@ -65,6 +65,8 @@ +diff -Nur openssh-9.9p1.orig/progressmeter.c openssh-9.9p1/progressmeter.c +--- openssh-9.9p1.orig/progressmeter.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/progressmeter.c 2025-01-20 20:50:04.586813817 +0100 +@@ -66,6 +66,8 @@ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ static off_t cur_pos; /* transfer position as of last refresh */ @@ -10737,7 +10653,7 @@ diff -Nur openssh-10.0p1.orig/progressmeter.c openssh-10.0p1/progressmeter.c static volatile off_t *counter; /* progress counter */ static long stalled; /* how long we have been stalled */ static int bytes_per_second; /* current speed in bytes per second */ -@@ -131,6 +133,7 @@ +@@ -132,6 +134,7 @@ int cur_speed; int hours, minutes, seconds; int file_len, cols; @@ -10745,7 +10661,7 @@ diff -Nur openssh-10.0p1.orig/progressmeter.c openssh-10.0p1/progressmeter.c if ((!force_update && !alarm_fired && !win_resized) || !can_output()) return; -@@ -146,6 +149,10 @@ +@@ -147,6 +150,10 @@ now = monotime_double(); bytes_left = end_pos - cur_pos; @@ -10756,7 +10672,7 @@ diff -Nur openssh-10.0p1.orig/progressmeter.c openssh-10.0p1/progressmeter.c if (bytes_left > 0) elapsed = now - last_update; else { -@@ -175,7 +182,7 @@ +@@ -176,7 +183,7 @@ return; /* filename */ @@ -10765,7 +10681,7 @@ diff -Nur openssh-10.0p1.orig/progressmeter.c openssh-10.0p1/progressmeter.c if (file_len > 0) { asmprintf(&buf, INT_MAX, &cols, "%-*s", file_len, file); /* If we used fewer columns than expected then pad */ -@@ -192,6 +199,12 @@ +@@ -193,6 +200,12 @@ xextendf(&buf, NULL, " %3d%% %s %s/s ", percent, format_size(cur_pos), format_rate((off_t)bytes_per_second)); @@ -10778,7 +10694,7 @@ diff -Nur openssh-10.0p1.orig/progressmeter.c openssh-10.0p1/progressmeter.c /* ETA */ if (!transferred) stalled += elapsed; -@@ -234,6 +247,7 @@ +@@ -235,6 +248,7 @@ } free(buf); free(obuf); @@ -10786,36 +10702,35 @@ diff -Nur openssh-10.0p1.orig/progressmeter.c openssh-10.0p1/progressmeter.c } static void -diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c ---- openssh-10.0p1.orig/readconf.c 2025-06-14 10:53:02.021809909 +0200 -+++ openssh-10.0p1/readconf.c 2025-06-14 10:54:01.327045863 +0200 -@@ -71,6 +71,7 @@ - #include "uidswap.h" +diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c +--- openssh-9.9p1.orig/readconf.c 2025-01-20 20:48:33.452582247 +0100 ++++ openssh-9.9p1/readconf.c 2025-01-20 21:03:08.963813150 +0100 +@@ -72,6 +72,7 @@ #include "myproposal.h" #include "digest.h" -+#include "sshbuf.h" - #include "version.h" #include "ssh-gss.h" ++#include "sshbuf.h" -@@ -174,6 +175,10 @@ + /* Format of the configuration file: + +@@ -173,6 +174,10 @@ oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oRemoteCommand, + oTcpRcvBufPoll, oHPNDisabled, + oNoneEnabled, oNoneMacEnabled, oNoneSwitch, -+ oDisableMTAES, oUseMPTCP, ++ oDisableMTAES, + oMetrics, oMetricsPath, oMetricsInterval, oFallback, oFallbackPort, oVisualHostKey, oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull, oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass, -@@ -321,6 +326,16 @@ +@@ -319,6 +324,15 @@ { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, { "requesttty", oRequestTTY }, + { "noneenabled", oNoneEnabled }, + { "nonemacenabled", oNoneMacEnabled }, + { "noneswitch", oNoneSwitch }, -+ { "usemptcp", oUseMPTCP}, + { "disablemtaes", oDisableMTAES }, + { "metrics", oMetrics }, + { "metricspath", oMetricsPath }, @@ -10825,7 +10740,7 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c { "sessiontype", oSessionType }, { "stdinnull", oStdinNull }, { "forkafterauthentication", oForkAfterAuthentication }, -@@ -343,6 +358,8 @@ +@@ -341,6 +355,8 @@ { "proxyjump", oProxyJump }, { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, @@ -10834,7 +10749,7 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c { "requiredrsasize", oRequiredRSASize }, { "rsaminsize", oRequiredRSASize }, /* alias */ { "enableescapecommandline", oEnableEscapeCommandline }, -@@ -542,7 +559,7 @@ +@@ -539,7 +555,7 @@ if (port == 0) { sp = getservbyname(SSH_SERVICE_NAME, "tcp"); @@ -10843,7 +10758,7 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c } return port; } -@@ -1381,6 +1398,67 @@ +@@ -1317,6 +1333,63 @@ intptr = &options->check_host_ip; goto parse_flag; @@ -10863,10 +10778,6 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c + intptr = &options->nonemac_enabled; + goto parse_flag; + -+ case oUseMPTCP: -+ intptr = &options->use_mptcp; -+ goto parse_flag; -+ + case oDisableMTAES: + intptr = &options->disable_multithreaded; + goto parse_flag; @@ -10911,14 +10822,13 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; -@@ -2798,6 +2876,18 @@ +@@ -2712,6 +2785,17 @@ options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; + options->none_switch = -1; + options->none_enabled = -1; + options->nonemac_enabled = -1; -+ options->use_mptcp = -1; + options->disable_multithreaded = -1; + options->metrics = -1; + options->metrics_path = NULL; @@ -10930,7 +10840,7 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c options->session_type = -1; options->stdin_null = -1; options->fork_after_authentication = -1; -@@ -2982,8 +3072,39 @@ +@@ -2895,8 +2979,37 @@ options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; @@ -10953,8 +10863,6 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c + fprintf(stderr, "None MAC can only be used with the None cipher. None MAC disabled.\n"); + options->nonemac_enabled = 0; + } -+ if (options->use_mptcp == -1) -+ options->use_mptcp = 0; + if (options->disable_multithreaded == -1) + options->disable_multithreaded = 0; + if (options->metrics == -1) @@ -10970,49 +10878,23 @@ diff -Nur openssh-10.0p1.orig/readconf.c openssh-10.0p1/readconf.c if (options->control_persist == -1) { options->control_persist = 0; options->control_persist_timeout = 0; -@@ -3757,6 +3878,14 @@ - dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); - dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); - dump_cfg_fmtint(oEnableEscapeCommandline, o->enable_escape_commandline); -+ dump_cfg_fmtint(oTcpRcvBufPoll, o->tcp_rcv_buf_poll); -+ dump_cfg_fmtint(oHPNDisabled, o->hpn_disabled); -+ dump_cfg_fmtint(oNoneSwitch, o->none_switch); -+ dump_cfg_fmtint(oNoneEnabled, o->none_enabled); -+ dump_cfg_fmtint(oNoneMacEnabled, o->nonemac_enabled); -+ dump_cfg_fmtint(oFallback, o->fallback); -+ dump_cfg_fmtint(oMetrics, o->metrics); -+ - - /* Integer options */ - dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); -@@ -3768,6 +3897,8 @@ - dump_cfg_int(oRequiredRSASize, o->required_rsa_size); - dump_cfg_int(oObscureKeystrokeTiming, - o->obscure_keystroke_timing_interval); -+ dump_cfg_int(oMetricsInterval, o->metrics_interval); -+ dump_cfg_int(oFallbackPort, o->fallback_port); - - /* String options */ - dump_cfg_string(oBindAddress, o->bind_address); -@@ -3796,6 +3927,7 @@ - dump_cfg_string(oXAuthLocation, o->xauth_location); - dump_cfg_string(oKnownHostsCommand, o->known_hosts_command); - dump_cfg_string(oTag, o->tag); -+ dump_cfg_string(oMetricsPath, o->metrics_path); - dump_cfg_string(oVersionAddendum, o->version_addendum); - - /* Forwards */ -diff -Nur openssh-10.0p1.orig/readconf.h openssh-10.0p1/readconf.h ---- openssh-10.0p1.orig/readconf.h 2025-06-14 10:53:02.022395739 +0200 -+++ openssh-10.0p1/readconf.h 2025-06-14 10:54:01.328092159 +0200 -@@ -128,6 +128,21 @@ +diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h +--- openssh-9.9p1.orig/readconf.h 2025-01-20 20:48:33.452582247 +0100 ++++ openssh-9.9p1/readconf.h 2025-01-21 07:26:17.608445051 +0100 +@@ -56,6 +56,8 @@ + int strict_host_key_checking; /* Strict host key checking. */ + int compression; /* Compress packets in both directions. */ + int tcp_keep_alive; /* Set SO_KEEPALIVE. */ ++ int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ ++ int hpn_disabled; /* Switch to disable HPN buffer management */ + int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ + int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ + SyslogFacility log_facility; /* Facility for system logging. */ +@@ -129,6 +131,17 @@ int enable_ssh_keysign; int64_t rekey_limit; int rekey_interval; + -+ /* hpnssh options */ -+ int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ -+ int hpn_disabled; /* Switch to disable HPN buffer management */ + int none_switch; /* Use none cipher */ + int none_enabled; /* Allow none to be used */ + int nonemac_enabled; /* Allow none to be used */ @@ -11022,29 +10904,26 @@ diff -Nur openssh-10.0p1.orig/readconf.h openssh-10.0p1/readconf.h + char *metrics_path; /* path for the metrics files */ + int fallback; /* en|disable fallback port (def: true) */ + int fallback_port; /* port to fallback to (def: 22) */ -+ int use_mptcp; + int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; -diff -Nur openssh-10.0p1.orig/README.md openssh-10.0p1/README.md ---- openssh-10.0p1.orig/README.md 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/README.md 2025-06-14 10:54:01.328596415 +0200 -@@ -1,16 +1,22 @@ +diff -Nur openssh-9.9p1.orig/README.md openssh-9.9p1/README.md +--- openssh-9.9p1.orig/README.md 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/README.md 2025-01-20 20:50:04.588813822 +0100 +@@ -1,12 +1,16 @@ -# Portable OpenSSH +# HPNSSH: Based on Portable OpenSSH -[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml) -[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh) -[![Coverity Status](https://scan.coverity.com/projects/21341/badge.svg)](https://scan.coverity.com/projects/openssh-portable) -+HPN-SSH is a high performance soft fork of OpenSSH that can provide significnatly faster throughput for bulk data transfers over a wide range of network paths. In some situations we've seen throughput rates more than 100 times faster than OpenSSH. HPN-SSH is able to do this by optimizing the application layer receive buffer to match the TCP receive buffer. Notably, to see performance improvements HPN-SSH only needs to be the data receiver so users can see notable improvements with many other SSH implementations. HPN-SSH also incorporate two parallelized ciphers, AES-CTR and Chacha20 (the default). When using these ciphers a throughput performance increase of 30% is typical. More information on how we do this work and other features of HPN-SSH is available from [https://hpnssh.org](https://hpnssh.org). - --OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs. +Starting with version HPN17v0 there will be significant changes to the naming convention used for executables and installation locations. The last version that does not include these changes is HPN16v1 corresponding to the HPN-8_8_P1 tag on the master branch. --This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM). +-OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs. +HPNSSH is a variant of OpenSSH. It a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``hpnssh`` and server ``hpnsshd``, file transfer utilities ``hpnscp`` and ``hpnsftp`` as well as tools for key generation (``hpnssh-keygen``), run-time key storage (``hpnssh-agent``) and a number of supporting programs. It includes numerous performance and functionality enhancements focused on high performance networks and computing envrironments. Complete information can be found in the HPN-README file. -+ + +-This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM). +It is fully compatible with all compliant implementations of the SSH protocol and OpenSSH in particular. + +This version of HPNSSH is significant departure in terms of naming executables and installation locations. Specifically, all executables are now prefixed with ``hpn``. So ``ssh`` becomes ``hpnssh`` and ``scp`` is now ``hpnscp``. Configuation files and host keys can now be found in ``/etc/hpnssh``. By default ``hpnsshd`` now runs on port 2222 but this is configurable. This change was made in order to prevent installations of hpnssh, particularly from package distributions, from interfering with default installations of OpenSSH. HPNSSH is backwards compatible with all versions of OpenSSH including configuration files, keys, and run time options. Additionally, the client will, by default attempt to connect to port 2222 but will automatically fall back to port 22. This is also user configurable. @@ -11055,12 +10934,7 @@ diff -Nur openssh-10.0p1.orig/README.md openssh-10.0p1/README.md ## Documentation --The official documentation for OpenSSH are the man pages for each tool: -+The official documentation for OpenSSH are the man pages for each tool. - - * [ssh(1)](https://man.openbsd.org/ssh.1) - * [sshd(8)](https://man.openbsd.org/sshd.8) -@@ -21,15 +27,15 @@ +@@ -21,15 +25,15 @@ * [ssh-keyscan(8)](https://man.openbsd.org/ssh-keyscan.8) * [sftp-server(8)](https://man.openbsd.org/sftp-server.8) @@ -11080,8 +10954,8 @@ diff -Nur openssh-10.0p1.orig/README.md openssh-10.0p1/README.md ``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available. -@@ -44,8 +50,9 @@ - Release tarballs and release branches in git include a pre-built copy of the ``configure`` script and may be built using: +@@ -44,8 +48,9 @@ + Releases include a pre-built copy of the ``configure`` script and may be built using: ``` -tar zxvf openssh-X.YpZ.tar.gz @@ -11092,8 +10966,8 @@ diff -Nur openssh-10.0p1.orig/README.md openssh-10.0p1/README.md ./configure # [options] make && make tests ``` -@@ -57,9 +64,9 @@ - If building from the git master branch, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: +@@ -57,9 +62,9 @@ + If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: ``` -git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git @@ -11105,7 +10979,7 @@ diff -Nur openssh-10.0p1.orig/README.md openssh-10.0p1/README.md ./configure make && make tests ``` -@@ -76,6 +83,7 @@ +@@ -76,6 +81,7 @@ ``--with-libedit`` | Enable [libedit](https://www.thrysoee.dk/editline/) support for sftp. ``--with-kerberos5`` | Enable Kerberos/GSSAPI support. Both [Heimdal](https://www.h5l.org/) and [MIT](https://web.mit.edu/kerberos/) Kerberos implementations are supported. ``--with-selinux`` | Enable [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) support. @@ -11113,14 +10987,9 @@ diff -Nur openssh-10.0p1.orig/README.md openssh-10.0p1/README.md ## Development -@@ -84,3 +92,4 @@ - ## Reporting bugs - - _Non-security_ bugs may be reported to the developers via [Bugzilla](https://bugzilla.mindrot.org/) or via the mailing list above. Security bugs should be reported to [openssh@openssh.com](mailto:openssh.openssh.com). -+ -diff -Nur openssh-10.0p1.orig/sandbox-seccomp-filter.c openssh-10.0p1/sandbox-seccomp-filter.c ---- openssh-10.0p1.orig/sandbox-seccomp-filter.c 2025-06-14 10:53:01.776677219 +0200 -+++ openssh-10.0p1/sandbox-seccomp-filter.c 2025-06-14 10:54:01.328916358 +0200 +diff -Nur openssh-9.9p1.orig/sandbox-seccomp-filter.c openssh-9.9p1/sandbox-seccomp-filter.c +--- openssh-9.9p1.orig/sandbox-seccomp-filter.c 2025-01-20 20:48:33.408582135 +0100 ++++ openssh-9.9p1/sandbox-seccomp-filter.c 2025-01-20 20:50:04.589813825 +0100 @@ -295,6 +295,9 @@ #ifdef __NR_geteuid32 SC_ALLOW(__NR_geteuid32), @@ -11141,9 +11010,9 @@ diff -Nur openssh-10.0p1.orig/sandbox-seccomp-filter.c openssh-10.0p1/sandbox-se #ifdef __NR_time SC_ALLOW(__NR_time), #endif -diff -Nur openssh-10.0p1.orig/scp.1 openssh-10.0p1/scp.1 ---- openssh-10.0p1.orig/scp.1 2025-06-14 10:53:01.646933368 +0200 -+++ openssh-10.0p1/scp.1 2025-06-14 10:54:01.329403433 +0200 +diff -Nur openssh-9.9p1.orig/scp.1 openssh-9.9p1/scp.1 +--- openssh-9.9p1.orig/scp.1 2025-01-20 20:48:33.380582065 +0100 ++++ openssh-9.9p1/scp.1 2025-01-20 22:18:33.595608452 +0100 @@ -18,7 +18,7 @@ .Nd OpenSSH secure file copy .Sh SYNOPSIS @@ -11153,35 +11022,17 @@ diff -Nur openssh-10.0p1.orig/scp.1 openssh-10.0p1/scp.1 .Op Fl c Ar cipher .Op Fl D Ar sftp_server_path .Op Fl F Ar ssh_config -@@ -33,6 +33,8 @@ - .Sh DESCRIPTION - .Nm - copies files between hosts on a network. -+It is binary compatible with OpenSSH's scp including -+the use of the same directives and configuration options except where noted. - .Pp - .Nm - uses the SFTP protocol over a -@@ -257,6 +259,7 @@ - .It Tunnel - .It TunnelDevice - .It UpdateHostKeys -+.It UseMPTCP - .It User - .It UserKnownHostsFile - .It VerifyHostKeyDNS -@@ -291,6 +294,10 @@ +@@ -252,6 +252,9 @@ Note that .Nm follows symbolic links encountered in the tree traversal. +.It Fl Z +Resume failed or interrupted transfer. Identical files will be skipped. Remote must have resume option. -+.Nm -+only option. ++HPN-SSH only option. .It Fl S Ar program Name of .Ar program -@@ -298,6 +305,14 @@ +@@ -259,6 +262,13 @@ The program must understand .Xr ssh 1 options. @@ -11189,14 +11040,13 @@ diff -Nur openssh-10.0p1.orig/scp.1 openssh-10.0p1/scp.1 +Path to hpnscp on remote system. Useful if remote has multiple scp installs. +For example, using the resume option but the default remote scp does not have the resume option. +Use -z to point the version that does - e.g. -z /opt/hpnssh/bin/hpnscp. -+.Nm -+only option. ++HPN-SSH only option. +.It Fl s +Use the SFTP protocol for transfers rather than the original scp protocol. .It Fl T Disable strict filename checking. By default when copying files from a remote host to a local directory -@@ -324,10 +339,13 @@ +@@ -285,10 +295,13 @@ .It Cm nrequests Ns = Ns Ar value Controls how many concurrent SFTP read or write requests may be in progress at any point in time during a download or upload. @@ -11211,7 +11061,7 @@ diff -Nur openssh-10.0p1.orig/scp.1 openssh-10.0p1/scp.1 By default a 32KB buffer is used. .El .El -@@ -361,6 +379,7 @@ +@@ -322,6 +335,7 @@ .Sh AUTHORS .An Timo Rinne Aq Mt tri@iki.fi .An Tatu Ylonen Aq Mt ylo@cs.hut.fi @@ -11219,9 +11069,9 @@ diff -Nur openssh-10.0p1.orig/scp.1 openssh-10.0p1/scp.1 .Sh CAVEATS The legacy SCP protocol (selected by the .Fl O -diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c ---- openssh-10.0p1.orig/scp.c 2025-06-14 10:53:01.663335155 +0200 -+++ openssh-10.0p1/scp.c 2025-06-14 12:35:32.946245567 +0200 +diff -Nur openssh-9.9p1.orig/scp.c openssh-9.9p1/scp.c +--- openssh-9.9p1.orig/scp.c 2025-01-20 20:48:33.382582070 +0100 ++++ openssh-9.9p1/scp.c 2025-01-21 07:44:00.216159475 +0100 @@ -17,6 +17,7 @@ /* * Copyright (c) 1999 Theo de Raadt. All rights reserved. @@ -11310,7 +11160,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c /* Copy argv, because we modify it */ argv0 = argv[0]; newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv)); -@@ -509,7 +543,7 @@ +@@ -508,7 +542,7 @@ fflag = Tflag = tflag = 0; while ((ch = getopt(argc, argv, @@ -11319,7 +11169,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c switch (ch) { /* User-visible flags. */ case '1': -@@ -590,24 +624,36 @@ +@@ -589,24 +623,36 @@ addargs(&remote_remote_args, "-q"); showprogress = 0; break; @@ -11343,9 +11193,8 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c } if (r == -1) { - fatal("Invalid buffer size \"%s\": %s", -- optarg + 7, strerror(errno)); -+ fatal("Invalid buffer size. Must be between 1B and 255KB." -+ "\"%s\": %s", optarg + 7, strerror(errno)); ++ fatal("Invalid buffer size. Must be between 1B and 255KB. \"%s\": %s", + optarg + 7, strerror(errno)); } sftp_copy_buflen = (size_t)llv; } else if (strncmp(optarg, "nrequests=", 10) == 0) { @@ -11361,32 +11210,30 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c "\"%s\": %s", optarg + 10, errstr); } sftp_nrequests = (size_t)llv; -@@ -695,11 +741,20 @@ +@@ -694,11 +740,20 @@ remin = remout = -1; do_cmd_pid = -1; /* Command to be executed on remote system using "ssh". */ - (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", -- verbose_mode ? " -v" : "", -- iamrecursive ? " -r" : "", pflag ? " -p" : "", -- targetshouldbedirectory ? " -d" : ""); + /* In the event of an hpn to hpn connection the scp + * command is rewritten to hpnscp. This happens in + * clientloop.c -cjr 12/12/2022 */ - ++ + (void) snprintf(cmd, sizeof cmd, "%s%s%s%s%s%s", + remote_path ? remote_path : "scp", -+ verbose_mode ? " -v" : "", -+ iamrecursive ? " -r" : "", -+ pflag ? " -p" : "", + verbose_mode ? " -v" : "", + iamrecursive ? " -r" : "", pflag ? " -p" : "", +- targetshouldbedirectory ? " -d" : ""); + targetshouldbedirectory ? " -d" : "", + resume_flag ? " -Z" : ""); + +#ifdef DEBUG + fprintf(stderr, "%s: Sending cmd %s\n", hostname, cmd); +#endif (void) ssh_signal(SIGPIPE, lostconn); if (colon(argv[argc - 1])) /* Dest is remote host. */ -@@ -1324,6 +1379,74 @@ +@@ -1323,6 +1378,74 @@ free(src); } @@ -11461,7 +11308,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c /* Prepare remote path, handling ~ by assuming cwd is the homedir */ static char * prepare_remote_path(struct sftp_conn *conn, const char *path) -@@ -1407,14 +1530,23 @@ +@@ -1406,14 +1529,23 @@ struct stat stb; static BUF buffer; BUF *bp; @@ -11487,7 +11334,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c statbytes = 0; len = strlen(name); while (len > 1 && name[len-1] == '/') -@@ -1436,6 +1568,14 @@ +@@ -1435,6 +1567,14 @@ unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: @@ -11502,7 +11349,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c break; case S_IFDIR: if (iamrecursive) { -@@ -1457,14 +1597,133 @@ +@@ -1456,14 +1596,133 @@ goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) @@ -11514,12 +11361,12 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c + /* Add a hash of the file along with the filemode if in resume */ + if (resume_flag) + snprintf(buf, sizeof buf, "C%04o %lld %s %s\n", -+ (u_int) (stb.st_mode & FILEMODEMASK), -+ (long long)stb.st_size, hashsum, last); ++ (u_int) (stb.st_mode & FILEMODEMASK), ++ (long long)stb.st_size, hashsum, last); + else + snprintf(buf, sizeof buf, "C%04o %lld %s\n", -+ (u_int) (stb.st_mode & FILEMODEMASK), -+ (long long)stb.st_size, last); ++ (u_int) (stb.st_mode & FILEMODEMASK), ++ (long long)stb.st_size, last); + +#ifdef DEBUG + fprintf(stderr, "%s: Sending file modes: %s", hostname, buf); @@ -11642,7 +11489,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { next: if (fd != -1) { (void) close(fd); -@@ -1472,13 +1731,17 @@ +@@ -1471,13 +1730,17 @@ } continue; } @@ -11664,7 +11511,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if (!haderr) { if ((nr = atomicio(read, fd, bp->buf, amt)) != amt) { -@@ -1675,24 +1938,35 @@ +@@ -1674,24 +1937,36 @@ sink(int argc, char **argv, const char *src) { static BUF buffer; @@ -11692,18 +11539,19 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c + int bad_match_flag = 0; + np = NULL; /* this was originally '/0' but that's wrong */ + np_tmp = NULL; ++ #define atime tv[0] #define mtime tv[1] #define SCREWUP(str) { why = str; goto screwup; } +#ifdef DEBUG -+ fprintf (stderr, "%s: LOCAL In sink with %s\n", hostname, src); ++ fprintf (stderr, "%s: LOCAL In sink with %s\n", hostname, src); +#endif if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0)) SCREWUP("Unexpected off_t/time_t size"); -@@ -1708,9 +1982,16 @@ +@@ -1707,9 +1982,16 @@ if (targetshouldbedirectory) verifydir(targ); @@ -11720,7 +11568,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if (src != NULL && !iamrecursive && !Tflag) { /* * Prepare to try to restrict incoming filenames to match -@@ -1720,6 +2001,10 @@ +@@ -1719,6 +2001,10 @@ fatal_f("could not expand pattern"); } for (first = 1;; first = 0) { @@ -11731,7 +11579,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c cp = buf; if (atomicio(read, remin, cp, 1) != 1) goto done; -@@ -1747,6 +2032,9 @@ +@@ -1746,6 +2032,9 @@ continue; } if (buf[0] == 'E') { @@ -11741,7 +11589,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c (void) atomicio(vwrite, remout, "", 1); goto done; } -@@ -1754,6 +2042,9 @@ +@@ -1753,6 +2042,9 @@ *--cp = 0; cp = buf; @@ -11751,7 +11599,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if (*cp == 'T') { setimes++; cp++; -@@ -1781,9 +2072,19 @@ +@@ -1780,9 +2072,19 @@ if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || atime.tv_usec > 999999) SCREWUP("atime.usec not delimited"); @@ -11771,7 +11619,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if (*cp != 'C' && *cp != 'D') { /* * Check for the case "rcp remote:foo\* local:bar". -@@ -1799,6 +2100,18 @@ +@@ -1798,6 +2100,18 @@ SCREWUP("expected control record"); } mode = 0; @@ -11790,7 +11638,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c for (++cp; cp < buf + 5; cp++) { if (*cp < '0' || *cp > '7') SCREWUP("bad mode"); -@@ -1809,6 +2122,10 @@ +@@ -1808,6 +2122,10 @@ if (*cp++ != ' ') SCREWUP("mode not delimited"); @@ -11801,7 +11649,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if (!isdigit((unsigned char)*cp)) SCREWUP("size not present"); ull = strtoull(cp, &cp, 10); -@@ -1818,11 +2135,32 @@ +@@ -1817,11 +2135,32 @@ SCREWUP("size out of range"); size = (off_t)ull; @@ -11834,7 +11682,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if (npatterns > 0) { for (n = 0; n < npatterns; n++) { if (strcmp(patterns[n], cp) == 0 || -@@ -1892,11 +2230,195 @@ +@@ -1891,11 +2230,195 @@ } omode = mode; mode |= S_IWUSR; @@ -12031,7 +11879,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { (void) close(ofd); continue; -@@ -1911,13 +2433,17 @@ +@@ -1910,13 +2433,17 @@ */ statbytes = 0; if (showprogress) @@ -12053,7 +11901,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c do { j = atomicio6(read, remin, cp, amt, scpio, &statbytes); -@@ -1952,8 +2478,78 @@ +@@ -1951,8 +2478,78 @@ wrerr = 1; } if (!wrerr && (!exists || S_ISREG(stb.st_mode)) && @@ -12133,7 +11981,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c if (pflag) { if (exists || omode != mode) #ifdef HAVE_FCHMOD -@@ -1988,8 +2584,17 @@ +@@ -1987,8 +2584,17 @@ } } /* If no error was noted then signal success for this file */ @@ -12152,7 +12000,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c } done: for (n = 0; n < npatterns; n++) -@@ -2133,11 +2738,20 @@ +@@ -2132,11 +2738,20 @@ void usage(void) { @@ -12173,7 +12021,7 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c } void -@@ -2276,6 +2890,18 @@ +@@ -2275,6 +2890,18 @@ exit(1); } @@ -12192,10 +12040,10 @@ diff -Nur openssh-10.0p1.orig/scp.c openssh-10.0p1/scp.c void cleanup_exit(int i) { -diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c ---- openssh-10.0p1.orig/servconf.c 2025-06-14 10:53:02.022835252 +0200 -+++ openssh-10.0p1/servconf.c 2025-06-14 12:36:43.529579310 +0200 -@@ -217,6 +217,12 @@ +diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c +--- openssh-9.9p1.orig/servconf.c 2025-01-20 20:48:33.453582249 +0100 ++++ openssh-9.9p1/servconf.c 2025-01-20 22:27:14.328008145 +0100 +@@ -215,6 +215,11 @@ options->authorized_principals_file = NULL; options->authorized_principals_command = NULL; options->authorized_principals_command_user = NULL; @@ -12203,12 +12051,11 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c + options->hpn_disabled = -1; + options->none_enabled = -1; + options->nonemac_enabled = -1; -+ options->use_mptcp = -1; + options->disable_multithreaded = -1; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; -@@ -511,6 +517,22 @@ +@@ -508,6 +513,18 @@ } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; @@ -12220,27 +12067,23 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c + debug ("Attempted to enabled None MAC without setting None Enabled to true. None MAC disabled."); + options->nonemac_enabled = 0; + } -+ if (options->tcp_rcv_buf_poll == -1) -+ options->tcp_rcv_buf_poll = 1; + if (options->disable_multithreaded == -1) + options->disable_multithreaded = 0; + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; -+ if (options->use_mptcp == -1) -+ options->use_mptcp = 0; if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) -@@ -595,6 +617,8 @@ +@@ -590,6 +607,8 @@ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sNoneEnabled, sNoneMacEnabled, sTcpRcvBufPoll, sHPNDisabled, -+ sDisableMTAES, sUseMPTCP, ++ sDisableMTAES, sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, -@@ -804,6 +828,12 @@ +@@ -797,6 +816,11 @@ { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, @@ -12248,12 +12091,11 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c + { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, + { "noneenabled", sNoneEnabled, SSHCFG_ALL }, + { "nonemacenabled", sNoneMacEnabled, SSHCFG_ALL }, -+ { "usemptcp", sUseMPTCP, SSHCFG_GLOBAL }, + { "disableMTAES", sDisableMTAES, SSHCFG_ALL }, { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "include", sInclude, SSHCFG_ALL }, { "ipqos", sIPQoS, SSHCFG_ALL }, -@@ -869,6 +899,7 @@ +@@ -861,6 +885,7 @@ for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { @@ -12261,7 +12103,7 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c *flags = keywords[i].flags; return keywords[i].opcode; } -@@ -1640,6 +1671,30 @@ +@@ -1593,12 +1618,32 @@ multistate_ptr = multistate_ignore_rhosts; goto parse_multistate; @@ -12273,6 +12115,12 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c + intptr = &options->hpn_disabled; + goto parse_flag; + + case sIgnoreUserKnownHosts: + intptr = &options->ignore_user_known_hosts; + parse_flag: + multistate_ptr = multistate_flag; + goto parse_multistate; + + case sNoneEnabled: + intptr = &options->none_enabled; + goto parse_flag; @@ -12285,45 +12133,28 @@ diff -Nur openssh-10.0p1.orig/servconf.c openssh-10.0p1/servconf.c + intptr = &options->disable_multithreaded; + goto parse_flag; + -+ case sUseMPTCP: -+ intptr = &options->use_mptcp; -+ goto parse_flag; -+ - case sIgnoreUserKnownHosts: - intptr = &options->ignore_user_known_hosts; - parse_flag: -@@ -3434,6 +3489,11 @@ - dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); - dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); - dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); -+ dump_cfg_fmtint(sHPNDisabled, o->hpn_disabled); -+ dump_cfg_fmtint(sTcpRcvBufPoll, o->tcp_rcv_buf_poll); -+ dump_cfg_fmtint(sNoneEnabled, o->none_enabled); -+ dump_cfg_fmtint(sNoneMacEnabled, o->nonemac_enabled); -+ dump_cfg_fmtint(sUseMPTCP, o->use_mptcp); - dump_cfg_fmtint(sRefuseConnection, o->refuse_connection); - - /* string arguments */ -diff -Nur openssh-10.0p1.orig/servconf.h openssh-10.0p1/servconf.h ---- openssh-10.0p1.orig/servconf.h 2025-06-14 10:53:02.023331755 +0200 -+++ openssh-10.0p1/servconf.h 2025-06-14 10:54:01.332534777 +0200 -@@ -227,6 +227,13 @@ + case sHostbasedAuthentication: + intptr = &options->hostbased_authentication; + goto parse_flag; +diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h +--- openssh-9.9p1.orig/servconf.h 2025-01-20 20:48:33.453582249 +0100 ++++ openssh-9.9p1/servconf.h 2025-01-20 22:28:39.829229874 +0100 +@@ -226,6 +226,12 @@ char *pam_service_name; int permit_pam_user_change; /* Allow PAM to change user name */ -+ /* hpnssh options */ + int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ + int hpn_disabled; /* disable hpn functionality. false by default */ + int none_enabled; /* Enable NONE cipher switch */ + int nonemac_enabled; /* Enable NONE MAC switch */ -+ int use_mptcp; /* Use MPTCP - Linux only */ -+ int disable_multithreaded; /* Disable multithreaded aes-ctr cipher */ ++ int disable_multithreaded; /* Disable multithreaded aes-ctr cipher */ ++ int permit_tun; char **permitted_opens; /* May also be one of PERMITOPEN_* */ -diff -Nur openssh-10.0p1.orig/serverloop.c openssh-10.0p1/serverloop.c ---- openssh-10.0p1.orig/serverloop.c 2025-06-14 10:53:01.992010916 +0200 -+++ openssh-10.0p1/serverloop.c 2025-06-14 12:39:09.690199658 +0200 +diff -Nur openssh-9.9p1.orig/serverloop.c openssh-9.9p1/serverloop.c +--- openssh-9.9p1.orig/serverloop.c 2025-01-20 20:48:33.440582216 +0100 ++++ openssh-9.9p1/serverloop.c 2025-01-20 22:30:36.463532350 +0100 @@ -81,6 +81,8 @@ #include "serverloop.h" #include "ssherr.h" @@ -12445,9 +12276,9 @@ diff -Nur openssh-10.0p1.orig/serverloop.c openssh-10.0p1/serverloop.c } /* XXX sshpkt_get_end() */ if (want_reply) { -diff -Nur openssh-10.0p1.orig/session.c openssh-10.0p1/session.c ---- openssh-10.0p1.orig/session.c 2025-06-14 10:53:01.741334418 +0200 -+++ openssh-10.0p1/session.c 2025-06-14 10:54:01.333888095 +0200 +diff -Nur openssh-9.9p1.orig/session.c openssh-9.9p1/session.c +--- openssh-9.9p1.orig/session.c 2025-01-20 20:48:33.402582120 +0100 ++++ openssh-9.9p1/session.c 2025-01-20 20:50:04.595813840 +0100 @@ -94,6 +94,7 @@ #include "monitor_wrap.h" #include "sftp.h" @@ -12484,20 +12315,10 @@ diff -Nur openssh-10.0p1.orig/session.c openssh-10.0p1/session.c return 0; } -diff -Nur openssh-10.0p1.orig/sftp.1 openssh-10.0p1/sftp.1 ---- openssh-10.0p1.orig/sftp.1 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/sftp.1 2025-06-14 10:54:01.334573170 +0200 -@@ -55,6 +55,9 @@ - transport. - It may also use many features of ssh, such as public key authentication and - compression. -+.Nm -+is binary compatible with OpenSSH's sftp and uses the same directive and configuration -+options except where noted. - .Pp - The - .Ar destination -@@ -338,7 +341,8 @@ +diff -Nur openssh-9.9p1.orig/sftp.1 openssh-9.9p1/sftp.1 +--- openssh-9.9p1.orig/sftp.1 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/sftp.1 2025-01-20 20:50:04.595813840 +0100 +@@ -299,7 +299,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. @@ -12507,7 +12328,7 @@ diff -Nur openssh-10.0p1.orig/sftp.1 openssh-10.0p1/sftp.1 .It Fl r Recursively copy entire directories when uploading and downloading. Note that -@@ -367,10 +371,13 @@ +@@ -328,10 +329,13 @@ .It Cm nrequests Ns = Ns Ar value Controls how many concurrent SFTP read or write requests may be in progress at any point in time during a download or upload. @@ -12522,10 +12343,10 @@ diff -Nur openssh-10.0p1.orig/sftp.1 openssh-10.0p1/sftp.1 By default a 32KB buffer is used. .El .El -diff -Nur openssh-10.0p1.orig/sftp.c openssh-10.0p1/sftp.c ---- openssh-10.0p1.orig/sftp.c 2025-06-14 10:53:01.664429990 +0200 -+++ openssh-10.0p1/sftp.c 2025-06-14 10:54:01.335020156 +0200 -@@ -2570,20 +2570,25 @@ +diff -Nur openssh-9.9p1.orig/sftp.c openssh-9.9p1/sftp.c +--- openssh-9.9p1.orig/sftp.c 2025-01-20 20:48:33.383582072 +0100 ++++ openssh-9.9p1/sftp.c 2025-01-20 20:50:04.596813843 +0100 +@@ -2569,20 +2569,25 @@ /* Please keep in sync with ssh.c -X */ if (strncmp(optarg, "buffer=", 7) == 0) { r = scan_scaled(optarg + 7, &llv); @@ -12556,9 +12377,9 @@ diff -Nur openssh-10.0p1.orig/sftp.c openssh-10.0p1/sftp.c "\"%s\": %s", optarg + 10, errstr); } num_requests = (size_t)llv; -diff -Nur openssh-10.0p1.orig/sftp-client.c openssh-10.0p1/sftp-client.c ---- openssh-10.0p1.orig/sftp-client.c 2025-06-14 10:53:01.663814268 +0200 -+++ openssh-10.0p1/sftp-client.c 2025-06-14 10:54:01.335625123 +0200 +diff -Nur openssh-9.9p1.orig/sftp-client.c openssh-9.9p1/sftp-client.c +--- openssh-9.9p1.orig/sftp-client.c 2025-01-20 20:48:33.382582070 +0100 ++++ openssh-9.9p1/sftp-client.c 2025-01-20 20:50:04.596813843 +0100 @@ -72,7 +72,8 @@ #define DEFAULT_COPY_BUFLEN 32768 @@ -12569,9 +12390,9 @@ diff -Nur openssh-10.0p1.orig/sftp-client.c openssh-10.0p1/sftp-client.c /* Minimum amount of data to read at a time */ #define MIN_READ_SIZE 512 -diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 ---- openssh-10.0p1.orig/ssh.1 2025-06-14 10:53:02.023904385 +0200 -+++ openssh-10.0p1/ssh.1 2025-06-14 11:29:03.370919913 +0200 +diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1 +--- openssh-9.9p1.orig/ssh.1 2025-01-20 20:48:33.453582249 +0100 ++++ openssh-9.9p1/ssh.1 2025-01-20 21:06:00.112249282 +0100 @@ -77,6 +77,14 @@ X11 connections, arbitrary TCP ports and .Ux Ns -domain @@ -12587,7 +12408,7 @@ diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 .Pp .Nm connects and logs into the specified -@@ -527,12 +535,14 @@ +@@ -526,11 +534,13 @@ .It ControlMaster .It ControlPath .It ControlPersist @@ -12595,25 +12416,24 @@ diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 .It DynamicForward .It EnableSSHKeysign .It EnableEscapeCommandline - .It EnableSSHKeysign .It EscapeChar .It ExitOnForwardFailure +.It FallbackPort .It FingerprintHash .It ForkAfterAuthentication .It ForwardAgent -@@ -556,6 +566,7 @@ - .It HostbasedAcceptedAlgorithms - .It HostbasedAuthentication +@@ -554,6 +564,7 @@ + .It HostKeyAlgorithms + .It HostKeyAlias .It Hostname +.It HPNDisabled* - .It IPQoS .It IdentitiesOnly .It IdentityAgent -@@ -571,7 +582,13 @@ - .It LogLevel + .It IdentityFile +@@ -570,7 +581,13 @@ .It LogVerbose .It MACs + .It Match +.It Metrics +.It MetricsInterval +.It MetricsPath @@ -12622,20 +12442,17 @@ diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 +.It NoneEnabled* +.It NoneMacEnabled* .It NumberOfPasswordPrompts - .It ObscureKeystrokeTiming - .It PKCS11Provider -@@ -605,15 +622,19 @@ + .It PasswordAuthentication + .It PermitLocalCommand +@@ -601,6 +618,7 @@ .It StrictHostKeyChecking .It SyslogFacility .It TCPKeepAlive +.It TcpRcvBufPoll* - .It Tag .It Tunnel .It TunnelDevice .It UpdateHostKeys -+.It UseMPTCP - .It User - .It UserKnownHostsFile +@@ -609,6 +627,8 @@ .It VerifyHostKeyDNS .It VisualHostKey .It XAuthLocation @@ -12644,7 +12461,7 @@ diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 .El .Pp .It Fl P Ar tag -@@ -630,6 +651,13 @@ +@@ -625,6 +645,13 @@ Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. @@ -12658,7 +12475,7 @@ diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 .Pp .It Fl Q Ar query_option Queries for the algorithms supported by one of the following features: -@@ -1821,3 +1849,7 @@ +@@ -1816,3 +1843,7 @@ created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. @@ -12666,9 +12483,9 @@ diff -Nur openssh-10.0p1.orig/ssh.1 openssh-10.0p1/ssh.1 +the HPN extensions at the Pittsburgh Supercomuting Center with grants +from Cisco, the National Library of Medicine, and the National Science +Foundation. -diff -Nur openssh-10.0p1.orig/ssh_api.c openssh-10.0p1/ssh_api.c ---- openssh-10.0p1.orig/ssh_api.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/ssh_api.c 2025-06-14 10:54:01.337078874 +0200 +diff -Nur openssh-9.9p1.orig/ssh_api.c openssh-9.9p1/ssh_api.c +--- openssh-9.9p1.orig/ssh_api.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/ssh_api.c 2025-01-20 20:50:04.598813848 +0100 @@ -427,7 +427,7 @@ char *cp; int r; @@ -12678,9 +12495,9 @@ diff -Nur openssh-10.0p1.orig/ssh_api.c openssh-10.0p1/ssh_api.c return r; if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) return r; -diff -Nur openssh-10.0p1.orig/sshbuf.c openssh-10.0p1/sshbuf.c ---- openssh-10.0p1.orig/sshbuf.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/sshbuf.c 2025-06-14 10:54:01.337433040 +0200 +diff -Nur openssh-9.9p1.orig/sshbuf.c openssh-9.9p1/sshbuf.c +--- openssh-9.9p1.orig/sshbuf.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/sshbuf.c 2025-01-20 20:50:04.598813848 +0100 @@ -27,6 +27,9 @@ #define SSHBUF_INTERNAL #include "sshbuf.h" @@ -12797,9 +12614,9 @@ diff -Nur openssh-10.0p1.orig/sshbuf.c openssh-10.0p1/sshbuf.c SSHBUF_DBG(("adjusted rlen %zu", rlen)); if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL) { SSHBUF_DBG(("realloc fail")); -diff -Nur openssh-10.0p1.orig/sshbuf.h openssh-10.0p1/sshbuf.h ---- openssh-10.0p1.orig/sshbuf.h 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/sshbuf.h 2025-06-14 10:54:01.337808997 +0200 +diff -Nur openssh-9.9p1.orig/sshbuf.h openssh-9.9p1/sshbuf.h +--- openssh-9.9p1.orig/sshbuf.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/sshbuf.h 2025-01-20 20:50:04.598813848 +0100 @@ -29,18 +29,49 @@ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -12878,18 +12695,18 @@ diff -Nur openssh-10.0p1.orig/sshbuf.h openssh-10.0p1/sshbuf.h /* Internal definitions follow. Exposed for regress tests */ #ifdef SSHBUF_INTERNAL -diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c ---- openssh-10.0p1.orig/ssh.c 2025-06-14 10:53:02.024428197 +0200 -+++ openssh-10.0p1/ssh.c 2025-06-14 11:26:41.535259834 +0200 -@@ -111,6 +111,7 @@ +diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c +--- openssh-9.9p1.orig/ssh.c 2025-01-20 20:48:33.454582252 +0100 ++++ openssh-9.9p1/ssh.c 2025-01-20 20:50:04.599813850 +0100 +@@ -109,6 +109,7 @@ + #include "ssherr.h" #include "myproposal.h" #include "utf8.h" - #include "hostfile.h" +#include "cipher-switch.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" -@@ -1122,6 +1123,10 @@ +@@ -1113,6 +1114,10 @@ break; case 'T': options.request_tty = REQUEST_TTY_NO; @@ -12900,7 +12717,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c break; case 'o': line = xstrdup(optarg); -@@ -1743,10 +1748,36 @@ +@@ -1682,10 +1687,36 @@ } /* Open a connection to the remote host. */ @@ -12938,7 +12755,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c if (addrs != NULL) freeaddrinfo(addrs); -@@ -1957,7 +1988,7 @@ +@@ -1896,7 +1927,7 @@ /* Do fork() after authentication. Used by "ssh -f" */ static void @@ -12947,7 +12764,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c { if (need_controlpersist_detach) control_persist_detach(); -@@ -1967,17 +1998,21 @@ +@@ -1906,17 +1937,21 @@ fatal("daemon() failed: %.200s", strerror(errno)); if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1) error_f("stdfd_devnull failed"); @@ -12971,7 +12788,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c } else { debug2_f("%d expected forwarding replies remaining", forward_confirms_pending); -@@ -2044,7 +2079,7 @@ +@@ -1983,7 +2018,7 @@ "for listen port %d", rfwd->listen_port); } } @@ -12980,7 +12797,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c } static void -@@ -2071,7 +2106,7 @@ +@@ -2010,7 +2045,7 @@ } debug_f("tunnel forward established, id=%d", id); @@ -12989,7 +12806,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c } static void -@@ -2272,6 +2307,15 @@ +@@ -2211,6 +2246,15 @@ NULL, fileno(stdin), command, environ); } @@ -13005,7 +12822,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c /* open new channel for a session */ static int ssh_session2_open(struct ssh *ssh) -@@ -2293,6 +2337,7 @@ +@@ -2232,6 +2276,7 @@ window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { @@ -13013,7 +12830,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c window >>= 1; packetmax >>= 1; } -@@ -2301,6 +2346,12 @@ +@@ -2240,6 +2285,12 @@ window, packetmax, CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); @@ -13026,7 +12843,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c debug3_f("channel_new: %d", c->self); channel_send_open(ssh, c->self); -@@ -2317,6 +2368,13 @@ +@@ -2256,6 +2307,13 @@ int r, interactive, id = -1; char *cp, *tun_fwd_ifname = NULL; @@ -13040,7 +12857,7 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c /* XXX should be pre-session */ if (!options.control_persist) ssh_init_stdio_forwarding(ssh); -@@ -2415,7 +2473,14 @@ +@@ -2354,7 +2412,14 @@ debug("deferring postauth fork until remote forward " "confirmation received"); } else @@ -13056,20 +12873,9 @@ diff -Nur openssh-10.0p1.orig/ssh.c openssh-10.0p1/ssh.c } return client_loop(ssh, tty_flag, tty_flag ? -diff -Nur openssh-10.0p1.orig/ssh_config openssh-10.0p1/ssh_config ---- openssh-10.0p1.orig/ssh_config 2025-06-14 10:53:02.024947608 +0200 -+++ openssh-10.0p1/ssh_config 2025-06-14 11:01:39.412445292 +0200 -@@ -46,6 +46,7 @@ - # ProxyCommand ssh -q -W %h:%p gateway.example.com - # RekeyLimit 1G 1h - # UserKnownHostsFile ~/.ssh/known_hosts.d/%k -+# UseMPTCP no - # - # This system is following system-wide crypto policy. - # To modify the crypto properties (Ciphers, MACs, ...), create a *.conf -diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 ---- openssh-10.0p1.orig/ssh_config.5 2025-06-14 10:53:02.025331736 +0200 -+++ openssh-10.0p1/ssh_config.5 2025-06-14 10:54:01.339955855 +0200 +diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5 +--- openssh-9.9p1.orig/ssh_config.5 2025-01-20 20:48:33.454582252 +0100 ++++ openssh-9.9p1/ssh_config.5 2025-01-20 20:50:04.600813853 +0100 @@ -62,6 +62,19 @@ .Pq Pa /etc/ssh/ssh_config .El @@ -13085,12 +12891,12 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 +use +.Xr hpnssh 1 +specific directives in their default ssh_config files or ensure that they always use a -+custom config file. ++custom config file. +.Pp Unless noted otherwise, for each parameter, the first obtained value will be used. The configuration files contain sections separated by -@@ -833,6 +846,9 @@ +@@ -795,6 +808,9 @@ or .Cm no (the default). @@ -13100,7 +12906,7 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 .It Cm FingerprintHash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: -@@ -1159,6 +1175,11 @@ +@@ -1121,6 +1137,11 @@ .Cm Hostname specifications). The default is the name given on the command line. @@ -13112,7 +12918,7 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 .It Cm IdentitiesOnly Specifies that .Xr ssh 1 -@@ -1547,6 +1568,63 @@ +@@ -1502,6 +1523,63 @@ .Pp The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . @@ -13176,7 +12982,7 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 .It Cm NoHostAuthenticationForLocalhost Disable host authentication for localhost (loopback addresses). The argument to this keyword must be -@@ -1554,6 +1632,36 @@ +@@ -1509,6 +1587,36 @@ or .Cm no (the default). @@ -13213,7 +13019,7 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 .It Cm NumberOfPasswordPrompts Specifies the number of password prompts before giving up. The argument to this keyword must be an integer. -@@ -2124,6 +2232,12 @@ +@@ -2066,6 +2174,12 @@ Specify a configuration tag name that may be later used by a .Cm Match directive to select a block of configuration. @@ -13226,20 +13032,7 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 .It Cm Tunnel Request .Xr tun 4 -@@ -2209,6 +2323,12 @@ - from OpenSSH 6.8 and greater support the - .Qq hostkeys@openssh.com - protocol extension used to inform the client of all the server's hostkeys. -+.It Cm UseMPTCP -+If set to -+.Cm yes , -+this will enable Multipath TCP (MPTCP) instead of TCP (this only works on Linux). -+The default is -+.Cm no . - .It Cm User - Specifies the user to log in as. - This can be useful when a different user name is used on different machines. -@@ -2497,3 +2617,11 @@ +@@ -2424,3 +2538,11 @@ created OpenSSH. .An Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. @@ -13251,9 +13044,9 @@ diff -Nur openssh-10.0p1.orig/ssh_config.5 openssh-10.0p1/ssh_config.5 +developed the HPN extensions at the Pittsburgh Supercomuting Center +with grants from Cisco, the National Library of Medicine, and +the National Science Foundation. -diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c ---- openssh-10.0p1.orig/sshconnect2.c 2025-06-14 10:53:02.025925109 +0200 -+++ openssh-10.0p1/sshconnect2.c 2025-06-14 10:54:01.340908632 +0200 +diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c +--- openssh-9.9p1.orig/sshconnect2.c 2025-01-20 20:48:33.455582254 +0100 ++++ openssh-9.9p1/sshconnect2.c 2025-01-20 20:50:04.601813855 +0100 @@ -76,6 +76,7 @@ #include "utf8.h" #include "ssh-sk.h" @@ -13319,28 +13112,9 @@ diff -Nur openssh-10.0p1.orig/sshconnect2.c openssh-10.0p1/sshconnect2.c if (ssh_packet_connection_is_on_socket(ssh)) { verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), -diff -Nur openssh-10.0p1.orig/sshconnect.c openssh-10.0p1/sshconnect.c ---- openssh-10.0p1.orig/sshconnect.c 2025-06-14 10:53:01.488393170 +0200 -+++ openssh-10.0p1/sshconnect.c 2025-06-14 10:54:01.341617244 +0200 -@@ -359,9 +359,14 @@ - #endif - char ntop[NI_MAXHOST]; - -- sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); -+ if (options.use_mptcp) -+ sock = socket(ai->ai_family, ai->ai_socktype, IPPROTO_MPTCP); -+ else -+ sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (sock == -1) { - error("socket: %s", strerror(errno)); -+ if (options.use_mptcp) -+ error ("You asked to use MPTCP. Please ensure it is enabled."); - return -1; - } - (void)fcntl(sock, F_SETFD, FD_CLOEXEC); -diff -Nur openssh-10.0p1.orig/sshd.8 openssh-10.0p1/sshd.8 ---- openssh-10.0p1.orig/sshd.8 2025-06-14 10:53:02.026331727 +0200 -+++ openssh-10.0p1/sshd.8 2025-06-14 10:54:01.342080852 +0200 +diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8 +--- openssh-9.9p1.orig/sshd.8 2025-01-20 20:48:33.455582254 +0100 ++++ openssh-9.9p1/sshd.8 2025-01-20 20:50:04.601813855 +0100 @@ -1079,3 +1079,7 @@ protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support @@ -13349,39 +13123,10 @@ diff -Nur openssh-10.0p1.orig/sshd.8 openssh-10.0p1/sshd.8 +the HPN extensions at the Pittsburgh Supercomuting Center with grants +from Cisco, the National Library of Medicine, and the National Science +Foundation. -diff -Nur openssh-10.0p1.orig/sshd-auth.c openssh-10.0p1/sshd-auth.c ---- openssh-10.0p1.orig/sshd-auth.c 2025-06-14 10:53:01.779184668 +0200 -+++ openssh-10.0p1/sshd-auth.c 2025-06-14 10:54:01.342636371 +0200 -@@ -832,6 +832,25 @@ - struct kex *kex; - int r; - -+ /* this used to be in sshd.c when we read the configuration file -+ * but needed to be moved here as do_ssh2_kex in sshd-auth wasn't -+ * picking up the none options. CJR 4/10/2025 -+ */ -+ if (options.none_enabled == 1) { -+ debug("WARNING: None cipher enabled"); -+ char *old_ciphers = options.ciphers; -+ xasprintf(&options.ciphers, "%s,none", old_ciphers); -+ free(old_ciphers); -+ -+ /* only enable the none MAC in context of the none cipher -cjr */ -+ if (options.nonemac_enabled == 1) { -+ debug("WARNING: None MAC enabled"); -+ char *old_macs = options.macs; -+ xasprintf(&options.macs, "%s,none", old_macs); -+ free(old_macs); -+ } -+ } -+ - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); -diff -Nur openssh-10.0p1.orig/sshd.c openssh-10.0p1/sshd.c ---- openssh-10.0p1.orig/sshd.c 2025-06-14 10:53:01.779446364 +0200 -+++ openssh-10.0p1/sshd.c 2025-06-14 10:54:01.343195243 +0200 -@@ -822,6 +822,8 @@ +diff -Nur openssh-9.9p1.orig/sshd.c openssh-9.9p1/sshd.c +--- openssh-9.9p1.orig/sshd.c 2025-01-20 20:48:33.410582141 +0100 ++++ openssh-9.9p1/sshd.c 2025-01-20 20:50:04.602813858 +0100 +@@ -760,6 +760,8 @@ int ret, listen_sock; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -13390,27 +13135,7 @@ diff -Nur openssh-10.0p1.orig/sshd.c openssh-10.0p1/sshd.c for (ai = la->addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -837,11 +839,17 @@ - continue; - } - /* Create socket for listening. */ -- listen_sock = socket(ai->ai_family, ai->ai_socktype, -- ai->ai_protocol); -+ if (options.use_mptcp) -+ listen_sock = socket(ai->ai_family, ai->ai_socktype, -+ IPPROTO_MPTCP); -+ else -+ listen_sock = socket(ai->ai_family, ai->ai_socktype, -+ ai->ai_protocol); - if (listen_sock == -1) { - /* kernel may not support ipv6 */ - verbose("socket: %.100s", strerror(errno)); -+ if (options.use_mptcp) -+ verbose("MPTCP requested but may not be available."); - continue; - } - if (set_nonblock(listen_sock) == -1) { -@@ -867,6 +875,10 @@ +@@ -805,6 +807,10 @@ debug("Bind to port %s on %s.", strport, ntop); @@ -13421,9 +13146,29 @@ diff -Nur openssh-10.0p1.orig/sshd.c openssh-10.0p1/sshd.c /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) { error("Bind to port %s on %s failed: %.200s.", -diff -Nur openssh-10.0p1.orig/sshd_config openssh-10.0p1/sshd_config ---- openssh-10.0p1.orig/sshd_config 2025-06-14 10:53:02.026903728 +0200 -+++ openssh-10.0p1/sshd_config 2025-06-14 11:00:18.384210561 +0200 +@@ -1428,6 +1434,19 @@ + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + ++ if (options.none_enabled == 1) { ++ char *old_ciphers = options.ciphers; ++ xasprintf(&options.ciphers, "%s,none", old_ciphers); ++ free(old_ciphers); ++ ++ /* only enable the none MAC in context of the none cipher -cjr */ ++ if (options.nonemac_enabled == 1) { ++ char *old_macs = options.macs; ++ xasprintf(&options.macs, "%s,none", old_macs); ++ free(old_macs); ++ } ++ } ++ + /* Check that options are sensible */ + if (options.authorized_keys_command_user == NULL && + (options.authorized_keys_command != NULL && +diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config +--- openssh-9.9p1.orig/sshd_config 2025-01-20 20:48:33.456582257 +0100 ++++ openssh-9.9p1/sshd_config 2025-01-20 21:06:55.293389906 +0100 @@ -18,7 +18,7 @@ # SELinux about this change. # semanage port -a -t ssh_port_t -p tcp #PORTNUMBER @@ -13433,15 +13178,7 @@ diff -Nur openssh-10.0p1.orig/sshd_config openssh-10.0p1/sshd_config #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: -@@ -122,6 +122,7 @@ - #PermitTunnel no - #ChrootDirectory none - #VersionAddendum none -+#UseMPTCP no - - # no default banner path - #Banner none -@@ -129,6 +130,19 @@ +@@ -127,6 +127,19 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server @@ -13461,9 +13198,9 @@ diff -Nur openssh-10.0p1.orig/sshd_config openssh-10.0p1/sshd_config # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no -diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 ---- openssh-10.0p1.orig/sshd_config.5 2025-06-14 10:53:02.027286949 +0200 -+++ openssh-10.0p1/sshd_config.5 2025-06-14 10:54:01.344536060 +0200 +diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5 +--- openssh-9.9p1.orig/sshd_config.5 2025-01-20 20:48:33.456582257 +0100 ++++ openssh-9.9p1/sshd_config.5 2025-01-20 20:50:04.604813863 +0100 @@ -56,6 +56,16 @@ .Pq \&" in order to represent arguments containing spaces. @@ -13492,7 +13229,7 @@ diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 .It Cm ExposeAuthInfo Writes a temporary file containing a list of authentication methods and public credentials (e.g. keys) used to authenticate the user. -@@ -944,6 +958,11 @@ +@@ -900,6 +914,11 @@ The default for this option is: The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . @@ -13504,7 +13241,7 @@ diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 .It Cm IgnoreRhosts Specifies whether to ignore per-user .Pa .rhosts -@@ -1467,6 +1486,19 @@ +@@ -1415,6 +1434,19 @@ key exchange methods. The default is .Pa /etc/moduli . @@ -13524,7 +13261,7 @@ diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 .It Cm PAMServiceName Specifies the service name used for Pluggable Authentication Modules (PAM) authentication, authorisation and session controls when -@@ -2035,6 +2067,13 @@ +@@ -1976,6 +2008,13 @@ .Pp To disable TCP keepalive messages, the value should be set to .Cm no . @@ -13538,20 +13275,7 @@ diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -@@ -2095,6 +2134,12 @@ - .Cm Match - .Cm Host - directives. -+.It Cm UseMPTCP -+If set to -+.Cm yes , -+this will enable Multipath TCP (MPTCP) instead of TCP (this only works on Linux). -+The default is -+.Cm no . - .It Cm UsePAM - Enables the Pluggable Authentication Module interface. - If set to -@@ -2333,3 +2378,11 @@ +@@ -2274,3 +2313,11 @@ and .An Markus Friedl contributed support for privilege separation. @@ -13563,10 +13287,10 @@ diff -Nur openssh-10.0p1.orig/sshd_config.5 openssh-10.0p1/sshd_config.5 +developed the HPN extensions at the Pittsburgh Supercomuting Center +with grants from Cisco, the National Library of Medicine, and +the National Science Foundation. -diff -Nur openssh-10.0p1.orig/sshd-session.c openssh-10.0p1/sshd-session.c ---- openssh-10.0p1.orig/sshd-session.c 2025-06-14 10:53:02.028087821 +0200 -+++ openssh-10.0p1/sshd-session.c 2025-06-14 10:54:01.345322405 +0200 -@@ -1164,6 +1164,20 @@ +diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c +--- openssh-9.9p1.orig/sshd-session.c 2025-01-20 20:48:33.457582259 +0100 ++++ openssh-9.9p1/sshd-session.c 2025-01-20 20:50:04.604813863 +0100 +@@ -1196,6 +1196,20 @@ } endpwent(); @@ -13584,10 +13308,10 @@ diff -Nur openssh-10.0p1.orig/sshd-session.c openssh-10.0p1/sshd-session.c + } + } + - if (!debug_flag && !inetd_flag) { - if ((startup_pipe = dup(REEXEC_CONFIG_PASS_FD)) == -1) - fatal("internal error: no startup pipe"); -@@ -1375,6 +1389,9 @@ + if (!debug_flag) { + startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); + close(REEXEC_STARTUP_PIPE_FD); +@@ -1403,6 +1417,9 @@ rdomain == NULL ? "" : "\""); free(laddr); @@ -13597,10 +13321,22 @@ diff -Nur openssh-10.0p1.orig/sshd-session.c openssh-10.0p1/sshd-session.c /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is -diff -Nur openssh-10.0p1.orig/ssh.h openssh-10.0p1/ssh.h ---- openssh-10.0p1.orig/ssh.h 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/ssh.h 2025-06-14 10:54:01.345905093 +0200 -@@ -14,6 +14,7 @@ +@@ -1575,6 +1592,11 @@ + struct kex *kex; + int r; + ++ if (options.none_enabled == 1) ++ debug("WARNING: None cipher enabled"); ++ if (options.nonemac_enabled == 1) ++ debug("WARNING: None MAC enabled"); ++ + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +diff -Nur openssh-9.9p1.orig/ssh.h openssh-9.9p1/ssh.h +--- openssh-9.9p1.orig/ssh.h 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/ssh.h 2025-01-20 20:50:04.605813865 +0100 +@@ -17,6 +17,7 @@ /* Default port number. */ #define SSH_DEFAULT_PORT 22 @@ -13608,7 +13344,7 @@ diff -Nur openssh-10.0p1.orig/ssh.h openssh-10.0p1/ssh.h /* * Maximum number of certificate files that can be specified -@@ -43,7 +44,7 @@ +@@ -48,7 +49,7 @@ * Name for the service. The port named by this service overrides the * default port if present. */ @@ -13617,10 +13353,10 @@ diff -Nur openssh-10.0p1.orig/ssh.h openssh-10.0p1/ssh.h /* * Name of the environment variable containing the process ID of the -diff -Nur openssh-10.0p1.orig/sshkey.c openssh-10.0p1/sshkey.c ---- openssh-10.0p1.orig/sshkey.c 2025-06-14 10:53:01.935152884 +0200 -+++ openssh-10.0p1/sshkey.c 2025-06-14 10:54:01.346333152 +0200 -@@ -1775,7 +1775,8 @@ +diff -Nur openssh-9.9p1.orig/sshkey.c openssh-9.9p1/sshkey.c +--- openssh-9.9p1.orig/sshkey.c 2025-01-20 20:48:33.411582143 +0100 ++++ openssh-9.9p1/sshkey.c 2025-01-20 20:50:04.606813868 +0100 +@@ -1778,7 +1778,8 @@ stderr); #endif if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), @@ -13630,7 +13366,7 @@ diff -Nur openssh-10.0p1.orig/sshkey.c openssh-10.0p1/sshkey.c goto out; /* Serialise and encrypt the private key using the ephemeral key */ -@@ -1910,7 +1911,8 @@ +@@ -1913,7 +1914,8 @@ keyiv, SSH_DIGEST_MAX_LENGTH)) != 0) goto out; if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), @@ -13640,7 +13376,7 @@ diff -Nur openssh-10.0p1.orig/sshkey.c openssh-10.0p1/sshkey.c goto out; #ifdef DEBUG_PK fprintf(stderr, "%s: key+iv\n", __func__); -@@ -2965,6 +2967,13 @@ +@@ -2981,6 +2983,13 @@ kdfname = "none"; } else if (ciphername == NULL) ciphername = DEFAULT_CIPHERNAME; @@ -13654,7 +13390,7 @@ diff -Nur openssh-10.0p1.orig/sshkey.c openssh-10.0p1/sshkey.c if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_INVALID_ARGUMENT; goto out; -@@ -3000,7 +3009,7 @@ +@@ -3016,7 +3025,7 @@ goto out; } if ((r = cipher_init(&ciphercontext, cipher, key, keylen, @@ -13663,7 +13399,7 @@ diff -Nur openssh-10.0p1.orig/sshkey.c openssh-10.0p1/sshkey.c goto out; if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || -@@ -3187,6 +3196,8 @@ +@@ -3203,6 +3212,8 @@ (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) goto out; @@ -13672,7 +13408,7 @@ diff -Nur openssh-10.0p1.orig/sshkey.c openssh-10.0p1/sshkey.c if ((cipher = cipher_by_name(ciphername)) == NULL) { r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; -@@ -3242,7 +3253,7 @@ +@@ -3258,7 +3269,7 @@ /* decrypt private portion of key */ if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || (r = cipher_init(&ciphercontext, cipher, key, keylen, @@ -13681,9 +13417,9 @@ diff -Nur openssh-10.0p1.orig/sshkey.c openssh-10.0p1/sshkey.c goto out; if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded), encrypted_len, 0, authlen)) != 0) { -diff -Nur openssh-10.0p1.orig/sshkey-xmss.c openssh-10.0p1/sshkey-xmss.c ---- openssh-10.0p1.orig/sshkey-xmss.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/sshkey-xmss.c 2025-06-14 10:54:01.347175650 +0200 +diff -Nur openssh-9.9p1.orig/sshkey-xmss.c openssh-9.9p1/sshkey-xmss.c +--- openssh-9.9p1.orig/sshkey-xmss.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/sshkey-xmss.c 2025-01-20 20:50:04.606813868 +0100 @@ -903,9 +903,29 @@ state->enc_keyiv == NULL || state->enc_ciphername == NULL) @@ -13768,9 +13504,9 @@ diff -Nur openssh-10.0p1.orig/sshkey-xmss.c openssh-10.0p1/sshkey-xmss.c (r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(copy), encrypted_len, aadlen, authlen)) != 0) goto out; -diff -Nur openssh-10.0p1.orig/umac.c openssh-10.0p1/umac.c ---- openssh-10.0p1.orig/umac.c 2025-04-09 09:02:43.000000000 +0200 -+++ openssh-10.0p1/umac.c 2025-06-14 10:54:01.347637721 +0200 +diff -Nur openssh-9.9p1.orig/umac.c openssh-9.9p1/umac.c +--- openssh-9.9p1.orig/umac.c 2024-09-20 00:20:48.000000000 +0200 ++++ openssh-9.9p1/umac.c 2025-01-20 20:50:04.607813871 +0100 @@ -134,15 +134,48 @@ /* --- Endian Conversion --- Forcing assembly on some platforms */ /* ---------------------------------------------------------------------- */ @@ -13823,9 +13559,9 @@ diff -Nur openssh-10.0p1.orig/umac.c openssh-10.0p1/umac.c #define STORE_UINT32_BIG(p,v) put_u32(p, v) /* ---------------------------------------------------------------------- */ -diff -Nur openssh-10.0p1.orig/uthash.h openssh-10.0p1/uthash.h ---- openssh-10.0p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 -+++ openssh-10.0p1/uthash.h 2025-06-14 10:54:01.348457241 +0200 +diff -Nur openssh-9.9p1.orig/uthash.h openssh-9.9p1/uthash.h +--- openssh-9.9p1.orig/uthash.h 1970-01-01 01:00:00.000000000 +0100 ++++ openssh-9.9p1/uthash.h 2025-01-20 20:50:04.608813873 +0100 @@ -0,0 +1,1140 @@ +/* +Copyright (c) 2003-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ @@ -14967,14 +14703,14 @@ diff -Nur openssh-10.0p1.orig/uthash.h openssh-10.0p1/uthash.h +} UT_hash_handle; + +#endif /* UTHASH_H */ -diff -Nur openssh-10.0p1.orig/version.h openssh-10.0p1/version.h ---- openssh-10.0p1.orig/version.h 2025-06-14 10:53:02.028786585 +0200 -+++ openssh-10.0p1/version.h 2025-06-14 11:34:35.359783615 +0200 +diff -Nur openssh-9.9p1.orig/version.h openssh-9.9p1/version.h +--- openssh-9.9p1.orig/version.h 2025-01-20 20:48:33.457582259 +0100 ++++ openssh-9.9p1/version.h 2025-01-20 21:09:18.648755010 +0100 @@ -16,5 +16,6 @@ - #define SSH_PORTABLE "p2" + #define SSH_PORTABLE "p1" #define GSI_PORTABLE "c-GSI" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE \ -+#define SSH_HPN "_hpn18.7.0" ++#define SSH_HPN "_hpn18.6.0" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE GSI_PORTABLE SSH_HPN \ GSI_VERSION KRB5_VERSION diff --git a/openssh-9.9p1-match-regression.patch b/openssh-9.9p1-match-regression.patch new file mode 100644 index 0000000..73ea964 --- /dev/null +++ b/openssh-9.9p1-match-regression.patch @@ -0,0 +1,471 @@ +diff --git a/misc.c b/misc.c +index afdf5142..1b4b55c5 100644 +--- a/misc.c ++++ b/misc.c +@@ -107,6 +107,27 @@ rtrim(char *s) + } + } + ++/* ++ * returns pointer to character after 'prefix' in 's' or otherwise NULL ++ * if the prefix is not present. ++ */ ++const char * ++strprefix(const char *s, const char *prefix, int ignorecase) ++{ ++ size_t prefixlen; ++ ++ if ((prefixlen = strlen(prefix)) == 0) ++ return s; ++ if (ignorecase) { ++ if (strncasecmp(s, prefix, prefixlen) != 0) ++ return NULL; ++ } else { ++ if (strncmp(s, prefix, prefixlen) != 0) ++ return NULL; ++ } ++ return s + prefixlen; ++} ++ + /* set/unset filedescriptor to non-blocking */ + int + set_nonblock(int fd) +diff --git a/misc.h b/misc.h +index 11340389..efecdf1a 100644 +--- a/misc.h ++++ b/misc.h +@@ -56,6 +56,7 @@ struct ForwardOptions { + char *chop(char *); + void rtrim(char *); + void skip_space(char **); ++const char *strprefix(const char *, const char *, int); + char *strdelim(char **); + char *strdelimw(char **); + int set_nonblock(int); +diff --git a/readconf.c b/readconf.c +index 3d9cc6db..9f559269 100644 +--- a/readconf.c ++++ b/readconf.c +@@ -710,7 +710,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + struct passwd *pw, const char *host_arg, const char *original_host, + int final_pass, int *want_final_pass, const char *filename, int linenum) + { +- char *arg, *oattrib, *attrib, *cmd, *host, *criteria; ++ char *arg, *oattrib = NULL, *attrib = NULL, *cmd, *host, *criteria; + const char *ruser; + int r, this_result, result = 1, attributes = 0, negate; + +@@ -731,7 +731,8 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + + debug2("checking match for '%s' host %s originally %s", + full_line, host, original_host); +- while ((oattrib = attrib = argv_next(acp, avp)) != NULL) { ++ while ((attrib = argv_next(acp, avp)) != NULL) { ++ attrib = oattrib = xstrdup(attrib); + /* Terminate on comment */ + if (*attrib == '#') { + argv_consume(acp); +@@ -777,9 +778,23 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + this_result ? "" : "not ", oattrib); + continue; + } ++ ++ /* Keep this list in sync with below */ ++ if (strprefix(attrib, "host=", 1) != NULL || ++ strprefix(attrib, "originalhost=", 1) != NULL || ++ strprefix(attrib, "user=", 1) != NULL || ++ strprefix(attrib, "localuser=", 1) != NULL || ++ strprefix(attrib, "localnetwork=", 1) != NULL || ++ strprefix(attrib, "tagged=", 1) != NULL || ++ strprefix(attrib, "exec=", 1) != NULL) { ++ arg = strchr(attrib, '='); ++ *(arg++) = '\0'; ++ } else { ++ arg = argv_next(acp, avp); ++ } ++ + /* All other criteria require an argument */ +- if ((arg = argv_next(acp, avp)) == NULL || +- *arg == '\0' || *arg == '#') { ++ if (arg == NULL || *arg == '\0' || *arg == '#') { + error("Missing Match criteria for %s", attrib); + result = -1; + goto out; +@@ -856,6 +871,8 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + criteria == NULL ? "" : criteria, + criteria == NULL ? "" : "\""); + free(criteria); ++ free(oattrib); ++ oattrib = attrib = NULL; + } + if (attributes == 0) { + error("One or more attributes required for Match"); +@@ -865,6 +882,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + out: + if (result != -1) + debug2("match %sfound", result ? "" : "not "); ++ free(oattrib); + free(host); + return result; + } +diff --git a/servconf.c b/servconf.c +index 89b8413e..dd774f46 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: servconf.c,v 1.418 2024/09/15 03:09:44 djm Exp $ */ ++/* $OpenBSD: servconf.c,v 1.419 2024/09/25 01:24:04 djm Exp $ */ + /* + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved +@@ -1033,7 +1033,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + int line, struct connection_info *ci) + { + int result = 1, attributes = 0, port; +- char *arg, *attrib; ++ char *arg, *attrib = NULL, *oattrib; + + if (ci == NULL) + debug3("checking syntax for 'Match %s'", full_line); +@@ -1047,7 +1047,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + ci->laddress ? ci->laddress : "(null)", ci->lport); + } + +- while ((attrib = argv_next(acp, avp)) != NULL) { ++ while ((oattrib = argv_next(acp, avp)) != NULL) { ++ attrib = xstrdup(oattrib); + /* Terminate on comment */ + if (*attrib == '#') { + argv_consume(acp); /* mark all arguments consumed */ +@@ -1062,16 +1063,20 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + *arg != '\0' && *arg != '#')) { + error("'all' cannot be combined with other " + "Match attributes"); +- return -1; ++ result = -1; ++ goto out; + } + if (arg != NULL && *arg == '#') + argv_consume(acp); /* consume remaining args */ +- return 1; ++ result = 1; ++ goto out; + } + /* Criterion "invalid-user" also has no argument */ + if (strcasecmp(attrib, "invalid-user") == 0) { +- if (ci == NULL) ++ if (ci == NULL) { ++ result = 0; + continue; ++ } + if (ci->user_invalid == 0) + result = 0; + else +@@ -1078,11 +1081,26 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + debug("matched invalid-user at line %d", line); + continue; + } ++ ++ /* Keep this list in sync with below */ ++ if (strprefix(attrib, "user=", 1) != NULL || ++ strprefix(attrib, "group=", 1) != NULL || ++ strprefix(attrib, "host=", 1) != NULL || ++ strprefix(attrib, "address=", 1) != NULL || ++ strprefix(attrib, "localaddress=", 1) != NULL || ++ strprefix(attrib, "localport=", 1) != NULL || ++ strprefix(attrib, "rdomain=", 1) != NULL) { ++ arg = strchr(attrib, '='); ++ *(arg++) = '\0'; ++ } else { ++ arg = argv_next(acp, avp); ++ } ++ + /* All other criteria require an argument */ +- if ((arg = argv_next(acp, avp)) == NULL || +- *arg == '\0' || *arg == '#') { ++ if (arg == NULL || *arg == '\0' || *arg == '#') { + error("Missing Match criteria for %s", attrib); +- return -1; ++ result = -1; ++ goto out; + } + if (strcasecmp(attrib, "user") == 0) { + if (ci == NULL || (ci->test && ci->user == NULL)) { +@@ -1105,7 +1123,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + match_test_missing_fatal("Group", "user"); + switch (match_cfg_line_group(arg, line, ci->user)) { + case -1: +- return -1; ++ result = -1; ++ goto out; + case 0: + result = 0; + } +@@ -1141,7 +1160,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + result = 0; + break; + case -2: +- return -1; ++ result = -1; ++ goto out; + } + } else if (strcasecmp(attrib, "localaddress") == 0){ + if (ci == NULL || (ci->test && ci->laddress == NULL)) { +@@ -1166,13 +1186,15 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + result = 0; + break; + case -2: +- return -1; ++ result = -1; ++ goto out; + } + } else if (strcasecmp(attrib, "localport") == 0) { + if ((port = a2port(arg)) == -1) { + error("Invalid LocalPort '%s' on Match line", + arg); +- return -1; ++ result = -1; ++ goto out; + } + if (ci == NULL || (ci->test && ci->lport == -1)) { + result = 0; +@@ -1200,16 +1222,21 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, + debug("user %.100s matched 'RDomain %.100s' at " + "line %d", ci->rdomain, arg, line); + } else { +- error("Unsupported Match attribute %s", attrib); +- return -1; ++ error("Unsupported Match attribute %s", oattrib); ++ result = -1; ++ goto out; + } ++ free(attrib); ++ attrib = NULL; + } + if (attributes == 0) { + error("One or more attributes required for Match"); + return -1; + } +- if (ci != NULL) ++ out: ++ if (ci != NULL && result != -1) + debug3("match %sfound", result ? "" : "not "); ++ free(attrib); + return result; + } + +diff --git a/regress/cfginclude.sh b/regress/cfginclude.sh +index d442cdd6..97fd816f 100644 +--- a/regress/cfginclude.sh ++++ b/regress/cfginclude.sh +@@ -1,4 +1,4 @@ +-# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ ++# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ + # Placed in the Public Domain. + + tid="config include" +@@ -10,7 +10,7 @@ cat > $OBJ/ssh_config.i << _EOF + Match host a + Hostname aa + +-Match host b # comment ++Match host=b # comment + Hostname bb + Include $OBJ/ssh_config.i.* + +@@ -18,7 +18,7 @@ Match host c + Include $OBJ/ssh_config.i.* + Hostname cc + +-Match host m ++Match host=m !user xxxyfake + Include $OBJ/ssh_config.i.* # comment + + Host d +@@ -41,7 +41,7 @@ Match host xxxxxx + _EOF + + cat > $OBJ/ssh_config.i.1 << _EOF +-Match host a ++Match host=a + Hostname aaa + + Match host b +@@ -64,10 +64,10 @@ cat > $OBJ/ssh_config.i.2 << _EOF + Match host a + Hostname aaaa + +-Match host b ++Match host=b !user blahblahfake + Hostname bbbb + +-Match host c ++Match host=c + Hostname cccc + + Host d +@@ -142,7 +142,7 @@ trial a aa + + # cleanup + rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out +-# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ ++# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ + # Placed in the Public Domain. + + tid="config include" +diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh +index 05a66685..2737a5f9 100644 +--- a/regress/cfgmatch.sh ++++ b/regress/cfgmatch.sh +@@ -1,4 +1,4 @@ +-# $OpenBSD: cfgmatch.sh,v 1.13 2021/06/08 06:52:43 djm Exp $ ++# $OpenBSD: cfgmatch.sh,v 1.14 2024/09/27 01:05:54 djm Exp $ + # Placed in the Public Domain. + + tid="sshd_config match" +@@ -26,7 +26,7 @@ start_client() + kill $client_pid + fatal "timeout waiting for background ssh" + fi +- done ++ done + } + + stop_client() +@@ -119,40 +119,42 @@ stop_client + # requires knowledge of actual group memberships user running the test). + params="user:user:u1 host:host:h1 address:addr:1.2.3.4 \ + localaddress:laddr:5.6.7.8 rdomain:rdomain:rdom1" +-cp $OBJ/sshd_proxy_bak $OBJ/sshd_config +-echo 'Banner /nomatch' >>$OBJ/sshd_config +-for i in $params; do +- config=`echo $i | cut -f1 -d:` +- criteria=`echo $i | cut -f2 -d:` +- value=`echo $i | cut -f3 -d:` +- cat >>$OBJ/sshd_config </dev/null || \ ++ fail "validate config for w/out spec" ++ ++ # Test matching each criteria. ++ for i in $params; do ++ testcriteria=`echo $i | cut -f2 -d:` ++ expected=/`echo $i | cut -f3 -d:` ++ spec="" ++ for j in $params; do ++ config=`echo $j | cut -f1 -d:` ++ criteria=`echo $j | cut -f2 -d:` ++ value=`echo $j | cut -f3 -d:` ++ if [ "$criteria" = "$testcriteria" ]; then ++ spec="$criteria=$value,$spec" ++ else ++ spec="$criteria=1$value,$spec" ++ fi ++ done ++ trace "test spec $spec" ++ result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ ++ awk '$1=="banner"{print $2}'` ++ if [ "$result" != "$expected" ]; then ++ fail "match $config expected $expected got $result" + fi + done +- trace "test spec $spec" +- result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ +- awk '$1=="banner"{print $2}'` +- if [ "$result" != "$expected" ]; then +- fail "match $config expected $expected got $result" +- fi + done +diff --git a/regress/servcfginclude.sh b/regress/servcfginclude.sh +index 518a703d..f67c3caa 100644 +--- a/regress/servcfginclude.sh ++++ b/regress/servcfginclude.sh +@@ -4,14 +4,14 @@ tid="server config include" + + cat > $OBJ/sshd_config.i << _EOF + HostKey $OBJ/host.ssh-ed25519 +-Match host a ++Match host=a + Banner /aa + + Match host b + Banner /bb + Include $OBJ/sshd_config.i.* # comment + +-Match host c ++Match host=c + Include $OBJ/sshd_config.i.* # comment + Banner /cc + +@@ -25,7 +25,7 @@ Match Host e + Banner /ee + Include $OBJ/sshd_config.i.* + +-Match Host f ++Match Host=f + Include $OBJ/sshd_config.i.* + Banner /ff + +@@ -47,13 +47,13 @@ Match host b + Match host c + Banner /ccc + +-Match Host d ++Match Host=d + Banner /ddd + + Match Host e + Banner /eee + +-Match Host f ++Match Host=f + Banner /fff + _EOF + +@@ -61,13 +61,13 @@ cat > $OBJ/sshd_config.i.2 << _EOF + Match host a + Banner /aaaa + +-Match host b ++Match host=b + Banner /bbbb + + Match host c # comment + Banner /cccc + +-Match Host d ++Match Host=d + Banner /dddd + + Match Host e diff --git a/openssh-9.9p1-mlkembe.patch b/openssh-9.9p1-mlkembe.patch new file mode 100644 index 0000000..aa0c26c --- /dev/null +++ b/openssh-9.9p1-mlkembe.patch @@ -0,0 +1,98 @@ +diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c +index 679446e9..2b5d3960 100644 +--- a/kexmlkem768x25519.c ++++ b/kexmlkem768x25519.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: kexmlkem768x25519.c,v 1.1 2024/09/02 12:13:56 djm Exp $ */ ++/* $OpenBSD: kexmlkem768x25519.c,v 1.2 2024/10/27 02:06:59 djm Exp $ */ + /* + * Copyright (c) 2023 Markus Friedl. All rights reserved. + * +@@ -34,6 +34,9 @@ + #include + #include + #include ++#ifdef HAVE_ENDIAN_H ++# include ++#endif + + #include "sshkey.h" + #include "kex.h" +diff --git a/libcrux_mlkem768_sha3.h b/libcrux_mlkem768_sha3.h +index a82d60e8..b8ac1436 100644 +--- a/libcrux_mlkem768_sha3.h ++++ b/libcrux_mlkem768_sha3.h +@@ -1,4 +1,5 @@ +-/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.1 2024/09/02 12:13:56 djm Exp $ */ ++/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.2 2024/10/27 02:06:01 djm Exp $ */ ++ + /* Extracted from libcrux revision 84c5d87b3092c59294345aa269ceefe0eb97cc35 */ + + /* +@@ -160,18 +161,19 @@ static inline void Eurydice_slice_to_array3(uint8_t *dst_tag, char *dst_ok, + // CORE STUFF (conversions, endianness, ...) + + static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { ++ v = htole64(v); + memcpy(buf, &v, sizeof(v)); + } + static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { + uint64_t v; + memcpy(&v, buf, sizeof(v)); +- return v; ++ return le64toh(v); + } + + static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { + uint32_t v; + memcpy(&v, buf, sizeof(v)); +- return v; ++ return le32toh(v); + } + + static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { +diff --git a/mlkem768.sh b/mlkem768.sh +index 2fdc2831..3d12b2ed 100644 +--- a/mlkem768.sh ++++ b/mlkem768.sh +@@ -1,9 +1,10 @@ + #!/bin/sh +-# $OpenBSD: mlkem768.sh,v 1.2 2024/09/04 05:11:33 djm Exp $ ++# $OpenBSD: mlkem768.sh,v 1.3 2024/10/27 02:06:01 djm Exp $ + # Placed in the Public Domain. + # + +-WANT_LIBCRUX_REVISION="origin/main" ++#WANT_LIBCRUX_REVISION="origin/main" ++WANT_LIBCRUX_REVISION="84c5d87b3092c59294345aa269ceefe0eb97cc35" + + FILES=" + libcrux/libcrux-ml-kem/cg/eurydice_glue.h +@@ -47,6 +48,7 @@ echo '#define KRML_NOINLINE __attribute__((noinline, unused))' + echo '#define KRML_HOST_EPRINTF(...)' + echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")' + echo ++ + for i in $FILES; do + echo "/* from $i */" + # Changes to all files: +@@ -56,11 +58,16 @@ for i in $FILES; do + -e 's/[ ]*$//' \ + $i | \ + case "$i" in +- # XXX per-file handling goes here. ++ */libcrux-ml-kem/cg/eurydice_glue.h) ++ # Replace endian functions with versions that work. ++ perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1 v = htole64(v);\n\2/' | ++ perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' | ++ perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' ++ ;; + # Default: pass through. + *) +- cat +- ;; ++ cat ++ ;; + esac + echo + done diff --git a/openssh-9.9p1-separate-keysign.patch b/openssh-9.9p1-separate-keysign.patch new file mode 100644 index 0000000..ff0e35f --- /dev/null +++ b/openssh-9.9p1-separate-keysign.patch @@ -0,0 +1,12 @@ +diff -up openssh-9.9p1/ssh_config.5.xxx openssh-9.9p1/ssh_config.5 +--- openssh-9.9p1/ssh_config.5.xxx 2024-10-11 12:01:14.260566303 +0200 ++++ openssh-9.9p1/ssh_config.5 2024-10-11 12:01:59.725654775 +0200 +@@ -759,7 +759,7 @@ or + This option should be placed in the non-hostspecific section. + See + .Xr ssh-keysign 8 +-for more information. ++for more information. ssh-keysign should be installed explicitly. + .It Cm EscapeChar + Sets the escape character (default: + .Ql ~ ) . diff --git a/openssh-9.9p2-error_processing.patch b/openssh-9.9p2-error_processing.patch new file mode 100644 index 0000000..692c6ac --- /dev/null +++ b/openssh-9.9p2-error_processing.patch @@ -0,0 +1,152 @@ +diff --git a/krl.c b/krl.c +index e2efdf06..0d0f6953 100644 +--- a/krl.c ++++ b/krl.c +@@ -674,6 +674,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf) + break; + case KRL_SECTION_CERT_SERIAL_BITMAP: + if (rs->lo - bitmap_start > INT_MAX) { ++ r = SSH_ERR_INVALID_FORMAT; + error_f("insane bitmap gap"); + goto out; + } +@@ -1059,6 +1060,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp) + } + + if ((krl = ssh_krl_init()) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; + error_f("alloc failed"); + goto out; + } +diff --git a/packet.c b/packet.c +index 486f8515..9dea2cfc 100644 +--- a/packet.c ++++ b/packet.c +@@ -1864,6 +1864,14 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) + if ((r = sshpkt_get_string_direct(ssh, &d, &len)) != 0) + return r; + DBG(debug("Received SSH2_MSG_PING len %zu", len)); ++ if (!ssh->state->after_authentication) { ++ DBG(debug("Won't reply to PING in preauth")); ++ break; ++ } ++ if (ssh_packet_is_rekeying(ssh)) { ++ DBG(debug("Won't reply to PING during KEX")); ++ break; ++ } + if ((r = sshpkt_start(ssh, SSH2_MSG_PONG)) != 0 || + (r = sshpkt_put_string(ssh, d, len)) != 0 || + (r = sshpkt_send(ssh)) != 0) +diff --git a/ssh-agent.c b/ssh-agent.c +index 48973b2c..c27c5a95 100644 +--- a/ssh-agent.c ++++ b/ssh-agent.c +@@ -1220,6 +1220,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, + "restrict-destination-v00@openssh.com") == 0) { + if (*dcsp != NULL) { + error_f("%s already set", ext_name); ++ r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if ((r = sshbuf_froms(m, &b)) != 0) { +@@ -1229,6 +1230,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, + while (sshbuf_len(b) != 0) { + if (*ndcsp >= AGENT_MAX_DEST_CONSTRAINTS) { + error_f("too many %s constraints", ext_name); ++ r = SSH_ERR_INVALID_FORMAT; + goto out; + } + *dcsp = xrecallocarray(*dcsp, *ndcsp, *ndcsp + 1, +@@ -1246,6 +1248,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, + } + if (*certs != NULL) { + error_f("%s already set", ext_name); ++ r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if ((r = sshbuf_get_u8(m, &v)) != 0 || +@@ -1257,6 +1260,7 @@ parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, + while (sshbuf_len(b) != 0) { + if (*ncerts >= AGENT_MAX_EXT_CERTS) { + error_f("too many %s constraints", ext_name); ++ r = SSH_ERR_INVALID_FORMAT; + goto out; + } + *certs = xrecallocarray(*certs, *ncerts, *ncerts + 1, +@@ -1757,6 +1761,7 @@ process_ext_session_bind(SocketEntry *e) + /* record new key/sid */ + if (e->nsession_ids >= AGENT_MAX_SESSION_IDS) { + error_f("too many session IDs recorded"); ++ r = -1; + goto out; + } + e->session_ids = xrecallocarray(e->session_ids, e->nsession_ids, +diff --git a/ssh-sk-client.c b/ssh-sk-client.c +index 321fe53a..06fad221 100644 +--- a/ssh-sk-client.c ++++ b/ssh-sk-client.c +@@ -439,6 +439,7 @@ sshsk_load_resident(const char *provider_path, const char *device, + } + if ((srk = calloc(1, sizeof(*srk))) == NULL) { + error_f("calloc failed"); ++ r = SSH_ERR_ALLOC_FAIL; + goto out; + } + srk->key = key; +@@ -450,6 +451,7 @@ sshsk_load_resident(const char *provider_path, const char *device, + if ((tmp = recallocarray(srks, nsrks, nsrks + 1, + sizeof(*srks))) == NULL) { + error_f("recallocarray keys failed"); ++ r = SSH_ERR_ALLOC_FAIL; + goto out; + } + debug_f("srks[%zu]: %s %s uidlen %zu", nsrks, +diff --git a/sshconnect2.c b/sshconnect2.c +index a69c4da1..1ee6000a 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -99,7 +99,7 @@ verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) + options.required_rsa_size)) != 0) + fatal_r(r, "Bad server host key"); + if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, +- xxx_conn_info) == -1) ++ xxx_conn_info) != 0) + fatal("Host key verification failed."); + return 0; + } +@@ -699,6 +699,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) + + if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { + debug_f("server sent unknown pkalg %s", pkalg); ++ r = SSH_ERR_INVALID_FORMAT; + goto done; + } + if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { +@@ -709,6 +710,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) + error("input_userauth_pk_ok: type mismatch " + "for decoded key (received %d, expected %d)", + key->type, pktype); ++ r = SSH_ERR_INVALID_FORMAT; + goto done; + } + +@@ -728,6 +730,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) + SSH_FP_DEFAULT); + error_f("server replied with unknown key: %s %s", + sshkey_type(key), fp == NULL ? "" : fp); ++ r = SSH_ERR_INVALID_FORMAT; + goto done; + } + ident = format_identity(id); +diff --git a/sshsig.c b/sshsig.c +index 6e03c0b0..3da005d6 100644 +--- a/sshsig.c ++++ b/sshsig.c +@@ -879,6 +879,7 @@ cert_filter_principals(const char *path, u_long linenum, + } + if ((principals = sshbuf_dup_string(nprincipals)) == NULL) { + error_f("buffer error"); ++ r = SSH_ERR_ALLOC_FAIL; + goto out; + } + /* success */ diff --git a/sources b/sources index 10b461b..e88b6d9 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-10.0p1.tar.gz) = 2daa1fcf95793b23810142077e68ddfabdf3732b207ef4f033a027f72d733d0e9bcdb6f757e7f3a5934b972de05bfaae3baae381cfc7a400cd8ab4d4e277a0ed -SHA512 (openssh-10.0p1.tar.gz.asc) = 6ab9deb4233ff159e55a18c9fc07d5ff8a41723dad74aa3d803e1476b585f5662aba34f8a7a1f5fe1d248f3ff3cd663f2c2fb8e399c6a4723b6215b0eb423d13 +SHA512 (openssh-9.9p1.tar.gz) = 3cc0ed97f3e29ecbd882eca79239f02eb5a1606fce4f3119ddc3c5e86128aa3ff12dc85000879fccc87b60e7d651cfe37376607ac66075fede2118deaa685d6d +SHA512 (openssh-9.9p1.tar.gz.asc) = 916e975c54eb68c0b2f0b0006522b241cbe54c4caa88d31537a6278490c93d9d732c2ab3a080ac084bf75cbdd5402901ec68583cbe7c7cde4a8e40e7a8b78c28 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21