diff --git a/.gitignore b/.gitignore index c400ff6..98996cc 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,5 @@ pam_ssh_agent_auth-0.9.2.tar.bz2 /openssh-9.9p1.tar.gz.asc /openssh-10.0p1.tar.gz /openssh-10.0p1.tar.gz.asc +/openssh-10.2p1.tar.gz +/openssh-10.2p1.tar.gz.asc diff --git a/0001-openssh-7.8p1-role-mls.patch b/0001-openssh-7.8p1-role-mls.patch index c08e414..0377e8c 100644 --- a/0001-openssh-7.8p1-role-mls.patch +++ b/0001-openssh-7.8p1-role-mls.patch @@ -1,7 +1,7 @@ -From 95f4e30195382c3df7104c2ad3e5e9953f8ad554 Mon Sep 17 00:00:00 2001 +From b6875ceaca4be9e0de0d6d260d8fcff1772f5fb5 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 +Subject: [PATCH 01/53] openssh-7.8p1-role-mls --- auth-pam.c | 2 +- @@ -26,10 +26,10 @@ Subject: [PATCH 01/50] openssh-7.8p1-role-mls create mode 100644 openbsd-compat/port-linux-sshd.c diff --git a/auth-pam.c b/auth-pam.c -index 13c0a792..b4100ea1 100644 +index 5591f094e..70bcae83a 100644 --- a/auth-pam.c +++ b/auth-pam.c -@@ -1238,7 +1238,7 @@ is_pam_session_open(void) +@@ -1261,7 +1261,7 @@ is_pam_session_open(void) * during the ssh authentication process. */ int @@ -39,7 +39,7 @@ index 13c0a792..b4100ea1 100644 int ret = 1; char *compound; diff --git a/auth-pam.h b/auth-pam.h -index 8d801c68..9dd7ae07 100644 +index 8d801c689..9dd7ae078 100644 --- a/auth-pam.h +++ b/auth-pam.h @@ -33,7 +33,7 @@ u_int do_pam_account(void); @@ -52,7 +52,7 @@ index 8d801c68..9dd7ae07 100644 char ** fetch_pam_child_environment(void); void free_pam_environment(char **); diff --git a/auth.h b/auth.h -index 98bb23d4..83d07ae8 100644 +index 98bb23d4c..83d07ae8b 100644 --- a/auth.h +++ b/auth.h @@ -65,6 +65,9 @@ struct Authctxt { @@ -66,7 +66,7 @@ index 98bb23d4..83d07ae8 100644 /* 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 +index 75eb4e3a3..f7898ab3e 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) @@ -102,7 +102,7 @@ index 75eb4e3a..f7898ab3 100644 authctxt->postponed = 0; diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index eb21479a..a3be6e49 100644 +index 9d8b860eb..976484fc5 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -129,7 +129,16 @@ userauth_hostbased(struct ssh *ssh, const char *method) @@ -123,10 +123,10 @@ index eb21479a..a3be6e49 100644 (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 +index 15ad3000c..c326a69ba 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c -@@ -206,9 +206,16 @@ userauth_pubkey(struct ssh *ssh, const char *method) +@@ -204,9 +204,16 @@ userauth_pubkey(struct ssh *ssh, const char *method) goto done; } /* reconstruct packet */ @@ -146,7 +146,7 @@ index aa24fda0..267a27d2 100644 (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 +index b9bb46f59..1345d3257 100644 --- a/auth2.c +++ b/auth2.c @@ -271,6 +271,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) @@ -186,10 +186,10 @@ index 82f6e621..5ba45c12 100644 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 +index ce77ec943..5bed34735 100644 --- a/misc.c +++ b/misc.c -@@ -806,6 +806,7 @@ char * +@@ -822,6 +822,7 @@ char * colon(char *cp) { int flag = 0; @@ -197,7 +197,7 @@ index dd0bd032..c932f9bb 100644 if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -821,6 +822,13 @@ colon(char *cp) +@@ -837,6 +838,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -212,10 +212,10 @@ index dd0bd032..c932f9bb 100644 return NULL; } diff --git a/monitor.c b/monitor.c -index 2179553d..02b3eaaa 100644 +index a9e854bec..85dc1b1b7 100644 --- a/monitor.c +++ b/monitor.c -@@ -120,6 +120,9 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); +@@ -110,6 +110,9 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); 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 +225,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[] = { +@@ -184,6 +187,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 +235,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) +@@ -919,6 +925,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -245,7 +245,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, +@@ -993,6 +1002,26 @@ key_base_type_match(const char *method, const struct sshkey *key, return found; } @@ -272,7 +272,7 @@ 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) +@@ -1364,7 +1393,7 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) struct sshbuf *b; struct sshkey *hostkey = NULL; const u_char *p; @@ -281,7 +281,7 @@ index 2179553d..02b3eaaa 100644 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) +@@ -1395,6 +1424,8 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse userstyle"); @@ -290,7 +290,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, +@@ -1445,7 +1476,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, { struct sshbuf *b; const u_char *p; @@ -299,7 +299,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, +@@ -1466,6 +1497,8 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse userstyle"); @@ -309,7 +309,7 @@ index 2179553d..02b3eaaa 100644 authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); diff --git a/monitor.h b/monitor.h -index 3f8a9bea..9dcd9c29 100644 +index 3f8a9bea3..9dcd9c293 100644 --- a/monitor.h +++ b/monitor.h @@ -56,6 +56,10 @@ enum monitor_reqtype { @@ -324,10 +324,10 @@ index 3f8a9bea..9dcd9c29 100644 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 +index 33494b73f..347eb6870 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -442,6 +442,27 @@ mm_inform_authserv(char *service, char *style) +@@ -453,6 +453,27 @@ mm_inform_authserv(char *service, char *style) sshbuf_free(m); } @@ -356,10 +356,10 @@ index bd900b2f..ef3ab1b1 100644 int mm_auth_password(struct ssh *ssh, char *password) diff --git a/monitor_wrap.h b/monitor_wrap.h -index 7134afee..38a280c8 100644 +index c87295388..9b42ddbcb 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 *, +@@ -50,6 +50,9 @@ int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, const char *, const char *, u_int compat); void mm_inform_authserv(char *, char *); @@ -370,10 +370,10 @@ index 7134afee..38a280c8 100644 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 +index 53c87db6d..39531ae77 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in -@@ -100,7 +100,8 @@ PORTS= port-aix.o \ +@@ -102,7 +102,8 @@ PORTS= port-aix.o \ port-prngd.o \ port-solaris.o \ port-net.o \ @@ -385,7 +385,7 @@ index 1d549954..78e6fa5b 100644 $(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 +index 000000000..b9fbe38b7 --- /dev/null +++ b/openbsd-compat/port-linux-sshd.c @@ -0,0 +1,420 @@ @@ -810,7 +810,7 @@ index 00000000..b9fbe38b +#endif + diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index c1d54f38..7426f6f7 100644 +index c1d54f38d..7426f6f79 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -109,37 +109,6 @@ ssh_selinux_getctxbyname(char *pwname) @@ -865,7 +865,7 @@ index c1d54f38..7426f6f7 100644 /* 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 +index 959430de1..055c825e4 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -20,9 +20,10 @@ @@ -881,7 +881,7 @@ index 959430de..055c825e 100644 #ifdef LINUX_OOM_ADJUST diff --git a/platform.c b/platform.c -index 4c4fe57e..1bfb4bea 100644 +index fd1a7a7c2..bcf1b0491 100644 --- a/platform.c +++ b/platform.c @@ -140,7 +140,7 @@ platform_setusercontext_post_groups(struct passwd *pw) @@ -894,10 +894,10 @@ index 4c4fe57e..1bfb4bea 100644 } diff --git a/sshd-session.c b/sshd-session.c -index c64eb29f..74d2cbc7 100644 +index 8979f743b..cb4b0523d 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1328,6 +1328,9 @@ main(int ac, char **av) +@@ -1306,6 +1306,9 @@ main(int ac, char **av) restore_uid(); } #endif @@ -908,5 +908,5 @@ index c64eb29f..74d2cbc7 100644 if (options.use_pam) { do_pam_setcred(); -- -2.49.0 +2.52.0 diff --git a/0003-openssh-6.6p1-keycat.patch b/0002-openssh-6.6p1-keycat.patch similarity index 90% rename from 0003-openssh-6.6p1-keycat.patch rename to 0002-openssh-6.6p1-keycat.patch index b46b378..b196636 100644 --- a/0003-openssh-6.6p1-keycat.patch +++ b/0002-openssh-6.6p1-keycat.patch @@ -1,24 +1,24 @@ -From 5e35e18a419a5a66b6e1cb2b98beaaf4d9db0dc6 Mon Sep 17 00:00:00 2001 +From 5f16fff915643a515adbbd2e0cd12717938e3570 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 +Subject: [PATCH 02/53] 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 + + openbsd-compat/port-linux-sshd.c | 42 +++++- + openbsd-compat/port-linux.h | 1 + platform.c | 2 +- ssh-keycat.c | 241 +++++++++++++++++++++++++++++++ - 8 files changed, 314 insertions(+), 8 deletions(-) + 8 files changed, 312 insertions(+), 7 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 +index 000000000..630ec628c --- /dev/null +++ b/HOWTO.ssh-keycat @@ -0,0 +1,12 @@ @@ -35,7 +35,7 @@ index 00000000..630ec628 + + diff --git a/Makefile.in b/Makefile.in -index 4617cebc..438efc51 100644 +index ba17a79f0..a3a495c1b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -23,6 +23,7 @@ SSH_PROGRAM=@bindir@/ssh @@ -46,7 +46,7 @@ index 4617cebc..438efc51 100644 SSHD_SESSION=$(libexecdir)/sshd-session SSHD_AUTH=$(libexecdir)/sshd-auth SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper -@@ -57,6 +58,7 @@ CHANNELLIBS=@CHANNELLIBS@ +@@ -58,6 +59,7 @@ CHANNELLIBS=@CHANNELLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ SSHDLIBS=@SSHDLIBS@ @@ -54,16 +54,16 @@ index 4617cebc..438efc51 100644 LIBEDIT=@LIBEDIT@ LIBFIDO2=@LIBFIDO2@ LIBWTMPDB=@LIBWTMPDB@ -@@ -74,7 +76,7 @@ MKDIR_P=@MKDIR_P@ +@@ -75,7 +77,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) + LIBOPENSSH_OBJS=\ + ssh_api.o \ +@@ -252,6 +254,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) @@ -73,7 +73,7 @@ index 4617cebc..438efc51 100644 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: +@@ -439,6 +444,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) @@ -82,10 +82,10 @@ index 4617cebc..438efc51 100644 $(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 +index db5211013..fd632a5a8 100644 --- a/configure.ac +++ b/configure.ac -@@ -3566,6 +3566,7 @@ AC_ARG_WITH([pam], +@@ -3648,6 +3648,7 @@ AC_ARG_WITH([pam], PAM_MSG="yes" SSHDLIBS="$SSHDLIBS -lpam" @@ -93,7 +93,7 @@ index ee77a048..d546788c 100644 AC_DEFINE([USE_PAM], [1], [Define if you want to enable PAM support]) -@@ -3576,6 +3577,7 @@ AC_ARG_WITH([pam], +@@ -3658,6 +3659,7 @@ AC_ARG_WITH([pam], ;; *) SSHDLIBS="$SSHDLIBS -ldl" @@ -101,7 +101,7 @@ index ee77a048..d546788c 100644 ;; esac fi -@@ -4801,6 +4803,7 @@ AC_ARG_WITH([selinux], +@@ -4883,6 +4885,7 @@ AC_ARG_WITH([selinux], fi ] ) AC_SUBST([SSHDLIBS]) @@ -109,7 +109,7 @@ index ee77a048..d546788c 100644 # Check whether user wants Kerberos 5 support KRB5_MSG="no" -@@ -5812,6 +5815,9 @@ fi +@@ -5894,6 +5897,9 @@ fi if test ! -z "${SSHDLIBS}"; then echo " +for sshd: ${SSHDLIBS}" fi @@ -120,10 +120,10 @@ index ee77a048..d546788c 100644 echo "" diff --git a/misc.c b/misc.c -index c932f9bb..1e31acc9 100644 +index 5bed34735..7e27a38d1 100644 --- a/misc.c +++ b/misc.c -@@ -2897,6 +2897,13 @@ subprocess(const char *tag, const char *command, +@@ -2921,6 +2921,13 @@ subprocess(const char *tag, const char *command, error("%s: dup2: %s", tag, strerror(errno)); _exit(1); } @@ -138,7 +138,7 @@ index c932f9bb..1e31acc9 100644 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 +index b9fbe38b7..4d56745f7 100644 --- a/openbsd-compat/port-linux-sshd.c +++ b/openbsd-compat/port-linux-sshd.c @@ -52,6 +52,20 @@ extern ServerOptions options; @@ -225,32 +225,20 @@ index dfafc622..8c5fc1fe 100644 return; if (options.use_pam) { -@@ -420,7 +452,7 @@ sshd_selinux_copy_context(void) - { - security_context_t *ctx; - -- if (!ssh_selinux_enabled()) -+ if (!sshd_selinux_enabled()) - 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 +index 055c825e4..c004071d1 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 *); +@@ -24,6 +24,7 @@ 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 +index bcf1b0491..c92a0cba6 100644 --- a/platform.c +++ b/platform.c @@ -55,7 +55,7 @@ platform_setusercontext(struct passwd *pw) @@ -264,7 +252,7 @@ index 1bfb4bea..0d12f311 100644 #ifdef USE_SOLARIS_PROJECTS diff --git a/ssh-keycat.c b/ssh-keycat.c new file mode 100644 -index 00000000..5678be07 +index 000000000..5678be079 --- /dev/null +++ b/ssh-keycat.c @@ -0,0 +1,241 @@ @@ -510,5 +498,5 @@ index 00000000..5678be07 + return ev; +} -- -2.49.0 +2.52.0 diff --git a/0002-openssh-6.6p1-privsep-selinux.patch b/0002-openssh-6.6p1-privsep-selinux.patch deleted file mode 100644 index 32d3c64..0000000 --- a/0002-openssh-6.6p1-privsep-selinux.patch +++ /dev/null @@ -1,144 +0,0 @@ -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) - debug3_f("done"); - } - -+void -+sshd_selinux_copy_context(void) -+{ -+ security_context_t *ctx; -+ -+ if (!ssh_selinux_enabled()) -+ return; -+ -+ if (getexeccon((security_context_t *)&ctx) != 0) { -+ logit_f("getexeccon failed with %s", strerror(errno)); -+ return; -+ } -+ if (ctx != NULL) { -+ /* unset exec context before we will lose this capabililty */ -+ if (setexeccon(NULL) != 0) -+ fatal_f("setexeccon failed with %s", strerror(errno)); -+ if (setcon(ctx) != 0) -+ fatal_f("setcon failed with %s", strerror(errno)); -+ freecon(ctx); -+ } -+} -+ - #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) - - platform_setusercontext(pw); - -- if (platform_privileged_uidswap()) { -+ if (platform_privileged_uidswap() && !is_child) { - #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); -+#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) - /* Permanently switch to the desired uid. */ - permanently_set_uid(pw); - #endif -+ -+#ifdef WITH_SELINUX -+ if (in_chroot == 0) -+ sshd_selinux_copy_context(); -+#endif - } 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) - if (s->ttyfd != -1) { - fprintf(stderr, - "You must change your password now and log in 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) - argv[i] = NULL; - optind = optreset = 1; - __progname = argv[0]; --#ifdef WITH_SELINUX -- ssh_selinux_change_context("sftpd_t"); --#endif - 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 -+#ifdef WITH_SELINUX -+ ssh_selinux_change_context("sshd_net_t"); -+#endif -+ - /* 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) - * fd passing, as AFAIK PTY allocation on this platform doesn't require - * special privileges to begin with. - */ --#if defined(DISABLE_FD_PASSING) && !defined(HAVE_CYGWIN) -+#if defined(DISABLE_FD_PASSING) && !defined(HAVE_CYGWIN) && !defined(WITH_SELINUX) - skip_privdrop = 1; - #endif - --- -2.49.0 - diff --git a/0004-openssh-6.6p1-allow-ip-opts.patch b/0003-openssh-6.6p1-allow-ip-opts.patch similarity index 86% rename from 0004-openssh-6.6p1-allow-ip-opts.patch rename to 0003-openssh-6.6p1-allow-ip-opts.patch index ef15fbf..ea11b6c 100644 --- a/0004-openssh-6.6p1-allow-ip-opts.patch +++ b/0003-openssh-6.6p1-allow-ip-opts.patch @@ -1,17 +1,17 @@ -From 28333f1dfe68b0ffc80c2a4799759587b4c32d3e Mon Sep 17 00:00:00 2001 +From 7ffeef7e8218c544b6f4a09c5d43e9b748de5a5f 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 +Subject: [PATCH 03/53] 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 +index cb4b0523d..1c72e664a 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -778,12 +778,32 @@ check_ip_options(struct ssh *ssh) +@@ -754,12 +754,32 @@ check_ip_options(struct ssh *ssh) if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, &option_size) >= 0 && option_size != 0) { @@ -51,5 +51,5 @@ index 4a148db4..a365f26f 100644 #endif /* IP_OPTIONS */ } -- -2.49.0 +2.52.0 diff --git a/0005-openssh-5.9p1-ipv6man.patch b/0004-openssh-5.9p1-ipv6man.patch similarity index 86% rename from 0005-openssh-5.9p1-ipv6man.patch rename to 0004-openssh-5.9p1-ipv6man.patch index 909b988..6ec8afc 100644 --- a/0005-openssh-5.9p1-ipv6man.patch +++ b/0004-openssh-5.9p1-ipv6man.patch @@ -1,7 +1,7 @@ -From 388be633842a9f3e4b0a76fe40cf7035912a913a Mon Sep 17 00:00:00 2001 +From f653eed40e15c4c521ce683a604b46ed81cade6a 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 +Subject: [PATCH 04/53] openssh-5.9p1-ipv6man --- ssh.1 | 2 ++ @@ -9,7 +9,7 @@ Subject: [PATCH 05/50] openssh-5.9p1-ipv6man 2 files changed, 4 insertions(+) diff --git a/ssh.1 b/ssh.1 -index 697f4e42..db92ac9a 100644 +index 697f4e42a..db92ac9af 100644 --- a/ssh.1 +++ b/ssh.1 @@ -1663,6 +1663,8 @@ manual page for more information. @@ -22,7 +22,7 @@ index 697f4e42..db92ac9a 100644 .Xr scp 1 , .Xr sftp 1 , diff --git a/sshd.8 b/sshd.8 -index 08ebf53a..2aa73271 100644 +index 7fbca776a..0226a8303 100644 --- a/sshd.8 +++ b/sshd.8 @@ -1018,6 +1018,8 @@ concurrently for different ports, this contains the process ID of the one @@ -35,5 +35,5 @@ index 08ebf53a..2aa73271 100644 .Xr scp 1 , .Xr sftp 1 , -- -2.49.0 +2.52.0 diff --git a/0006-openssh-5.8p2-sigpipe.patch b/0005-openssh-5.8p2-sigpipe.patch similarity index 70% rename from 0006-openssh-5.8p2-sigpipe.patch rename to 0005-openssh-5.8p2-sigpipe.patch index 5bf31bc..a2a3714 100644 --- a/0006-openssh-5.8p2-sigpipe.patch +++ b/0005-openssh-5.8p2-sigpipe.patch @@ -1,17 +1,17 @@ -From 80359feb76fd8061b5ce18f73451d7b9db0c2477 Mon Sep 17 00:00:00 2001 +From 6ac14fb92cf0d0676f19282f30b9e427025be31b 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 +Subject: [PATCH 05/53] 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 +index f9788114d..11618ae8a 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c -@@ -798,6 +798,9 @@ main(int argc, char **argv) +@@ -776,6 +776,9 @@ main(int argc, char **argv) if (maxfd > fdlim_get(0)) fdlim_set(maxfd); fdcon = xcalloc(maxfd, sizeof(con)); @@ -22,5 +22,5 @@ index 3436c0b5..9f76ad22 100644 for (j = 0; j < maxfd; j++) read_wait[j].fd = -1; -- -2.49.0 +2.52.0 diff --git a/0007-openssh-7.2p2-x11.patch b/0006-openssh-7.2p2-x11.patch similarity index 84% rename from 0007-openssh-7.2p2-x11.patch rename to 0006-openssh-7.2p2-x11.patch index 2f72f9a..dceef7b 100644 --- a/0007-openssh-7.2p2-x11.patch +++ b/0006-openssh-7.2p2-x11.patch @@ -1,17 +1,17 @@ -From cf6d48305cf6601448ea7a0d96ae825cbbbf0a2c Mon Sep 17 00:00:00 2001 +From d6dc5be6e969ecffe30b9972706b3c92d930d81f 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 +Subject: [PATCH 06/53] 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 +index 80014ff34..5ce6bd400 100644 --- a/channels.c +++ b/channels.c -@@ -5098,11 +5098,13 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +@@ -5169,11 +5169,13 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, } static int @@ -26,7 +26,7 @@ index bfe2e3b2..d46531ce 100644 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) +@@ -5181,11 +5183,12 @@ connect_local_xsocket_path(const char *pathname) } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; @@ -42,7 +42,7 @@ index bfe2e3b2..d46531ce 100644 return -1; } -@@ -5122,8 +5125,18 @@ static int +@@ -5193,8 +5196,18 @@ static int connect_local_xsocket(u_int dnr) { char buf[1024]; @@ -64,5 +64,5 @@ index bfe2e3b2..d46531ce 100644 #ifdef __APPLE__ -- -2.49.0 +2.52.0 diff --git a/0008-openssh-5.1p1-askpass-progress.patch b/0007-openssh-5.1p1-askpass-progress.patch similarity index 94% rename from 0008-openssh-5.1p1-askpass-progress.patch rename to 0007-openssh-5.1p1-askpass-progress.patch index f7ca382..66b351e 100644 --- a/0008-openssh-5.1p1-askpass-progress.patch +++ b/0007-openssh-5.1p1-askpass-progress.patch @@ -1,14 +1,14 @@ -From 6b2a33044583e892badb9ac86cd2c6252b1a532f Mon Sep 17 00:00:00 2001 +From c62cd7ce2539c1eac6d0133c07441c617cbc7bc3 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 +Subject: [PATCH 07/53] 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 +index a62f98152..cb7152dc8 100644 --- a/contrib/gnome-ssh-askpass2.c +++ b/contrib/gnome-ssh-askpass2.c @@ -58,6 +58,7 @@ @@ -92,5 +92,5 @@ index a62f9815..cb7152dc 100644 /* Grab focus */ -- -2.49.0 +2.52.0 diff --git a/0009-openssh-4.3p2-askpass-grab-info.patch b/0008-openssh-4.3p2-askpass-grab-info.patch similarity index 87% rename from 0009-openssh-4.3p2-askpass-grab-info.patch rename to 0008-openssh-4.3p2-askpass-grab-info.patch index 8a7cf9e..8108482 100644 --- a/0009-openssh-4.3p2-askpass-grab-info.patch +++ b/0008-openssh-4.3p2-askpass-grab-info.patch @@ -1,14 +1,14 @@ -From 710ce53fdf1d32a0629fce2e42fb49d407e2b06c Mon Sep 17 00:00:00 2001 +From d124ab0f6eea910dc5f03cdd808f6fa792bf2b7a 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 +Subject: [PATCH 08/53] 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 +index cb7152dc8..bbe93d838 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) @@ -27,5 +27,5 @@ index cb7152dc..bbe93d83 100644 gtk_dialog_run(GTK_DIALOG(err)); -- -2.49.0 +2.52.0 diff --git a/0010-openssh-8.7p1-redhat.patch b/0009-openssh-8.7p1-redhat.patch similarity index 91% rename from 0010-openssh-8.7p1-redhat.patch rename to 0009-openssh-8.7p1-redhat.patch index cb3d140..8e75aa5 100644 --- a/0010-openssh-8.7p1-redhat.patch +++ b/0009-openssh-8.7p1-redhat.patch @@ -1,7 +1,7 @@ -From 5f21983f6472b26693babea4d6ca6b95a7dc7b05 Mon Sep 17 00:00:00 2001 +From c76607384ff077ba1c45759e749562cccaeaa335 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 +Subject: [PATCH 09/53] openssh-8.7p1-redhat --- ssh_config | 7 +++++++ @@ -17,10 +17,10 @@ Subject: [PATCH 10/50] openssh-8.7p1-redhat create mode 100644 sshd_config_redhat_cp diff --git a/ssh_config b/ssh_config -index cc566356..18169187 100644 +index 238a0c5e3..d9324c957 100644 --- a/ssh_config +++ b/ssh_config -@@ -44,3 +44,10 @@ +@@ -43,3 +43,10 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h # UserKnownHostsFile ~/.ssh/known_hosts.d/%k @@ -33,7 +33,7 @@ index cc566356..18169187 100644 +Include /etc/ssh/ssh_config.d/*.conf diff --git a/ssh_config_redhat b/ssh_config_redhat new file mode 100644 -index 00000000..8b1b5902 +index 000000000..8b1b59021 --- /dev/null +++ b/ssh_config_redhat @@ -0,0 +1,18 @@ @@ -56,7 +56,7 @@ index 00000000..8b1b5902 +# Uncomment this if you want to use .local domain +# Host *.local diff --git a/sshd_config b/sshd_config -index 0f4a3a72..608203e4 100644 +index 0f4a3a724..608203e4b 100644 --- a/sshd_config +++ b/sshd_config @@ -10,6 +10,14 @@ @@ -75,7 +75,7 @@ index 0f4a3a72..608203e4 100644 #AddressFamily any #ListenAddress 0.0.0.0 diff --git a/sshd_config.0 b/sshd_config.0 -index 2f77b4f4..49349bb3 100644 +index c63d729a9..8c5217c0b 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -1219,9 +1219,9 @@ DESCRIPTION @@ -92,10 +92,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 +index 6ae606f1e..aa9f0af76 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1942,7 +1942,7 @@ By default no subsystems are defined. +@@ -1941,7 +1941,7 @@ By default no subsystems are defined. .It Cm SyslogFacility Gives the facility code that is used when logging messages from .Xr sshd 8 . @@ -106,7 +106,7 @@ index c0771737..035a50c8 100644 .It Cm TCPKeepAlive diff --git a/sshd_config_redhat b/sshd_config_redhat new file mode 100644 -index 00000000..993a28d5 +index 000000000..993a28d52 --- /dev/null +++ b/sshd_config_redhat @@ -0,0 +1,18 @@ @@ -130,7 +130,7 @@ index 00000000..993a28d5 + diff --git a/sshd_config_redhat_cp b/sshd_config_redhat_cp new file mode 100644 -index 00000000..1d592d13 +index 000000000..1d592d13f --- /dev/null +++ b/sshd_config_redhat_cp @@ -0,0 +1,7 @@ @@ -142,5 +142,5 @@ index 00000000..1d592d13 +Include /etc/crypto-policies/back-ends/opensshserver.config + -- -2.49.0 +2.52.0 diff --git a/0011-openssh-7.8p1-UsePAM-warning.patch b/0010-openssh-7.8p1-UsePAM-warning.patch similarity index 81% rename from 0011-openssh-7.8p1-UsePAM-warning.patch rename to 0010-openssh-7.8p1-UsePAM-warning.patch index 76ee115..521abe4 100644 --- a/0011-openssh-7.8p1-UsePAM-warning.patch +++ b/0010-openssh-7.8p1-UsePAM-warning.patch @@ -1,7 +1,7 @@ -From 56b8d082bc9e25a77b5227d576f27088446c6fb9 Mon Sep 17 00:00:00 2001 +From 5f6dbc98a184ce485aef90321ae9fc1ba45293f8 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 +Subject: [PATCH 10/53] openssh-7.8p1-UsePAM-warning --- sshd-session.c | 4 ++++ @@ -9,10 +9,10 @@ Subject: [PATCH 11/50] openssh-7.8p1-UsePAM-warning 2 files changed, 6 insertions(+) diff --git a/sshd-session.c b/sshd-session.c -index a365f26f..a70b36c9 100644 +index 1c72e664a..9804dc334 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1127,6 +1127,10 @@ main(int ac, char **av) +@@ -1103,6 +1103,10 @@ main(int ac, char **av) "enabled authentication methods"); } @@ -24,7 +24,7 @@ index a365f26f..a70b36c9 100644 if (options.moduli_file != NULL) dh_set_moduli_file(options.moduli_file); diff --git a/sshd_config b/sshd_config -index 608203e4..48af6321 100644 +index 608203e4b..48af6321b 100644 --- a/sshd_config +++ b/sshd_config @@ -89,6 +89,8 @@ AuthorizedKeysFile .ssh/authorized_keys @@ -37,5 +37,5 @@ index 608203e4..48af6321 100644 #AllowAgentForwarding yes -- -2.49.0 +2.52.0 diff --git a/0012-openssh-9.6p1-gssapi-keyex.patch b/0011-openssh-9.6p1-gssapi-keyex.patch similarity index 94% rename from 0012-openssh-9.6p1-gssapi-keyex.patch rename to 0011-openssh-9.6p1-gssapi-keyex.patch index f5f54f7..2e5b723 100644 --- a/0012-openssh-9.6p1-gssapi-keyex.patch +++ b/0011-openssh-9.6p1-gssapi-keyex.patch @@ -1,7 +1,7 @@ -From 754b023b92aa68742258c55243a6ae8f30ed5a17 Mon Sep 17 00:00:00 2001 +From c992408da3ca7aeae129c731c7753019a16ed226 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 +Subject: [PATCH 11/53] openssh-9.6p1-gssapi-keyex --- Makefile.in | 7 +- @@ -13,10 +13,10 @@ Subject: [PATCH 12/50] openssh-9.6p1-gssapi-keyex canohost.h | 3 + clientloop.c | 12 + configure.ac | 24 ++ - gss-genr.c | 302 ++++++++++++++++++++- + gss-genr.c | 312 ++++++++++++++++++++- gss-serv-krb5.c | 97 ++++++- gss-serv.c | 200 ++++++++++++-- - kex-names.c | 62 ++++- + kex-names.c | 60 +++- kex.c | 35 ++- kex.h | 34 +++ kexdh.c | 10 + @@ -29,7 +29,7 @@ Subject: [PATCH 12/50] openssh-9.6p1-gssapi-keyex monitor_wrap.h | 4 +- readconf.c | 70 +++++ readconf.h | 6 + - servconf.c | 47 ++++ + servconf.c | 46 ++++ servconf.h | 3 + session.c | 10 +- ssh-gss.h | 64 ++++- @@ -38,30 +38,30 @@ Subject: [PATCH 12/50] openssh-9.6p1-gssapi-keyex ssh_config | 2 + ssh_config.5 | 58 ++++ sshconnect2.c | 154 ++++++++++- - sshd-auth.c | 53 ++++ + sshd-auth.c | 55 +++- 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(-) + 41 files changed, 2993 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 +index a3a495c1b..a36eb82ed 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -117,6 +117,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -108,6 +108,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 + sshbuf-io.o misc-agent.o -@@ -138,7 +139,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ +@@ -131,7 +132,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 \ @@ -70,7 +70,7 @@ index 438efc51..78f65948 100644 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 \ +@@ -143,7 +144,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 \ @@ -79,20 +79,20 @@ index 438efc51..78f65948 100644 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: +@@ -554,7 +555,7 @@ regress-prep: ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile REGRESSLIBS=libssh.a $(LIBCOMPAT) --TESTLIBS=$(LIBS) $(CHANNELLIBS) -+TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) +-TESTLIBS=$(LIBS) $(CHANNELLIBS) @TESTLIBS@ ++TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) @TESTLIBS@ 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 +index 8d9404743..d25653ee4 100644 --- a/auth.c +++ b/auth.c -@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) +@@ -354,7 +354,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -103,7 +103,7 @@ index 9a6e5a31..e4578169 100644 break; case PERMIT_FORCED_ONLY: diff --git a/auth2-gss.c b/auth2-gss.c -index f7898ab3..5b1b9cde 100644 +index f7898ab3e..5b1b9cde3 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -51,6 +51,7 @@ @@ -194,7 +194,7 @@ index f7898ab3..5b1b9cde 100644 &methodcfg_gssapi, userauth_gssapi, diff --git a/auth2-methods.c b/auth2-methods.c -index 99637a89..a05908cf 100644 +index 99637a89b..a05908cf3 100644 --- a/auth2-methods.c +++ b/auth2-methods.c @@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = { @@ -218,7 +218,7 @@ index 99637a89..a05908cf 100644 #endif &methodcfg_passwd, diff --git a/auth2.c b/auth2.c -index 5ba45c12..8ec41de2 100644 +index 1345d3257..5a4b932a9 100644 --- a/auth2.c +++ b/auth2.c @@ -71,6 +71,7 @@ extern Authmethod method_passwd; @@ -238,7 +238,7 @@ index 5ba45c12..8ec41de2 100644 #endif &method_passwd, diff --git a/canohost.c b/canohost.c -index 28f086e5..875805c9 100644 +index 28f086e5a..875805c99 100644 --- a/canohost.c +++ b/canohost.c @@ -35,6 +35,99 @@ @@ -342,7 +342,7 @@ index 28f086e5..875805c9 100644 ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) { diff --git a/canohost.h b/canohost.h -index 26d62855..0cadc9f1 100644 +index 26d62855a..0cadc9f18 100644 --- a/canohost.h +++ b/canohost.h @@ -15,6 +15,9 @@ @@ -356,10 +356,10 @@ index 26d62855..0cadc9f1 100644 int get_peer_port(int); char *get_local_ipaddr(int); diff --git a/clientloop.c b/clientloop.c -index 916fc077..4655f91f 100644 +index 49d048d85..33adf31dc 100644 --- a/clientloop.c +++ b/clientloop.c -@@ -115,6 +115,10 @@ +@@ -107,6 +107,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -370,7 +370,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, +@@ -1604,6 +1608,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, /* Do channel operations. */ channel_after_poll(ssh, pfd, npfd_active); @@ -386,10 +386,10 @@ index 916fc077..4655f91f 100644 if (conn_in_ready) client_process_net_input(ssh); diff --git a/configure.ac b/configure.ac -index d546788c..13c70a98 100644 +index fd632a5a8..adccaebd4 100644 --- a/configure.ac +++ b/configure.ac -@@ -786,6 +786,30 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +@@ -813,6 +813,30 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -421,7 +421,7 @@ index d546788c..13c70a98 100644 AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff --git a/gss-genr.c b/gss-genr.c -index aa34b71c..3034370c 100644 +index 8f1f54afb..f2d6f59e5 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -42,9 +42,33 @@ @@ -458,7 +458,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,169 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) return 0; } @@ -527,19 +527,29 @@ index aa34b71c..3034370c 100644 + for (i = 0; i < gss_supported->count; i++) { + if (gss_supported->elements[i].length < 128 && + (*check)(NULL, &(gss_supported->elements[i]), host, client)) { ++ EVP_MD_CTX * ctx = NULL; ++ EVP_MD *md5 = NULL; /* Here we don't use MD5 for crypto purposes */ ++ unsigned int md_size = sizeof(digest); + + deroid[0] = SSH_GSS_OIDTYPE; + deroid[1] = gss_supported->elements[i].length; -+ -+ if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || -+ (r = ssh_digest_update(md, deroid, 2)) != 0 || -+ (r = ssh_digest_update(md, -+ gss_supported->elements[i].elements, -+ gss_supported->elements[i].length)) != 0 || -+ (r = ssh_digest_final(md, digest, sizeof(digest))) != 0) ++ if ((md5 = EVP_MD_fetch(NULL, "MD5", "provider=default,-fips")) == NULL) ++ fatal_fr(r, "MD5 fetch failed"); ++ if ((ctx = EVP_MD_CTX_new()) == NULL) { ++ EVP_MD_free(md5); ++ fatal_fr(r, "digest ctx failed"); ++ } ++ if (EVP_DigestInit(ctx, md5) <= 0 ++ || EVP_DigestUpdate(ctx, deroid, 2) <= 0 ++ || EVP_DigestUpdate(ctx, gss_supported->elements[i].elements, ++ gss_supported->elements[i].length) <= 0 ++ || EVP_DigestFinal(ctx, digest, &md_size) <= 0) { ++ EVP_MD_free(md5); ++ EVP_MD_CTX_free(ctx); + fatal_fr(r, "digest failed"); -+ ssh_digest_free(md); -+ md = NULL; ++ } ++ EVP_MD_free(md5); md5 = NULL; ++ EVP_MD_CTX_free(ctx); ctx = NULL; + + encoded = xmalloc(ssh_digest_bytes(SSH_DIGEST_MD5) + * 2); @@ -618,7 +628,7 @@ index aa34b71c..3034370c 100644 /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -168,6 +345,7 @@ ssh_gssapi_build_ctx(Gssctxt **ctx) +@@ -168,6 +355,7 @@ ssh_gssapi_build_ctx(Gssctxt **ctx) (*ctx)->creds = GSS_C_NO_CREDENTIAL; (*ctx)->client = GSS_C_NO_NAME; (*ctx)->client_creds = GSS_C_NO_CREDENTIAL; @@ -626,7 +636,7 @@ index aa34b71c..3034370c 100644 } /* Delete our context, providing it has been built correctly */ -@@ -193,6 +371,12 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx) +@@ -193,6 +381,12 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx) gss_release_name(&ms, &(*ctx)->client); if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL) gss_release_cred(&ms, &(*ctx)->client_creds); @@ -639,7 +649,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 +410,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, } ctx->major = gss_init_sec_context(&ctx->minor, @@ -648,7 +658,7 @@ 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) +@@ -245,9 +439,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) return (ctx->major); } @@ -692,7 +702,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 +483,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) return (ctx->major); } @@ -712,7 +722,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 +512,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, } int @@ -730,7 +740,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 +531,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -741,7 +751,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 +544,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) GSS_C_NO_BUFFER); } @@ -810,7 +820,7 @@ index aa34b71c..3034370c 100644 + #endif /* GSSAPI */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index a151bc1e..8d2b677f 100644 +index a151bc1e4..8d2b677f7 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -1,7 +1,7 @@ @@ -950,11 +960,11 @@ index a151bc1e..8d2b677f 100644 #endif /* KRB5 */ diff --git a/gss-serv.c b/gss-serv.c -index 025a118f..a5cca797 100644 +index b0e9c3b49..6bac42931 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ - /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ + /* $OpenBSD: gss-serv.c,v 1.33 2025/09/29 21:30:15 dtucker Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1245,7 +1255,7 @@ index 025a118f..a5cca797 100644 /* Privileged */ diff --git a/kex-names.c b/kex-names.c -index ec840c1f..6c0b7c2b 100644 +index a20ce602a..31e395aa2 100644 --- a/kex-names.c +++ b/kex-names.c @@ -45,6 +45,10 @@ @@ -1259,22 +1269,22 @@ index ec840c1f..6c0b7c2b 100644 struct kexalg { char *name; u_int type; -@@ -89,15 +93,28 @@ static const struct kexalg kexalgs[] = { +@@ -90,9 +94,22 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, 0, -1, -1}, + { NULL, 0, -1, -1, 0 }, }; +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_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, ++ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, ++ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, ++ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, ++ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512, KEX_NOT_PQ }, + { 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 }, ++ NID_X9_62_prime256v1, SSH_DIGEST_SHA256, KEX_NOT_PQ }, ++ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, +#endif -+ { NULL, 0, -1, -1}, ++ { NULL, 0, -1, -1, 0}, +}; -char * @@ -1282,16 +1292,9 @@ index ec840c1f..6c0b7c2b 100644 +static char * +kex_alg_list_internal(char sep, const struct kexalg *algs) { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; + char *ret = NULL; 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) +@@ -104,6 +121,18 @@ kex_alg_list(char sep) return ret; } @@ -1310,7 +1313,7 @@ index ec840c1f..6c0b7c2b 100644 static const struct kexalg * kex_alg_by_name(const char *name) { -@@ -121,6 +150,10 @@ kex_alg_by_name(const char *name) +@@ -113,6 +142,10 @@ kex_alg_by_name(const char *name) if (strcmp(k->name, name) == 0) return k; } @@ -1321,7 +1324,7 @@ index ec840c1f..6c0b7c2b 100644 return NULL; } -@@ -334,3 +367,26 @@ kex_assemble_names(char **listp, const char *def, const char *all) +@@ -336,3 +369,26 @@ kex_assemble_names(char **listp, const char *def, const char *all) free(ret); return r; } @@ -1349,10 +1352,10 @@ index ec840c1f..6c0b7c2b 100644 + return 1; +} diff --git a/kex.c b/kex.c -index 6b957e5e..19a56e8e 100644 +index 814fad947..9a2ce6d88 100644 --- a/kex.c +++ b/kex.c -@@ -297,17 +297,37 @@ static int +@@ -295,17 +295,37 @@ static int kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m) { int r; @@ -1396,7 +1399,7 @@ index 6b957e5e..19a56e8e 100644 (r = sshbuf_put_cstring(m, "0")) != 0) { error_fr(r, "compose"); return r; -@@ -737,6 +757,9 @@ kex_free(struct kex *kex) +@@ -735,6 +755,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); sshbuf_free(kex->session_id); @@ -1407,7 +1410,7 @@ index 6b957e5e..19a56e8e 100644 sshkey_free(kex->initial_hostkey); free(kex->failed_choice); diff --git a/kex.h b/kex.h -index d08988b3..0e080ea3 100644 +index 55baa6a1e..206ce60ed 100644 --- a/kex.h +++ b/kex.h @@ -29,6 +29,10 @@ @@ -1437,7 +1440,7 @@ index d08988b3..0e080ea3 100644 KEX_MAX }; -@@ -165,6 +178,13 @@ struct kex { +@@ -169,6 +182,13 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1451,8 +1454,8 @@ index d08988b3..0e080ea3 100644 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 *); +@@ -196,8 +216,10 @@ int kex_nid_from_name(const char *); + int kex_is_pq_from_name(const char *); int kex_names_valid(const char *); char *kex_alg_list(char); +char *kex_gss_alg_list(char); @@ -1462,7 +1465,7 @@ index d08988b3..0e080ea3 100644 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 *); +@@ -231,6 +253,12 @@ int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kex_gen_client(struct ssh *); int kex_gen_server(struct ssh *); @@ -1475,7 +1478,7 @@ index d08988b3..0e080ea3 100644 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 *, +@@ -269,6 +297,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, const BIGNUM *, const u_char *, size_t, u_char *, size_t *); @@ -1489,10 +1492,10 @@ index d08988b3..0e080ea3 100644 __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); diff --git a/kexdh.c b/kexdh.c -index c1084f21..0faab21b 100644 +index 191bdced0..6d5a7813d 100644 --- a/kexdh.c +++ b/kexdh.c -@@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) +@@ -50,13 +50,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: @@ -1517,7 +1520,7 @@ index c1084f21..0faab21b 100644 break; case KEX_DH_GRP18_SHA512: diff --git a/kexgen.c b/kexgen.c -index 40d688d6..15df591c 100644 +index 494d4b233..58edc79ad 100644 --- a/kexgen.c +++ b/kexgen.c @@ -44,7 +44,7 @@ @@ -1531,7 +1534,7 @@ index 40d688d6..15df591c 100644 const struct sshbuf *client_version, diff --git a/kexgssc.c b/kexgssc.c new file mode 100644 -index 00000000..96f7b6f5 +index 000000000..96f7b6f58 --- /dev/null +++ b/kexgssc.c @@ -0,0 +1,706 @@ @@ -2243,7 +2246,7 @@ index 00000000..96f7b6f5 +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/kexgsss.c b/kexgsss.c new file mode 100644 -index 00000000..8362081e +index 000000000..8362081ea --- /dev/null +++ b/kexgsss.c @@ -0,0 +1,601 @@ @@ -2849,10 +2852,10 @@ index 00000000..8362081e + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/monitor.c b/monitor.c -index 02b3eaaa..2ef16cc8 100644 +index 85dc1b1b7..d463d6a9c 100644 --- a/monitor.c +++ b/monitor.c -@@ -147,6 +147,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); +@@ -137,6 +137,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); 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 +2864,7 @@ index 02b3eaaa..2ef16cc8 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -224,11 +226,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -214,11 +216,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}, @@ -2880,7 +2883,7 @@ index 02b3eaaa..2ef16cc8 100644 {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) +@@ -289,6 +298,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -2891,7 +2894,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) +@@ -341,8 +354,15 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { auth_log(ssh, authenticated, partial, auth_method, auth_submethod); @@ -2908,7 +2911,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) +@@ -429,6 +449,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2919,7 +2922,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) +@@ -1896,6 +1920,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2937,7 +2940,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) +@@ -1987,8 +2022,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; @@ -2948,7 +2951,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) +@@ -2020,8 +2055,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2959,7 +2962,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) +@@ -2041,6 +2076,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2967,7 +2970,7 @@ index 02b3eaaa..2ef16cc8 100644 } return (0); } -@@ -2046,8 +2082,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2052,8 +2088,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 ret; int r; @@ -2978,7 +2981,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) +@@ -2079,13 +2115,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -3000,7 +3003,7 @@ index 02b3eaaa..2ef16cc8 100644 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) +@@ -2094,7 +2134,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -3013,7 +3016,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) +@@ -2102,5 +2146,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -3099,7 +3102,7 @@ index 02b3eaaa..2ef16cc8 100644 #endif /* GSSAPI */ diff --git a/monitor.h b/monitor.h -index 9dcd9c29..dbc7e003 100644 +index 9dcd9c293..dbc7e0037 100644 --- a/monitor.h +++ b/monitor.h @@ -68,6 +68,8 @@ enum monitor_reqtype { @@ -3112,10 +3115,10 @@ index 9dcd9c29..dbc7e003 100644 struct ssh; diff --git a/monitor_wrap.c b/monitor_wrap.c -index ef3ab1b1..b6e3b3f3 100644 +index 347eb6870..08dc29e12 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) +@@ -1142,13 +1142,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int @@ -3132,7 +3135,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) +@@ -1161,6 +1163,59 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -3193,10 +3196,10 @@ index ef3ab1b1..b6e3b3f3 100644 /* diff --git a/monitor_wrap.h b/monitor_wrap.h -index 38a280c8..672dce52 100644 +index 9b42ddbcb..12c489c33 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); +@@ -71,8 +71,10 @@ void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); 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 *); @@ -3209,10 +3212,10 @@ index 38a280c8..672dce52 100644 #ifdef USE_PAM diff --git a/readconf.c b/readconf.c -index 7cbe7d2c..6c04ed43 100644 +index d99205944..eab734aaf 100644 --- a/readconf.c +++ b/readconf.c -@@ -71,6 +71,7 @@ +@@ -65,6 +65,7 @@ #include "myproposal.h" #include "digest.h" #include "version.h" @@ -3220,7 +3223,7 @@ index 7cbe7d2c..6c04ed43 100644 /* Format of the configuration file: -@@ -165,6 +166,8 @@ typedef enum { +@@ -159,6 +160,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -3229,7 +3232,7 @@ index 7cbe7d2c..6c04ed43 100644 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -212,10 +215,22 @@ static struct { +@@ -206,10 +209,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -3252,7 +3255,7 @@ index 7cbe7d2c..6c04ed43 100644 #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1320,10 +1335,42 @@ parse_time: +@@ -1326,10 +1341,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -3295,7 +3298,7 @@ index 7cbe7d2c..6c04ed43 100644 case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -2662,7 +2709,13 @@ initialize_options(Options * options) +@@ -2698,7 +2745,13 @@ initialize_options(Options * options) options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; options->gss_authentication = -1; @@ -3309,7 +3312,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) +@@ -2863,8 +2916,18 @@ fill_default_options(Options * options) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3328,7 +3331,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) +@@ -3692,7 +3755,14 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -3344,7 +3347,7 @@ index 7cbe7d2c..6c04ed43 100644 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 +index 942149f9a..b96e3279e 100644 --- a/readconf.h +++ b/readconf.h @@ -39,7 +39,13 @@ typedef struct { @@ -3362,10 +3365,10 @@ index cd49139b..368523dd 100644 * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --git a/servconf.c b/servconf.c -index f7bc9237..d4f7fd66 100644 +index 48ec8c4ec..3b93ca829 100644 --- a/servconf.c +++ b/servconf.c -@@ -69,6 +69,7 @@ +@@ -67,6 +67,7 @@ #include "myproposal.h" #include "digest.h" #include "version.h" @@ -3373,7 +3376,7 @@ index f7bc9237..d4f7fd66 100644 #if !defined(SSHD_PAM_SERVICE) # define SSHD_PAM_SERVICE "sshd" -@@ -138,8 +139,11 @@ initialize_server_options(ServerOptions *options) +@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3385,7 +3388,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) +@@ -374,10 +378,18 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3404,7 +3407,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 { +@@ -562,6 +574,7 @@ typedef enum { sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -3412,7 +3415,7 @@ index f7bc9237..d4f7fd66 100644 sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -653,12 +666,22 @@ static struct { +@@ -647,12 +660,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3435,7 +3438,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, +@@ -1643,6 +1666,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; @@ -3446,7 +3449,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, +@@ -1651,6 +1678,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3469,19 +3472,19 @@ index f7bc9237..d4f7fd66 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3254,6 +3297,10 @@ dump_config(ServerOptions *o) +@@ -3256,7 +3299,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); + dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); -+ dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); + dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); + dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --git a/servconf.h b/servconf.h -index 9beb90fa..c3f50140 100644 +index 9beb90fae..c3f501400 100644 --- a/servconf.h +++ b/servconf.h @@ -150,8 +150,11 @@ typedef struct { @@ -3497,10 +3500,10 @@ index 9beb90fa..c3f50140 100644 * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/session.c b/session.c -index e4657cef..cbfbcee8 100644 +index f265fdc3e..b8f0c1a58 100644 --- a/session.c +++ b/session.c -@@ -2670,13 +2670,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2630,13 +2630,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3523,7 +3526,7 @@ index e4657cef..cbfbcee8 100644 /* remove agent socket */ diff --git a/ssh-gss.h b/ssh-gss.h -index 7b14e74a..8ec45192 100644 +index 7b14e74a8..8ec451926 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -61,10 +61,36 @@ @@ -3651,7 +3654,7 @@ index 7b14e74a..8ec45192 100644 #endif /* _SSH_GSS_H */ diff --git a/ssh.1 b/ssh.1 -index db92ac9a..6a9fbdc5 100644 +index db92ac9af..6a9fbdc5b 100644 --- a/ssh.1 +++ b/ssh.1 @@ -539,9 +539,15 @@ For full details of the options listed below, and their possible values, see @@ -3680,10 +3683,10 @@ index db92ac9a..6a9fbdc5 100644 (key types), .Ar key-ca-sign diff --git a/ssh.c b/ssh.c -index dc4886d0..c23d3b9e 100644 +index 3b03108db..8d27f6379 100644 --- a/ssh.c +++ b/ssh.c -@@ -835,6 +835,8 @@ main(int ac, char **av) +@@ -847,6 +847,8 @@ main(int ac, char **av) else if (strcmp(optarg, "kex") == 0 || strcasecmp(optarg, "KexAlgorithms") == 0) cp = kex_alg_list('\n'); @@ -3692,7 +3695,7 @@ index dc4886d0..c23d3b9e 100644 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) +@@ -877,8 +879,8 @@ main(int ac, char **av) } else if (strcmp(optarg, "help") == 0) { cp = xstrdup( "cipher\ncipher-auth\ncompression\nkex\n" @@ -3704,7 +3707,7 @@ index dc4886d0..c23d3b9e 100644 if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); diff --git a/ssh_config b/ssh_config -index 18169187..209248d6 100644 +index d9324c957..ca7c5853b 100644 --- a/ssh_config +++ b/ssh_config @@ -24,6 +24,8 @@ @@ -3717,7 +3720,7 @@ index 18169187..209248d6 100644 # CheckHostIP no # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 -index 894d7383..3a8e246c 100644 +index f7066cbaa..8a4b469cf 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -976,10 +976,68 @@ The default is @@ -3790,7 +3793,7 @@ index 894d7383..3a8e246c 100644 Indicates that .Xr ssh 1 diff --git a/sshconnect2.c b/sshconnect2.c -index 1ee6000a..0af15bcc 100644 +index b3679c9d7..b253f991b 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, @@ -4023,10 +4026,19 @@ index 1ee6000a..0af15bcc 100644 static int diff --git a/sshd-auth.c b/sshd-auth.c -index f957dc22..d51e4636 100644 +index 9c31515de..5a4ee733c 100644 --- a/sshd-auth.c +++ b/sshd-auth.c -@@ -844,6 +844,48 @@ do_ssh2_kex(struct ssh *ssh) +@@ -696,7 +696,7 @@ main(int ac, char **av) + break; + } + } +- if (!have_key) ++ if (!have_key && !options.gss_keyex) + fatal("internal error: received no hostkeys"); + + /* Ensure that umask disallows at least group and world write */ +@@ -819,6 +819,48 @@ do_ssh2_kex(struct ssh *ssh) free(hkalgs); @@ -4075,7 +4087,7 @@ index f957dc22..d51e4636 100644 /* 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) +@@ -836,6 +878,17 @@ do_ssh2_kex(struct ssh *ssh) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif /* OPENSSL_HAS_ECC */ @@ -4094,10 +4106,10 @@ index f957dc22..d51e4636 100644 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 +index 9804dc334..6e28020e9 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -616,8 +616,8 @@ notify_hostkeys(struct ssh *ssh) +@@ -592,8 +592,8 @@ notify_hostkeys(struct ssh *ssh) } debug3_f("sent %u hostkeys", nkeys); if (nkeys == 0) @@ -4108,7 +4120,7 @@ index a70b36c9..f8c8a797 100644 sshpkt_fatal(ssh, r, "%s: send", __func__); sshbuf_free(buf); } -@@ -1159,8 +1159,9 @@ main(int ac, char **av) +@@ -1135,8 +1135,9 @@ main(int ac, char **av) break; } } @@ -4121,7 +4133,7 @@ index a70b36c9..f8c8a797 100644 /* 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 +index 3c76b60b0..3ab81e268 100644 --- a/sshd.c +++ b/sshd.c @@ -1676,7 +1676,8 @@ main(int ac, char **av) @@ -4135,7 +4147,7 @@ index 4a93e29e..c9ea8e38 100644 exit(1); } diff --git a/sshd_config b/sshd_config -index 48af6321..8db9f0fb 100644 +index 48af6321b..8db9f0fb1 100644 --- a/sshd_config +++ b/sshd_config @@ -79,6 +79,8 @@ AuthorizedKeysFile .ssh/authorized_keys @@ -4148,7 +4160,7 @@ index 48af6321..8db9f0fb 100644 # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will diff --git a/sshd_config.5 b/sshd_config.5 -index 035a50c8..8bc6586e 100644 +index aa9f0af76..b90068bf3 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -739,6 +739,11 @@ Specifies whether to automatically destroy the user's credentials cache @@ -4197,12 +4209,12 @@ index 035a50c8..8bc6586e 100644 Specifies the signature algorithms that will be accepted for hostbased authentication as a list of comma-separated patterns. diff --git a/sshkey.c b/sshkey.c -index ab80752b..4e41a78c 100644 +index afd7822c4..148fee2b7 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -129,6 +129,75 @@ extern const struct sshkey_impl sshkey_xmss_impl; - extern const struct sshkey_impl sshkey_xmss_cert_impl; - #endif +@@ -114,6 +114,75 @@ extern const struct sshkey_impl sshkey_rsa_sha512_impl; + extern const struct sshkey_impl sshkey_rsa_sha512_cert_impl; + #endif /* WITH_OPENSSL */ +static int ssh_gss_equal(const struct sshkey *, const struct sshkey *) +{ @@ -4276,15 +4288,15 @@ 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[] = { - &sshkey_xmss_impl, - &sshkey_xmss_cert_impl, - #endif +@@ -144,6 +213,7 @@ const struct sshkey_impl * const keyimpls[] = { + &sshkey_rsa_sha512_impl, + &sshkey_rsa_sha512_cert_impl, + #endif /* WITH_OPENSSL */ + &sshkey_gss_kex_impl, NULL }; -@@ -336,7 +406,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -314,7 +384,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -4294,10 +4306,10 @@ index ab80752b..4e41a78c 100644 if (!include_sigonly && impl->sigonly) continue; diff --git a/sshkey.h b/sshkey.h -index 19bbbac7..4a318d05 100644 +index c3262b896..931d1f79b 100644 --- a/sshkey.h +++ b/sshkey.h -@@ -75,6 +75,7 @@ enum sshkey_types { +@@ -67,6 +67,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, KEY_ED25519_SK_CERT, @@ -4306,5 +4318,5 @@ index 19bbbac7..4a318d05 100644 }; -- -2.49.0 +2.52.0 diff --git a/0013-openssh-6.6p1-force_krb.patch b/0012-openssh-6.6p1-force_krb.patch similarity index 96% rename from 0013-openssh-6.6p1-force_krb.patch rename to 0012-openssh-6.6p1-force_krb.patch index 74643b5..70f75fb 100644 --- a/0013-openssh-6.6p1-force_krb.patch +++ b/0012-openssh-6.6p1-force_krb.patch @@ -1,7 +1,7 @@ -From f5e5ee321def2a3674600714ad98fd1ca9b2cff1 Mon Sep 17 00:00:00 2001 +From 577b0fea53270292bd0b4979eb5369619b2f5adb 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 +Subject: [PATCH 12/53] openssh-6.6p1-force_krb --- gss-serv-krb5.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++- @@ -11,7 +11,7 @@ Subject: [PATCH 13/50] openssh-6.6p1-force_krb 4 files changed, 189 insertions(+), 1 deletion(-) diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 8d2b677f..14502c5a 100644 +index 8d2b677f7..14502c5a6 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -32,7 +32,9 @@ @@ -217,10 +217,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 b8f0c1a58..3eae5bdf3 100644 --- a/session.c +++ b/session.c -@@ -680,6 +680,29 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -642,6 +642,29 @@ do_exec(struct ssh *ssh, Session *s, const char *command) command = auth_opts->force_command; forced = "(key-option)"; } @@ -251,7 +251,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 8ec451926..db34d77f4 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -49,6 +49,10 @@ @@ -266,7 +266,7 @@ index 8ec45192..db34d77f 100644 /* draft-ietf-secsh-gsskeyex-06 */ diff --git a/sshd.8 b/sshd.8 -index 2aa73271..049d0a94 100644 +index 0226a8303..e2d8ff003 100644 --- a/sshd.8 +++ b/sshd.8 @@ -286,6 +286,7 @@ Finally, the server and the client enter an authentication dialog. @@ -291,5 +291,5 @@ index 2aa73271..049d0a94 100644 This directory is the default location for all user-specific configuration and authentication information. -- -2.49.0 +2.52.0 diff --git a/0014-openssh-7.7p1-gssapi-new-unique.patch b/0013-openssh-7.7p1-gssapi-new-unique.patch similarity index 94% rename from 0014-openssh-7.7p1-gssapi-new-unique.patch rename to 0013-openssh-7.7p1-gssapi-new-unique.patch index 1d21839..89fb40d 100644 --- a/0014-openssh-7.7p1-gssapi-new-unique.patch +++ b/0013-openssh-7.7p1-gssapi-new-unique.patch @@ -1,7 +1,7 @@ -From 5fca5946aa97dce23c6824c52b070a92532752a9 Mon Sep 17 00:00:00 2001 +From 1a5b32dbf550467a4ae19351667bcfdf9c52e44d 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 +Subject: [PATCH 13/53] openssh-7.7p1-gssapi-new-unique --- auth-krb5.c | 262 ++++++++++++++++++++++++++++++++++++++++++------ @@ -17,7 +17,7 @@ Subject: [PATCH 14/50] openssh-7.7p1-gssapi-new-unique 10 files changed, 279 insertions(+), 71 deletions(-) diff --git a/auth-krb5.c b/auth-krb5.c -index c99e4e43..77714e3d 100644 +index 9d2f1f0ea..035032221 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -51,6 +51,7 @@ @@ -339,7 +339,7 @@ index c99e4e43..77714e3d 100644 #endif /* !HEIMDAL */ #endif /* KRB5 */ diff --git a/auth.h b/auth.h -index 83d07ae8..10e88e11 100644 +index 83d07ae8b..10e88e11f 100644 --- a/auth.h +++ b/auth.h @@ -85,6 +85,7 @@ struct Authctxt { @@ -360,7 +360,7 @@ index 83d07ae8..10e88e11 100644 #endif /* AUTH_H */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 14502c5a..df55512d 100644 +index 14502c5a6..df55512d3 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, @@ -475,7 +475,7 @@ index 14502c5a..df55512d 100644 int diff --git a/gss-serv.c b/gss-serv.c -index a5cca797..9d5435ed 100644 +index 6bac42931..d2bc03486 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void) @@ -508,10 +508,10 @@ index a5cca797..9d5435ed 100644 ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); diff --git a/servconf.c b/servconf.c -index d4f7fd66..55aa5bf0 100644 +index 3b93ca829..7bf1507df 100644 --- a/servconf.c +++ b/servconf.c -@@ -138,6 +138,7 @@ initialize_server_options(ServerOptions *options) +@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions *options) options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -519,7 +519,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) +@@ -376,6 +377,8 @@ fill_default_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = 1; if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; @@ -528,7 +528,7 @@ index d4f7fd66..55aa5bf0 100644 if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) -@@ -564,7 +567,7 @@ typedef enum { +@@ -558,7 +561,7 @@ typedef enum { sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -537,7 +537,7 @@ index d4f7fd66..55aa5bf0 100644 sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, -@@ -655,11 +658,13 @@ static struct { +@@ -649,11 +652,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -551,7 +551,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, +@@ -1662,6 +1667,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->kerberos_get_afs_token; goto parse_flag; @@ -562,7 +562,7 @@ index d4f7fd66..55aa5bf0 100644 case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; -@@ -3293,6 +3302,7 @@ dump_config(ServerOptions *o) +@@ -3295,6 +3304,7 @@ dump_config(ServerOptions *o) # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif @@ -571,7 +571,7 @@ index d4f7fd66..55aa5bf0 100644 #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff --git a/servconf.h b/servconf.h -index c3f50140..a4a38d6d 100644 +index c3f501400..a4a38d6d7 100644 --- a/servconf.h +++ b/servconf.h @@ -149,6 +149,8 @@ typedef struct { @@ -584,10 +584,10 @@ index c3f50140..a4a38d6d 100644 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 +index 3eae5bdf3..b8a2dae92 100644 --- a/session.c +++ b/session.c -@@ -1025,7 +1025,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +@@ -987,7 +987,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) /* Allow any GSSAPI methods that we've used to alter * the child's environment as they see fit */ @@ -597,7 +597,7 @@ index 89b3a9cf..2620dd11 100644 #endif /* Set basic environment. */ -@@ -1101,7 +1102,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +@@ -1063,7 +1064,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) } #endif #ifdef KRB5 @@ -607,7 +607,7 @@ index 89b3a9cf..2620dd11 100644 s->authctxt->krb5_ccname); #endif diff --git a/ssh-gss.h b/ssh-gss.h -index db34d77f..a894e23c 100644 +index db34d77f4..a894e23c9 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -116,7 +116,7 @@ typedef struct ssh_gssapi_mech_struct { @@ -629,10 +629,10 @@ index db34d77f..a894e23c 100644 char *ssh_gssapi_server_mechanisms(void); diff --git a/sshd-session.c b/sshd-session.c -index f8c8a797..478381db 100644 +index 6e28020e9..028d5850e 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1349,7 +1349,7 @@ main(int ac, char **av) +@@ -1327,7 +1327,7 @@ main(int ac, char **av) #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(authctxt->pw); @@ -642,10 +642,10 @@ index f8c8a797..478381db 100644 } #endif diff --git a/sshd_config.5 b/sshd_config.5 -index 8bc6586e..1251d4d5 100644 +index b90068bf3..cae0fd0b4 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1033,6 +1033,14 @@ Specifies whether to automatically destroy the user's ticket cache +@@ -1032,6 +1032,14 @@ Specifies whether to automatically destroy the user's ticket cache file on logout. The default is .Cm yes . @@ -661,5 +661,5 @@ index 8bc6586e..1251d4d5 100644 Specifies the permitted KEX (Key Exchange) algorithms that the server will offer to clients. -- -2.49.0 +2.52.0 diff --git a/0015-openssh-7.2p2-k5login_directory.patch b/0014-openssh-7.2p2-k5login_directory.patch similarity index 91% rename from 0015-openssh-7.2p2-k5login_directory.patch rename to 0014-openssh-7.2p2-k5login_directory.patch index 5e980c8..fa07e55 100644 --- a/0015-openssh-7.2p2-k5login_directory.patch +++ b/0014-openssh-7.2p2-k5login_directory.patch @@ -1,7 +1,7 @@ -From 25540939422660b024b8832f67eab82267aa8df6 Mon Sep 17 00:00:00 2001 +From 0b19c3dabb1e23837238e90238f1ab5fa3c99df8 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 +Subject: [PATCH 14/53] openssh-7.2p2-k5login_directory --- auth-krb5.c | 16 ++++++++++++++++ @@ -11,7 +11,7 @@ Subject: [PATCH 15/50] openssh-7.2p2-k5login_directory 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/auth-krb5.c b/auth-krb5.c -index 77714e3d..74f56d47 100644 +index 035032221..4910aa38a 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 @@ -37,7 +37,7 @@ index 77714e3d..74f56d47 100644 #endif /* !HEIMDAL */ #endif /* KRB5 */ diff --git a/auth.h b/auth.h -index 10e88e11..39163035 100644 +index 10e88e11f..391630350 100644 --- a/auth.h +++ b/auth.h @@ -247,6 +247,8 @@ int sys_auth_passwd(struct ssh *, const char *); @@ -50,7 +50,7 @@ index 10e88e11..39163035 100644 #endif /* AUTH_H */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index df55512d..820f794c 100644 +index df55512d3..820f794cf 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -144,8 +144,27 @@ ssh_gssapi_k5login_exists() @@ -83,7 +83,7 @@ index df55512d..820f794c 100644 } diff --git a/sshd.8 b/sshd.8 -index 049d0a94..6784286d 100644 +index e2d8ff003..fa33f5232 100644 --- a/sshd.8 +++ b/sshd.8 @@ -880,6 +880,10 @@ rlogin/rsh. @@ -98,5 +98,5 @@ index 049d0a94..6784286d 100644 .It Pa ~/.ssh/ This directory is the default location for all user-specific configuration -- -2.49.0 +2.52.0 diff --git a/0016-openssh-6.6p1-kuserok.patch b/0015-openssh-6.6p1-kuserok.patch similarity index 94% rename from 0016-openssh-6.6p1-kuserok.patch rename to 0015-openssh-6.6p1-kuserok.patch index 3724b8d..a403c7c 100644 --- a/0016-openssh-6.6p1-kuserok.patch +++ b/0015-openssh-6.6p1-kuserok.patch @@ -1,7 +1,7 @@ -From bac7a9d1a654c8c2e0c71f979195e300b25d6232 Mon Sep 17 00:00:00 2001 +From d0c2e8ddde548c79144547152b523346ae9f0358 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 +Subject: [PATCH 15/53] openssh-6.6p1-kuserok --- auth-krb5.c | 20 ++++++++- @@ -13,7 +13,7 @@ Subject: [PATCH 16/50] openssh-6.6p1-kuserok 6 files changed, 139 insertions(+), 7 deletions(-) diff --git a/auth-krb5.c b/auth-krb5.c -index 74f56d47..bae153c9 100644 +index 4910aa38a..b9c261a24 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -55,6 +55,21 @@ @@ -51,7 +51,7 @@ index 74f56d47..bae153c9 100644 goto out; } diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 820f794c..187faf92 100644 +index 820f794cf..187faf929 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 *, @@ -189,10 +189,10 @@ 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 +index 7bf1507df..8f4b2b43e 100644 --- a/servconf.c +++ b/servconf.c -@@ -145,6 +145,7 @@ initialize_server_options(ServerOptions *options) +@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions *options) options->gss_strict_acceptor = -1; options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; @@ -200,7 +200,7 @@ index 55aa5bf0..5dd5ca21 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -399,6 +400,8 @@ fill_default_server_options(ServerOptions *options) +@@ -393,6 +394,8 @@ fill_default_server_options(ServerOptions *options) if (options->gss_kex_algorithms == NULL) options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); #endif @@ -209,7 +209,7 @@ 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 { +@@ -561,7 +564,7 @@ typedef enum { sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -218,7 +218,7 @@ index 55aa5bf0..5dd5ca21 100644 sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, -@@ -659,12 +662,14 @@ static struct { +@@ -653,12 +656,14 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif { "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL }, @@ -233,7 +233,7 @@ 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, +@@ -2431,6 +2436,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, } break; @@ -244,7 +244,7 @@ index 55aa5bf0..5dd5ca21 100644 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) +@@ -2997,6 +3006,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(client_alive_interval); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); @@ -252,7 +252,7 @@ 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) +@@ -3305,6 +3315,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); @@ -261,7 +261,7 @@ index 55aa5bf0..5dd5ca21 100644 #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff --git a/servconf.h b/servconf.h -index a4a38d6d..11de36a2 100644 +index a4a38d6d7..11de36a23 100644 --- a/servconf.h +++ b/servconf.h @@ -151,6 +151,7 @@ typedef struct { @@ -273,7 +273,7 @@ index a4a38d6d..11de36a2 100644 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 +index 8db9f0fb1..ea5a878e6 100644 --- a/sshd_config +++ b/sshd_config @@ -75,6 +75,7 @@ AuthorizedKeysFile .ssh/authorized_keys @@ -285,10 +285,10 @@ index 8db9f0fb..ea5a878e 100644 # GSSAPI options #GSSAPIAuthentication no diff --git a/sshd_config.5 b/sshd_config.5 -index 1251d4d5..0fcb409a 100644 +index cae0fd0b4..c360fcfff 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1041,6 +1041,10 @@ The default value +@@ -1040,6 +1040,10 @@ The default value .Cm no can lead to overwriting previous tickets by subseqent connections to the same user account. @@ -299,7 +299,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 +@@ -1354,6 +1358,7 @@ Available keywords are .Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , @@ -308,5 +308,5 @@ index 1251d4d5..0fcb409a 100644 .Cm MaxAuthTries , .Cm MaxSessions , -- -2.49.0 +2.52.0 diff --git a/0017-openssh-6.4p1-fromto-remote.patch b/0016-openssh-6.4p1-fromto-remote.patch similarity index 73% rename from 0017-openssh-6.4p1-fromto-remote.patch rename to 0016-openssh-6.4p1-fromto-remote.patch index 5e8309d..2a2575e 100644 --- a/0017-openssh-6.4p1-fromto-remote.patch +++ b/0016-openssh-6.4p1-fromto-remote.patch @@ -1,17 +1,17 @@ -From 20aabb2c445e29d211266ce7434bb0273edf88b9 Mon Sep 17 00:00:00 2001 +From d755d647c33f96cd4ec7d5499d11ecd443bdb098 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 +Subject: [PATCH 16/53] 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 +index c5f573cc1..d97a54cc4 100644 --- a/scp.c +++ b/scp.c -@@ -1162,7 +1162,10 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) +@@ -1148,7 +1148,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"); @@ -24,5 +24,5 @@ index 57c242ff..716ae386 100644 addargs(&alist, "%s", remote_remote_args.list[j]); -- -2.49.0 +2.52.0 diff --git a/0019-openssh-6.6.1p1-log-in-chroot.patch b/0017-openssh-6.6.1p1-log-in-chroot.patch similarity index 83% rename from 0019-openssh-6.6.1p1-log-in-chroot.patch rename to 0017-openssh-6.6.1p1-log-in-chroot.patch index 3b30f98..6704616 100644 --- a/0019-openssh-6.6.1p1-log-in-chroot.patch +++ b/0017-openssh-6.6.1p1-log-in-chroot.patch @@ -1,7 +1,7 @@ -From 825018f5f2d892655f3d63167a0d1f3391cec678 Mon Sep 17 00:00:00 2001 +From 674851677d1e38cf6992948f8f452e46107a2014 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 +Subject: [PATCH 17/53] openssh-6.6.1p1-log-in-chroot --- log.c | 11 +++++++++-- @@ -16,7 +16,7 @@ Subject: [PATCH 19/50] openssh-6.6.1p1-log-in-chroot 9 files changed, 52 insertions(+), 22 deletions(-) diff --git a/log.c b/log.c -index 6617f267..9782cfb0 100644 +index 5969c4a16..49b0c8a68 100644 --- a/log.c +++ b/log.c @@ -196,6 +196,11 @@ void @@ -45,7 +45,7 @@ index 6617f267..9782cfb0 100644 log_on_stderr = on_stderr; if (on_stderr) diff --git a/log.h b/log.h -index 8e8dfc23..70048a8a 100644 +index 8e8dfc23f..70048a8af 100644 --- a/log.h +++ b/log.h @@ -52,6 +52,7 @@ typedef enum { @@ -57,10 +57,10 @@ index 8e8dfc23..70048a8a 100644 int log_change_level(LogLevel); int log_is_on_stderr(void); diff --git a/monitor.c b/monitor.c -index 2ef16cc8..43c10a4e 100644 +index d463d6a9c..453469665 100644 --- a/monitor.c +++ b/monitor.c -@@ -2001,9 +2001,22 @@ monitor_init(void) +@@ -2007,9 +2007,22 @@ monitor_init(void) } void @@ -86,7 +86,7 @@ index 2ef16cc8..43c10a4e 100644 #ifdef GSSAPI diff --git a/monitor.h b/monitor.h -index dbc7e003..d4d631dd 100644 +index dbc7e0037..d4d631ddc 100644 --- a/monitor.h +++ b/monitor.h @@ -85,7 +85,7 @@ struct monitor { @@ -99,10 +99,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 +index b8a2dae92..d034f5c65 100644 --- a/session.c +++ b/session.c -@@ -169,6 +169,7 @@ login_cap_t *lc; +@@ -162,6 +162,7 @@ login_cap_t *lc; static int is_child = 0; static int in_chroot = 0; @@ -110,7 +110,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) +@@ -632,6 +633,7 @@ do_exec(struct ssh *ssh, Session *s, const char *command) int ret; const char *forced = NULL, *tty = NULL; char session_type[1024]; @@ -118,7 +118,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) +@@ -691,6 +693,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command) tty += 5; } @@ -129,7 +129,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) +@@ -1469,14 +1475,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 +144,7 @@ index 2620dd11..54da09d5 100644 } /* -@@ -1652,8 +1650,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1609,8 +1607,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) exit(1); } @@ -153,10 +153,10 @@ 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) - argv[i] = NULL; - optind = optreset = 1; - __progname = argv[0]; +@@ -1638,9 +1634,17 @@ do_child(struct ssh *ssh, Session *s, const char *command) + #ifdef WITH_SELINUX + ssh_selinux_change_context("sftpd_t"); + #endif - exit(sftp_server_main(i, argv, s->pw)); + exit(sftp_server_main(i, argv, s->pw, have_dev_log)); } @@ -173,7 +173,7 @@ index 2620dd11..54da09d5 100644 /* Get the last component of the shell name. */ diff --git a/sftp-server-main.c b/sftp-server-main.c -index 2c70f89b..bbb79f27 100644 +index 2c70f89bc..bbb79f278 100644 --- a/sftp-server-main.c +++ b/sftp-server-main.c @@ -48,5 +48,5 @@ main(int argc, char **argv) @@ -184,10 +184,10 @@ index 2c70f89b..bbb79f27 100644 + return (sftp_server_main(argc, argv, user_pw, 0)); } diff --git a/sftp-server.c b/sftp-server.c -index a4abb9f7..4985da38 100644 +index 777821acd..185ad1459 100644 --- a/sftp-server.c +++ b/sftp-server.c -@@ -1901,7 +1901,7 @@ sftp_server_usage(void) +@@ -1897,7 +1897,7 @@ sftp_server_usage(void) } int @@ -196,7 +196,7 @@ index a4abb9f7..4985da38 100644 { 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) +@@ -1909,7 +1909,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) extern char *__progname; __progname = ssh_get_progname(argv[0]); @@ -205,7 +205,7 @@ index a4abb9f7..4985da38 100644 pw = pwcopy(user_pw); -@@ -1986,7 +1986,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) +@@ -1982,7 +1982,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) } } @@ -215,7 +215,7 @@ 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 +index 2bde8bb7f..ddf1a3968 100644 --- a/sftp.h +++ b/sftp.h @@ -97,5 +97,5 @@ @@ -226,10 +226,10 @@ index 2bde8bb7..ddf1a396 100644 +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 +index 028d5850e..4a5eaa1ff 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -437,7 +437,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -415,7 +415,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) #endif /* New socket pair */ @@ -238,7 +238,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) +@@ -434,6 +434,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; @@ -251,5 +251,5 @@ index 478381db..9342e416 100644 /* Demote the private keys to public keys. */ demote_sensitive_data(); -- -2.49.0 +2.52.0 diff --git a/0020-openssh-6.6.1p1-scp-non-existing-directory.patch b/0018-openssh-6.6.1p1-scp-non-existing-directory.patch similarity index 65% rename from 0020-openssh-6.6.1p1-scp-non-existing-directory.patch rename to 0018-openssh-6.6.1p1-scp-non-existing-directory.patch index 94c43ef..e50e1c2 100644 --- a/0020-openssh-6.6.1p1-scp-non-existing-directory.patch +++ b/0018-openssh-6.6.1p1-scp-non-existing-directory.patch @@ -1,17 +1,17 @@ -From 007ee98fa9100f7241985ac2a7eed71e17d89a9f Mon Sep 17 00:00:00 2001 +From 931f22f77ab2b9cebd96e113f1e3ab179dd1b6cb 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 +Subject: [PATCH 18/53] 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 +index d97a54cc4..e1992622f 100644 --- a/scp.c +++ b/scp.c -@@ -1876,6 +1876,10 @@ sink(int argc, char **argv, const char *src) +@@ -1866,6 +1866,10 @@ sink(int argc, char **argv, const char *src) free(vect[0]); continue; } @@ -23,5 +23,5 @@ index 716ae386..9554b188 100644 mode |= S_IWUSR; if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { -- -2.49.0 +2.52.0 diff --git a/0018-openssh-6.6.1p1-selinux-contexts.patch b/0018-openssh-6.6.1p1-selinux-contexts.patch deleted file mode 100644 index 49f2119..0000000 --- a/0018-openssh-6.6.1p1-selinux-contexts.patch +++ /dev/null @@ -1,147 +0,0 @@ -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 ---- a/openbsd-compat/port-linux-sshd.c -+++ b/openbsd-compat/port-linux-sshd.c -@@ -33,6 +33,7 @@ - #include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ - #include "servconf.h" - #include "port-linux.h" -+#include "misc.h" - #include "sshkey.h" - #include "hostfile.h" - #include "auth.h" -@@ -450,7 +451,7 @@ sshd_selinux_setup_exec_context(char *pwname) - void - sshd_selinux_copy_context(void) - { -- security_context_t *ctx; -+ char *ctx; - - if (!sshd_selinux_enabled()) - return; -@@ -469,6 +470,72 @@ sshd_selinux_copy_context(void) - } - } - -+void -+sshd_selinux_change_privsep_preauth_context(void) -+{ -+ int len; -+ char line[1024], *preauth_context = NULL, *cp, *arg; -+ const char *contexts_path; -+ FILE *contexts_file; -+ struct stat sb; -+ -+ contexts_path = selinux_openssh_contexts_path(); -+ if (contexts_path == NULL) { -+ debug3_f("Failed to get the path to SELinux context"); -+ return; -+ } -+ -+ if ((contexts_file = fopen(contexts_path, "r")) == NULL) { -+ debug_f("Failed to open SELinux context file"); -+ return; -+ } -+ -+ if (fstat(fileno(contexts_file), &sb) != 0 || -+ sb.st_uid != 0 || (sb.st_mode & 022) != 0) { -+ logit_f("SELinux context file needs to be owned by root" -+ " and not writable by anyone else"); -+ fclose(contexts_file); -+ return; -+ } -+ -+ while (fgets(line, sizeof(line), contexts_file)) { -+ /* Strip trailing whitespace */ -+ for (len = strlen(line) - 1; len > 0; len--) { -+ if (strchr(" \t\r\n", line[len]) == NULL) -+ break; -+ line[len] = '\0'; -+ } -+ -+ if (line[0] == '\0') -+ continue; -+ -+ cp = line; -+ arg = strdelim(&cp); -+ if (arg && *arg == '\0') -+ arg = strdelim(&cp); -+ -+ if (arg && strcmp(arg, "privsep_preauth") == 0) { -+ arg = strdelim(&cp); -+ if (!arg || *arg == '\0') { -+ debug_f("privsep_preauth is empty"); -+ fclose(contexts_file); -+ return; -+ } -+ preauth_context = xstrdup(arg); -+ } -+ } -+ fclose(contexts_file); -+ -+ if (preauth_context == NULL) { -+ debug_f("Unable to find 'privsep_preauth' option in" -+ " SELinux context file"); -+ return; -+ } -+ -+ ssh_selinux_change_context(preauth_context); -+ free(preauth_context); -+} -+ - #endif - #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) - 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 ---- a/openbsd-compat/port-linux.h -+++ b/openbsd-compat/port-linux.h -@@ -27,6 +27,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); -+void sshd_selinux_change_privsep_preauth_context(void); - #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 - #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/0019-openssh-6.6p1-GSSAPIEnablek5users.patch similarity index 87% rename from 0021-openssh-6.6p1-GSSAPIEnablek5users.patch rename to 0019-openssh-6.6p1-GSSAPIEnablek5users.patch index eeff02a..4c0a60b 100644 --- a/0021-openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/0019-openssh-6.6p1-GSSAPIEnablek5users.patch @@ -1,7 +1,7 @@ -From 9c75c175e3555377328fc5fc9b06e94f129b7cd7 Mon Sep 17 00:00:00 2001 +From ef91c84a26a282adaf95e165ebcdd44a410c4328 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 +Subject: [PATCH 19/53] openssh-6.6p1-GSSAPIEnablek5users --- gss-serv-krb5.c | 3 +-- @@ -12,7 +12,7 @@ Subject: [PATCH 21/50] openssh-6.6p1-GSSAPIEnablek5users 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 187faf92..03188d9b 100644 +index 187faf929..03188d9b3 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, @@ -33,10 +33,10 @@ index 187faf92..03188d9b 100644 k5login_exists); } diff --git a/servconf.c b/servconf.c -index 5dd5ca21..c0de7110 100644 +index 8f4b2b43e..5e40f1b00 100644 --- a/servconf.c +++ b/servconf.c -@@ -146,6 +146,7 @@ initialize_server_options(ServerOptions *options) +@@ -144,6 +144,7 @@ initialize_server_options(ServerOptions *options) options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; options->use_kuserok = -1; @@ -44,7 +44,7 @@ index 5dd5ca21..c0de7110 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -402,6 +403,8 @@ fill_default_server_options(ServerOptions *options) +@@ -396,6 +397,8 @@ fill_default_server_options(ServerOptions *options) #endif if (options->use_kuserok == -1) options->use_kuserok = 1; @@ -53,7 +53,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 { +@@ -579,7 +582,7 @@ typedef enum { sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -62,7 +62,7 @@ index 5dd5ca21..c0de7110 100644 sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, -@@ -681,6 +684,7 @@ static struct { +@@ -675,6 +678,7 @@ static struct { { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, @@ -70,7 +70,7 @@ index 5dd5ca21..c0de7110 100644 #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -689,6 +693,7 @@ static struct { +@@ -683,6 +687,7 @@ static struct { { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, @@ -78,7 +78,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, +@@ -2440,6 +2445,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->use_kuserok; goto parse_flag; @@ -89,7 +89,7 @@ index 5dd5ca21..c0de7110 100644 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) +@@ -3007,6 +3016,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(use_kuserok); @@ -97,7 +97,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) +@@ -3316,6 +3326,7 @@ dump_config(ServerOptions *o) # endif dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); @@ -106,7 +106,7 @@ index 5dd5ca21..c0de7110 100644 #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff --git a/servconf.h b/servconf.h -index 11de36a2..c08cf6a7 100644 +index 11de36a23..c08cf6a7a 100644 --- a/servconf.h +++ b/servconf.h @@ -152,6 +152,7 @@ typedef struct { @@ -118,7 +118,7 @@ index 11de36a2..c08cf6a7 100644 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 +index ea5a878e6..33713c886 100644 --- a/sshd_config +++ b/sshd_config @@ -82,6 +82,7 @@ AuthorizedKeysFile .ssh/authorized_keys @@ -130,7 +130,7 @@ index ea5a878e..33713c88 100644 # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will diff --git a/sshd_config.5 b/sshd_config.5 -index 0fcb409a..fe246fc2 100644 +index c360fcfff..a0fc6064f 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -739,6 +739,12 @@ Specifies whether to automatically destroy the user's credentials cache @@ -147,5 +147,5 @@ index 0fcb409a..fe246fc2 100644 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 +2.52.0 diff --git a/0022-openssh-6.8p1-sshdT-output.patch b/0020-openssh-6.8p1-sshdT-output.patch similarity index 75% rename from 0022-openssh-6.8p1-sshdT-output.patch rename to 0020-openssh-6.8p1-sshdT-output.patch index 4e4766e..ed2379e 100644 --- a/0022-openssh-6.8p1-sshdT-output.patch +++ b/0020-openssh-6.8p1-sshdT-output.patch @@ -1,17 +1,17 @@ -From 05b09904f431333e19cd24528ef66d1fd15e9efe Mon Sep 17 00:00:00 2001 +From cce18d636f4137a4e5401170538868b8b80651c1 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 +Subject: [PATCH 20/53] 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 +index 5e40f1b00..b63a7f0b0 100644 --- a/servconf.c +++ b/servconf.c -@@ -3366,7 +3366,7 @@ dump_config(ServerOptions *o) +@@ -3368,7 +3368,7 @@ dump_config(ServerOptions *o) dump_cfg_string(sXAuthLocation, o->xauth_location); dump_cfg_string(sCiphers, o->ciphers); dump_cfg_string(sMacs, o->macs); @@ -21,5 +21,5 @@ index c0de7110..105e301d 100644 dump_cfg_string(sChrootDirectory, o->chroot_directory); dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); -- -2.49.0 +2.52.0 diff --git a/0023-openssh-6.7p1-sftp-force-permission.patch b/0021-openssh-6.7p1-sftp-force-permission.patch similarity index 85% rename from 0023-openssh-6.7p1-sftp-force-permission.patch rename to 0021-openssh-6.7p1-sftp-force-permission.patch index 1cdc0df..737430d 100644 --- a/0023-openssh-6.7p1-sftp-force-permission.patch +++ b/0021-openssh-6.7p1-sftp-force-permission.patch @@ -1,7 +1,7 @@ -From 34b196198018059bed294fa7a08e70606b4cbc36 Mon Sep 17 00:00:00 2001 +From 57ae33c2f43425725345c910d90ef6fed75d3b85 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 +Subject: [PATCH 21/53] openssh-6.7p1-sftp-force-permission --- sftp-server.8 | 7 +++++++ @@ -9,7 +9,7 @@ Subject: [PATCH 23/50] openssh-6.7p1-sftp-force-permission 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/sftp-server.8 b/sftp-server.8 -index 5311bf92..5e6e3aa4 100644 +index 5311bf929..5e6e3aa44 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -38,6 +38,7 @@ @@ -34,10 +34,10 @@ index 5311bf92..5e6e3aa4 100644 .Pp On some systems, diff --git a/sftp-server.c b/sftp-server.c -index 4985da38..6ed1c27f 100644 +index 185ad1459..e04fc63b3 100644 --- a/sftp-server.c +++ b/sftp-server.c -@@ -76,6 +76,10 @@ struct sshbuf *oqueue; +@@ -72,6 +72,10 @@ struct sshbuf *oqueue; /* Version of client */ static u_int version; @@ -48,7 +48,7 @@ index 4985da38..6ed1c27f 100644 /* SSH2_FXP_INIT received */ static int init_done; -@@ -745,6 +749,7 @@ process_open(u_int32_t id) +@@ -741,6 +745,7 @@ process_open(u_int32_t id) Attrib a; char *name; int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; @@ -56,7 +56,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) +@@ -750,6 +755,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 +67,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) +@@ -771,6 +780,8 @@ process_open(u_int32_t id) } } } @@ -76,7 +76,7 @@ index 4985da38..6ed1c27f 100644 if (status != SSH2_FX_OK) send_status(id, status); free(name); -@@ -1894,7 +1905,7 @@ sftp_server_usage(void) +@@ -1890,7 +1901,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 +85,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 +@@ -1914,7 +1925,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle pw = pwcopy(user_pw); while (!skipargs && (ch = getopt(argc, argv, @@ -94,7 +94,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 +@@ -1976,6 +1987,15 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle fatal("Invalid umask \"%s\"", optarg); (void)umask((mode_t)mask); break; @@ -111,5 +111,5 @@ index 4985da38..6ed1c27f 100644 default: sftp_server_usage(); -- -2.49.0 +2.52.0 diff --git a/0024-openssh-7.2p2-s390-closefrom.patch b/0022-openssh-7.2p2-s390-closefrom.patch similarity index 89% rename from 0024-openssh-7.2p2-s390-closefrom.patch rename to 0022-openssh-7.2p2-s390-closefrom.patch index 0214781..fa59fd6 100644 --- a/0024-openssh-7.2p2-s390-closefrom.patch +++ b/0022-openssh-7.2p2-s390-closefrom.patch @@ -1,14 +1,14 @@ -From 9bb31b63142adaaf949e20c2d86c97f9b787217b Mon Sep 17 00:00:00 2001 +From 25b593f41fa85bcaf1bbdc9c368325c4af033208 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 +Subject: [PATCH 22/53] openssh-7.2p2-s390-closefrom --- 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 +index 49a4f35ff..f61124585 100644 --- a/openbsd-compat/bsd-closefrom.c +++ b/openbsd-compat/bsd-closefrom.c @@ -140,7 +140,33 @@ closefrom(int lowfd) @@ -46,5 +46,5 @@ index 49a4f35f..f6112458 100644 (void) closedir(dirp); return; -- -2.49.0 +2.52.0 diff --git a/0026-openssh-7.6p1-cleanup-selinux.patch b/0023-openssh-7.6p1-cleanup-selinux.patch similarity index 81% rename from 0026-openssh-7.6p1-cleanup-selinux.patch rename to 0023-openssh-7.6p1-cleanup-selinux.patch index c4f2d15..d018772 100644 --- a/0026-openssh-7.6p1-cleanup-selinux.patch +++ b/0023-openssh-7.6p1-cleanup-selinux.patch @@ -1,25 +1,25 @@ -From 43320351b6f150167190aacc84f2f87030fef3d2 Mon Sep 17 00:00:00 2001 +From 4cacb1bda51a2d91cf4cc1c8058b989dfc0c58c8 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 +Subject: [PATCH 23/53] 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 +-- + openbsd-compat/port-linux.h | 5 ++-- platform.c | 6 ++++- sshconnect.c | 2 +- sshd-auth.c | 2 +- sshd-session.c | 6 +++-- - 9 files changed, 45 insertions(+), 32 deletions(-) + 9 files changed, 46 insertions(+), 32 deletions(-) diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index 267a27d2..0d5ae0df 100644 +index c326a69ba..b7300ca9e 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c -@@ -77,6 +77,8 @@ +@@ -75,6 +75,8 @@ /* import */ extern ServerOptions options; @@ -28,7 +28,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, +@@ -483,7 +485,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key, if ((pid = subprocess("AuthorizedPrincipalsCommand", command, ac, av, &f, SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, @@ -38,7 +38,7 @@ index 267a27d2..0d5ae0df 100644 goto out; uid_swapped = 1; -@@ -755,7 +758,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key, +@@ -759,7 +762,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key, if ((pid = subprocess("AuthorizedKeysCommand", command, ac, av, &f, SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, @@ -49,10 +49,10 @@ index 267a27d2..0d5ae0df 100644 uid_swapped = 1; diff --git a/misc.c b/misc.c -index 1e31acc9..09722962 100644 +index 7e27a38d1..2fd14159d 100644 --- a/misc.c +++ b/misc.c -@@ -2764,7 +2764,8 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) +@@ -2788,7 +2788,8 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) pid_t subprocess(const char *tag, const char *command, int ac, char **av, FILE **child, u_int flags, @@ -62,7 +62,7 @@ index 1e31acc9..09722962 100644 { FILE *f = NULL; struct stat st; -@@ -2898,7 +2899,7 @@ subprocess(const char *tag, const char *command, +@@ -2922,7 +2923,7 @@ subprocess(const char *tag, const char *command, _exit(1); } #ifdef WITH_SELINUX @@ -72,10 +72,10 @@ index 1e31acc9..09722962 100644 strerror(errno)); _exit(127); diff --git a/misc.h b/misc.h -index efecdf1a..9efa9cf4 100644 +index f3c5a18c6..8cdfd7cec 100644 --- a/misc.h +++ b/misc.h -@@ -122,7 +122,7 @@ typedef void privrestore_fn(void); +@@ -124,7 +124,7 @@ typedef void privrestore_fn(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, @@ -85,10 +85,10 @@ 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 +index 4d56745f7..ab083a637 100644 --- a/openbsd-compat/port-linux-sshd.c +++ b/openbsd-compat/port-linux-sshd.c -@@ -49,10 +49,6 @@ +@@ -48,10 +48,6 @@ #include #endif @@ -99,7 +99,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, +@@ -221,7 +217,8 @@ get_user_context(const char *sename, const char *role, const char *lvl, } static void @@ -109,7 +109,7 @@ index 646f0887..291b569a 100644 { *role = NULL; *level = NULL; -@@ -240,8 +237,8 @@ ssh_selinux_get_role_level(char **role, const char **level) +@@ -239,8 +236,8 @@ ssh_selinux_get_role_level(char **role, const char **level) /* Return the default security context for the given username */ static int @@ -120,7 +120,7 @@ index 646f0887..291b569a 100644 { char *sename, *lvl; char *role; -@@ -249,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -248,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname, int r = 0; context_t con = NULL; @@ -129,7 +129,7 @@ index 646f0887..291b569a 100644 #ifdef HAVE_GETSEUSERBYNAME if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { -@@ -271,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -270,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname, if (r == 0) { /* If launched from xinetd, we must use current level */ @@ -138,7 +138,7 @@ index 646f0887..291b569a 100644 security_context_t sshdsc=NULL; if (getcon_raw(&sshdsc) < 0) -@@ -332,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -331,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int @@ -148,7 +148,7 @@ index 646f0887..291b569a 100644 { const char *reqlvl; char *role; -@@ -341,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) +@@ -340,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) debug3_f("setting execution context"); @@ -162,7 +162,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 *)) +@@ -360,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) } static int @@ -175,7 +175,7 @@ index 646f0887..291b569a 100644 } static int -@@ -373,25 +372,28 @@ do_setenv(char *name, const char *value) +@@ -372,25 +371,28 @@ do_setenv(char *name, const char *value) } int @@ -209,7 +209,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) +@@ -406,7 +408,7 @@ sshd_selinux_setup_exec_context(char *pwname) debug3_f("setting execution context"); @@ -219,22 +219,23 @@ index 646f0887..291b569a 100644 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 +index c004071d1..26c5f773b 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h -@@ -25,8 +25,8 @@ void ssh_selinux_setfscreatecon(const char *); +@@ -23,8 +23,9 @@ 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); ++int sshd_selinux_enabled(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 + #ifdef LINUX_OOM_ADJUST diff --git a/platform.c b/platform.c -index 0d12f311..f0800b1f 100644 +index c92a0cba6..66d0c2a6b 100644 --- a/platform.c +++ b/platform.c @@ -33,6 +33,8 @@ @@ -258,10 +259,10 @@ index 0d12f311..f0800b1f 100644 } diff --git a/sshconnect.c b/sshconnect.c -index c86182d1..04084810 100644 +index 912a520c5..babe4a982 100644 --- a/sshconnect.c +++ b/sshconnect.c -@@ -925,7 +925,7 @@ load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template, +@@ -917,7 +917,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| @@ -271,10 +272,10 @@ index c86182d1..04084810 100644 load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1); diff --git a/sshd-auth.c b/sshd-auth.c -index e4a8edfd..897db9b4 100644 +index 5a4ee733c..f3c38a7d1 100644 --- a/sshd-auth.c +++ b/sshd-auth.c -@@ -122,7 +122,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; +@@ -120,7 +120,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; int debug_flag = 0; /* Flag indicating that the daemon is being started from inetd. */ @@ -284,10 +285,10 @@ index e4a8edfd..897db9b4 100644 /* Saved arguments to main(). */ static char **saved_argv; diff --git a/sshd-session.c b/sshd-session.c -index 9342e416..81d30152 100644 +index 4a5eaa1ff..d6bece941 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -136,7 +136,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; +@@ -130,7 +130,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; int debug_flag = 0; /* Flag indicating that the daemon is being started from inetd. */ @@ -296,7 +297,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) +@@ -1337,7 +1337,9 @@ main(int ac, char **av) } #endif #ifdef WITH_SELINUX @@ -308,5 +309,5 @@ index 9342e416..81d30152 100644 #ifdef USE_PAM if (options.use_pam) { -- -2.49.0 +2.52.0 diff --git a/0027-openssh-7.5p1-sandbox.patch b/0024-openssh-7.5p1-sandbox.patch similarity index 76% rename from 0027-openssh-7.5p1-sandbox.patch rename to 0024-openssh-7.5p1-sandbox.patch index 435d029..32b56db 100644 --- a/0027-openssh-7.5p1-sandbox.patch +++ b/0024-openssh-7.5p1-sandbox.patch @@ -1,17 +1,17 @@ -From 35205319dd71d8e61c1596b8f9479df91aff7756 Mon Sep 17 00:00:00 2001 +From 503297ec6f6eef3bb4906271d170fab848e27298 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 +Subject: [PATCH 24/53] 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 +index a0692dd2f..e0f2d4289 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c -@@ -277,6 +277,9 @@ static const struct sock_filter preauth_insns[] = { +@@ -305,6 +305,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_exit_group SC_ALLOW(__NR_exit_group), #endif @@ -21,7 +21,7 @@ index b31062c2..1fabf99d 100644 #ifdef __NR_futex SC_FUTEX(__NR_futex), #endif -@@ -295,6 +298,21 @@ static const struct sock_filter preauth_insns[] = { +@@ -323,6 +326,21 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_getpid SC_ALLOW(__NR_getpid), #endif @@ -43,7 +43,7 @@ index b31062c2..1fabf99d 100644 #ifdef __NR_getrandom SC_ALLOW(__NR_getrandom), #endif -@@ -304,6 +322,9 @@ static const struct sock_filter preauth_insns[] = { +@@ -332,6 +350,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_gettimeofday SC_ALLOW(__NR_gettimeofday), #endif @@ -54,5 +54,5 @@ index b31062c2..1fabf99d 100644 SC_ALLOW(__NR_getuid), #endif -- -2.49.0 +2.52.0 diff --git a/0029-openssh-7.8p1-scp-ipv6.patch b/0025-openssh-7.8p1-scp-ipv6.patch similarity index 74% rename from 0029-openssh-7.8p1-scp-ipv6.patch rename to 0025-openssh-7.8p1-scp-ipv6.patch index dbd69aa..d1eb51a 100644 --- a/0029-openssh-7.8p1-scp-ipv6.patch +++ b/0025-openssh-7.8p1-scp-ipv6.patch @@ -1,17 +1,17 @@ -From 507e6f245557ae7261806f7ecbd40697cb0dd389 Mon Sep 17 00:00:00 2001 +From e1d86d265d9543c77fa90a33acc70246e68bf3bf 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 +Subject: [PATCH 25/53] 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 e1992622f..621131ffc 100644 --- a/scp.c +++ b/scp.c -@@ -1183,7 +1183,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) +@@ -1169,7 +1169,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) addargs(&alist, "%s", host); addargs(&alist, "%s", cmd); addargs(&alist, "%s", src); @@ -23,5 +23,5 @@ index 9554b188..7f9795a5 100644 thost, targ); if (do_local_cmd(&alist) != 0) -- -2.49.0 +2.52.0 diff --git a/0030-openssh-8.0p1-crypto-policies.patch b/0026-openssh-8.0p1-crypto-policies.patch similarity index 96% rename from 0030-openssh-8.0p1-crypto-policies.patch rename to 0026-openssh-8.0p1-crypto-policies.patch index 498e3f5..5162ffa 100644 --- a/0030-openssh-8.0p1-crypto-policies.patch +++ b/0026-openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,7 @@ -From b436140fe3abd9f97f01f9af9f5da5cf6c5d7725 Mon Sep 17 00:00:00 2001 +From 6d9e08f061451f6cd464af5ec598fa99d15acadb 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 +Subject: [PATCH 26/53] openssh-8.0p1-crypto-policies --- ssh_config.5 | 164 ++++++++++++++++++++------------------------- @@ -9,7 +9,7 @@ Subject: [PATCH 30/50] openssh-8.0p1-crypto-policies 2 files changed, 140 insertions(+), 203 deletions(-) diff --git a/ssh_config.5 b/ssh_config.5 -index 8d5d0722..a43b2a27 100644 +index 8a4b469cf..8ac5e1633 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -438,17 +438,13 @@ A single argument of @@ -166,7 +166,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: +@@ -1360,6 +1357,11 @@ it may be zero or more of: and .Cm pam . .It Cm KexAlgorithms @@ -178,7 +178,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. +@@ -1368,29 +1370,17 @@ Multiple algorithms must be comma-separated. .Pp If the specified list begins with a .Sq + @@ -212,7 +212,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 +@@ -1506,37 +1496,33 @@ function, and all code in the file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -259,7 +259,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. +@@ -1725,39 +1711,31 @@ instead of continuing to execute and pass data. The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -311,7 +311,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. +@@ -2504,7 +2482,9 @@ for those users who do not have a configuration file. This file must be world-readable. .El .Sh SEE ALSO @@ -323,7 +323,7 @@ index 8d5d0722..a43b2a27 100644 .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 +index a0fc6064f..c172d5aab 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -379,17 +379,13 @@ If the argument is @@ -497,7 +497,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. +@@ -1051,6 +1024,11 @@ Specifies whether to look at .k5login file for user's aliases. The default is .Cm yes . .It Cm KexAlgorithms @@ -509,7 +509,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. +@@ -1059,16 +1037,16 @@ Multiple algorithms must be comma-separated. .Pp If the specified list begins with a .Sq + @@ -530,7 +530,7 @@ index 26fcdc84..583a01cd 100644 .Pp The supported algorithms are: .Pp -@@ -1106,14 +1084,6 @@ sntrup761x25519-sha512 +@@ -1105,14 +1083,6 @@ sntrup761x25519-sha512 sntrup761x25519-sha512@openssh.com .El .Pp @@ -545,7 +545,7 @@ index 26fcdc84..583a01cd 100644 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 +@@ -1199,21 +1169,26 @@ function, and all code in the file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -576,7 +576,7 @@ index 26fcdc84..583a01cd 100644 .Pp The algorithms that contain .Qq -etm -@@ -1257,15 +1232,6 @@ umac-64-etm@openssh.com +@@ -1256,15 +1231,6 @@ umac-64-etm@openssh.com umac-128-etm@openssh.com .El .Pp @@ -592,7 +592,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.) +@@ -1751,36 +1717,25 @@ or equivalent.) The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms @@ -638,7 +638,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 +@@ -2281,7 +2236,9 @@ This file should be writable by root only, but it is recommended .El .Sh SEE ALSO .Xr sftp-server 8 , @@ -650,5 +650,5 @@ index 26fcdc84..583a01cd 100644 .An -nosplit OpenSSH is a derivative of the original and free -- -2.49.0 +2.52.0 diff --git a/0031-openssh-8.0p1-openssl-kdf.patch b/0027-openssh-8.0p1-openssl-kdf.patch similarity index 89% rename from 0031-openssh-8.0p1-openssl-kdf.patch rename to 0027-openssh-8.0p1-openssl-kdf.patch index 529940f..6f7f49b 100644 --- a/0031-openssh-8.0p1-openssl-kdf.patch +++ b/0027-openssh-8.0p1-openssl-kdf.patch @@ -1,7 +1,7 @@ -From 430bd33963725beb8ec01a1e581529ae6bf6bec0 Mon Sep 17 00:00:00 2001 +From d73633dd9770bea0c3802075842398faf3e55e30 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 +Subject: [PATCH 27/53] openssh-8.0p1-openssl-kdf --- configure.ac | 1 + @@ -9,10 +9,10 @@ Subject: [PATCH 31/50] openssh-8.0p1-openssl-kdf 2 files changed, 108 insertions(+) diff --git a/configure.ac b/configure.ac -index d9bd2f51..d92a8580 100644 +index adccaebd4..805be4b5e 100644 --- a/configure.ac +++ b/configure.ac -@@ -3137,6 +3137,7 @@ if test "x$openssl" = "xyes" ; then +@@ -3182,6 +3182,7 @@ if test "x$openssl" = "xyes" ; then HMAC_CTX_init \ RSA_generate_key_ex \ RSA_get_default_method \ @@ -21,10 +21,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 9a2ce6d88..5f9530908 100644 --- a/kex.c +++ b/kex.c -@@ -40,6 +40,11 @@ +@@ -38,6 +38,11 @@ #ifdef WITH_OPENSSL #include #include @@ -36,7 +36,7 @@ index 19a56e8e..8b200ff4 100644 #endif #include "ssh.h" -@@ -1078,6 +1083,107 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -1077,6 +1082,107 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) return r; } @@ -144,7 +144,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, +@@ -1140,6 +1246,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, ssh_digest_free(hashctx); return r; } @@ -153,5 +153,5 @@ index 19a56e8e..8b200ff4 100644 #define NKEYS 6 int -- -2.49.0 +2.52.0 diff --git a/0032-openssh-8.2p1-visibility.patch b/0028-openssh-8.2p1-visibility.patch similarity index 75% rename from 0032-openssh-8.2p1-visibility.patch rename to 0028-openssh-8.2p1-visibility.patch index c67373c..7c5eabf 100644 --- a/0032-openssh-8.2p1-visibility.patch +++ b/0028-openssh-8.2p1-visibility.patch @@ -1,17 +1,17 @@ -From 6aa231d9acfeca870ee87e3bf9c4a1239518706d Mon Sep 17 00:00:00 2001 +From ed5e5df9ec7ac96ac2a68c5711db00ed29d4d1cd 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 +Subject: [PATCH 28/53] 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 4c96e8827..4af5209db 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, ...) +@@ -80,7 +80,7 @@ skdebug(const char *func, const char *fmt, ...) #endif } @@ -20,7 +20,7 @@ index 347b2122..344f8a8a 100644 sk_api_version(void) { return SSH_SK_VERSION_MAJOR; -@@ -230,7 +230,7 @@ check_options(struct sk_option **options) +@@ -229,7 +229,7 @@ check_options(struct sk_option **options) return 0; } @@ -29,7 +29,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, +@@ -477,7 +477,7 @@ sig_ed25519(const uint8_t *message, size_t message_len, return ret; } @@ -38,7 +38,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, +@@ -534,7 +534,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, return ret; } @@ -48,5 +48,5 @@ index 347b2122..344f8a8a 100644 struct sk_resident_key ***rks, size_t *nrks) { -- -2.49.0 +2.52.0 diff --git a/0033-openssh-8.2p1-x11-without-ipv6.patch b/0029-openssh-8.2p1-x11-without-ipv6.patch similarity index 75% rename from 0033-openssh-8.2p1-x11-without-ipv6.patch rename to 0029-openssh-8.2p1-x11-without-ipv6.patch index 32a9056..7063d7f 100644 --- a/0033-openssh-8.2p1-x11-without-ipv6.patch +++ b/0029-openssh-8.2p1-x11-without-ipv6.patch @@ -1,17 +1,17 @@ -From cfe5a99d335eb57b8c08b4eb6b4535dd042d96e3 Mon Sep 17 00:00:00 2001 +From c8dce0615eac6d2a724cdb3f288d7aaa1362f65b 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 +Subject: [PATCH 29/53] 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 +index 5ce6bd400..26ed9945f 100644 --- a/channels.c +++ b/channels.c -@@ -5055,6 +5055,16 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +@@ -5123,6 +5123,16 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, debug2_f("bind port %d: %.100s", port, strerror(errno)); close(sock); @@ -29,5 +29,5 @@ index 7438c1a5..95836d50 100644 close(socks[n]); num_socks = 0; -- -2.49.0 +2.52.0 diff --git a/0034-openssh-8.0p1-preserve-pam-errors.patch b/0030-openssh-8.0p1-preserve-pam-errors.patch similarity index 79% rename from 0034-openssh-8.0p1-preserve-pam-errors.patch rename to 0030-openssh-8.0p1-preserve-pam-errors.patch index 15e59c2..4aa2ffb 100644 --- a/0034-openssh-8.0p1-preserve-pam-errors.patch +++ b/0030-openssh-8.0p1-preserve-pam-errors.patch @@ -1,17 +1,17 @@ -From 8de0391e3b3eb75e23ee9f173f04a9c78f2b96c9 Mon Sep 17 00:00:00 2001 +From a3b6182e1d6b69a37a6c841baa43b818251036b1 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 +Subject: [PATCH 30/53] 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 +index 70bcae83a..70b2b8580 100644 --- a/auth-pam.c +++ b/auth-pam.c -@@ -523,7 +523,11 @@ sshpam_thread(void *ctxtp) +@@ -551,7 +551,11 @@ sshpam_thread(void *ctxtp) goto auth_fail; if (!do_pam_account()) { @@ -24,9 +24,9 @@ index b4100ea1..a042c3c8 100644 goto auth_fail; } if (sshpam_authctxt->force_pwchange) { -@@ -580,8 +584,10 @@ sshpam_thread(void *ctxtp) +@@ -608,8 +612,10 @@ sshpam_thread(void *ctxtp) pam_strerror(sshpam_handle, sshpam_err))) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); /* XXX - can't do much about an error here */ - if (sshpam_err == PAM_ACCT_EXPIRED) - ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer); @@ -37,7 +37,7 @@ 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, +@@ -913,9 +919,11 @@ sshpam_query(void *ctx, char **name, char **info, free(msg); break; case PAM_ACCT_EXPIRED: @@ -52,5 +52,5 @@ index b4100ea1..a042c3c8 100644 sshpam_set_maxtries_reached(1); /* FALLTHROUGH */ -- -2.49.0 +2.52.0 diff --git a/0035-openssh-8.7p1-scp-kill-switch.patch b/0031-openssh-8.7p1-scp-kill-switch.patch similarity index 75% rename from 0035-openssh-8.7p1-scp-kill-switch.patch rename to 0031-openssh-8.7p1-scp-kill-switch.patch index 58a5036..5c3594f 100644 --- a/0035-openssh-8.7p1-scp-kill-switch.patch +++ b/0031-openssh-8.7p1-scp-kill-switch.patch @@ -1,7 +1,7 @@ -From a68f3741fdc01bf6823a69d2442caba7de9835f9 Mon Sep 17 00:00:00 2001 +From ca8b4de1019b859e2c68288a554d1905a6cf029f 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 +Subject: [PATCH 31/53] openssh-8.7p1-scp-kill-switch --- pathnames.h | 1 + @@ -10,11 +10,11 @@ Subject: [PATCH 35/50] openssh-8.7p1-scp-kill-switch 3 files changed, 16 insertions(+) diff --git a/pathnames.h b/pathnames.h -index 1158bec9..43f0c570 100644 +index 0dcc49552..78bba2314 100644 --- a/pathnames.h +++ b/pathnames.h -@@ -42,6 +42,7 @@ - #define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key" +@@ -40,6 +40,7 @@ + #define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" #define _PATH_DH_MODULI SSHDIR "/moduli" +#define _PATH_SCP_KILL_SWITCH SSHDIR "/disable_scp" @@ -22,10 +22,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 +index 7bce0fe6f..2bb838c7d 100644 --- a/scp.1 +++ b/scp.1 -@@ -331,6 +331,13 @@ during download or upload. +@@ -334,6 +334,13 @@ during download or upload. By default a 32KB buffer is used. .El .El @@ -40,10 +40,10 @@ index aa2e2d8b..373d7237 100644 .Ex -std scp .Sh SEE ALSO diff --git a/scp.c b/scp.c -index 7f9795a5..7ed1a54c 100644 +index 621131ffc..3c213f83d 100644 --- a/scp.c +++ b/scp.c -@@ -649,6 +649,14 @@ main(int argc, char **argv) +@@ -633,6 +633,14 @@ main(int argc, char **argv) if (iamremote) mode = MODE_SCP; @@ -59,5 +59,5 @@ index 7f9795a5..7ed1a54c 100644 fatal("unknown user %u", (u_int) userid); -- -2.49.0 +2.52.0 diff --git a/0036-openssh-8.7p1-recursive-scp.patch b/0032-openssh-8.7p1-recursive-scp.patch similarity index 86% rename from 0036-openssh-8.7p1-recursive-scp.patch rename to 0032-openssh-8.7p1-recursive-scp.patch index 929b408..adb5e3d 100644 --- a/0036-openssh-8.7p1-recursive-scp.patch +++ b/0032-openssh-8.7p1-recursive-scp.patch @@ -1,7 +1,7 @@ -From 99e1e3af524376788e591ca73387f1ca37e6f5ef Mon Sep 17 00:00:00 2001 +From e6478b233cd2298c9e6e6128867421892ff8f0e4 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 +Subject: [PATCH 32/53] openssh-8.7p1-recursive-scp --- scp.c | 2 +- @@ -11,10 +11,10 @@ Subject: [PATCH 36/50] openssh-8.7p1-recursive-scp 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/scp.c b/scp.c -index 7ed1a54c..0c87dd0e 100644 +index 3c213f83d..78c79a755 100644 --- a/scp.c +++ b/scp.c -@@ -1388,7 +1388,7 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) +@@ -1378,7 +1378,7 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) if (src_is_dir && iamrecursive) { if (sftp_upload_dir(conn, src, abs_dst, pflag, @@ -24,10 +24,10 @@ index 7ed1a54c..0c87dd0e 100644 errs = 1; } diff --git a/sftp-client.c b/sftp-client.c -index 9f8ab4af..873dec04 100644 +index 840170ab6..9bf9cc047 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, +@@ -1001,7 +1001,7 @@ sftp_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, /* Implements both the realpath and expand-path operations */ static char * @@ -36,7 +36,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) +@@ -1047,11 +1047,43 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) if ((r = sshbuf_get_u32(msg, &status)) != 0 || (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0) fatal_fr(r, "parse status"); @@ -85,7 +85,7 @@ 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) +@@ -1076,9 +1108,9 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) } char * @@ -97,7 +97,7 @@ index 9f8ab4af..873dec04 100644 } int -@@ -1094,9 +1126,9 @@ sftp_expand_path(struct sftp_conn *conn, const char *path) +@@ -1092,9 +1124,9 @@ sftp_expand_path(struct sftp_conn *conn, const char *path) { if (!sftp_can_expand_path(conn)) { debug3_f("no server support, fallback to realpath"); @@ -109,7 +109,7 @@ index 9f8ab4af..873dec04 100644 } int -@@ -2016,7 +2048,7 @@ sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst, +@@ -2014,7 +2046,7 @@ sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst, char *src_canon; int ret; @@ -143,10 +143,10 @@ index 9f8ab4af..873dec04 100644 from_path); return -1; diff --git a/sftp-client.h b/sftp-client.h -index 74cdae7d..00ed6630 100644 +index 873ad3849..fe58651c1 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 *); +@@ -112,7 +112,7 @@ int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *); int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); /* Canonicalise 'path' - caller must free result */ @@ -155,7 +155,7 @@ index 74cdae7d..00ed6630 100644 /* 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 *, +@@ -164,7 +164,7 @@ int sftp_upload(struct sftp_conn *, const char *, const char *, * times if 'pflag' is set */ int sftp_upload_dir(struct sftp_conn *, const char *, const char *, @@ -165,10 +165,10 @@ index 74cdae7d..00ed6630 100644 /* * Download a 'from_path' from the 'from' connection and upload it to diff --git a/sftp.c b/sftp.c -index bdedd141..322e6d1f 100644 +index 3b505eea2..2a99698a8 100644 --- a/sftp.c +++ b/sftp.c -@@ -809,7 +809,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst, +@@ -801,7 +801,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst, (rflag || global_rflag)) { if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst, pflag || global_pflag, 1, resume, @@ -177,7 +177,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, +@@ -1636,7 +1636,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, if (path1 == NULL || *path1 == '\0') path1 = xstrdup(startdir); path1 = sftp_make_absolute(path1, *pwd); @@ -186,7 +186,7 @@ index bdedd141..322e6d1f 100644 err = 1; break; } -@@ -2249,7 +2249,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) +@@ -2241,7 +2241,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) } #endif /* USE_LIBEDIT */ @@ -196,5 +196,5 @@ index bdedd141..322e6d1f 100644 startdir = xstrdup(remote_path); -- -2.49.0 +2.52.0 diff --git a/0037-openssh-8.7p1-minrsabits.patch b/0033-openssh-8.7p1-minrsabits.patch similarity index 80% rename from 0037-openssh-8.7p1-minrsabits.patch rename to 0033-openssh-8.7p1-minrsabits.patch index 59e530b..fcd994b 100644 --- a/0037-openssh-8.7p1-minrsabits.patch +++ b/0033-openssh-8.7p1-minrsabits.patch @@ -1,7 +1,7 @@ -From 286bc4a302b5130f732c857095ae665f7bea01dd Mon Sep 17 00:00:00 2001 +From 14f25e21b4e2c5e625f266fcc9af42c2f89845de 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 +Subject: [PATCH 33/53] openssh-8.7p1-minrsabits --- readconf.c | 1 + @@ -9,10 +9,10 @@ Subject: [PATCH 37/50] openssh-8.7p1-minrsabits 2 files changed, 2 insertions(+) diff --git a/readconf.c b/readconf.c -index 6c04ed43..f340bf50 100644 +index eab734aaf..3f67f4de4 100644 --- a/readconf.c +++ b/readconf.c -@@ -343,6 +343,7 @@ static struct { +@@ -337,6 +337,7 @@ static struct { { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, { "requiredrsasize", oRequiredRSASize }, @@ -21,10 +21,10 @@ index 6c04ed43..f340bf50 100644 { "obscurekeystroketiming", oObscureKeystrokeTiming }, { "channeltimeout", oChannelTimeout }, diff --git a/servconf.c b/servconf.c -index 15c99b30..84891544 100644 +index b63a7f0b0..ac84b74d9 100644 --- a/servconf.c +++ b/servconf.c -@@ -788,6 +788,7 @@ static struct { +@@ -778,6 +778,7 @@ static struct { { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, @@ -33,5 +33,5 @@ index 15c99b30..84891544 100644 { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, -- -2.49.0 +2.52.0 diff --git a/0038-openssh-8.7p1-ibmca.patch b/0034-openssh-8.7p1-ibmca.patch similarity index 79% rename from 0038-openssh-8.7p1-ibmca.patch rename to 0034-openssh-8.7p1-ibmca.patch index 74dd5b5..803c899 100644 --- a/0038-openssh-8.7p1-ibmca.patch +++ b/0034-openssh-8.7p1-ibmca.patch @@ -1,14 +1,14 @@ -From 26af04432f6404eb03780265a5cce948ecfec8dc Mon Sep 17 00:00:00 2001 +From e2c0fb233119584b04d61d243cd58433072559c2 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 +Subject: [PATCH 34/53] 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 +index f61124585..417c20484 100644 --- a/openbsd-compat/bsd-closefrom.c +++ b/openbsd-compat/bsd-closefrom.c @@ -16,7 +16,7 @@ @@ -21,5 +21,5 @@ index f6112458..417c2048 100644 #include #include -- -2.49.0 +2.52.0 diff --git a/0039-openssh-7.6p1-audit.patch b/0035-openssh-7.6p1-audit.patch similarity index 91% rename from 0039-openssh-7.6p1-audit.patch rename to 0035-openssh-7.6p1-audit.patch index e4f89c7..1635f9f 100644 --- a/0039-openssh-7.6p1-audit.patch +++ b/0035-openssh-7.6p1-audit.patch @@ -1,7 +1,7 @@ -From b0505837bfa2dcdf07800634fa80c5cdb78799dc Mon Sep 17 00:00:00 2001 +From c64eb340d925f3f7e29bb1c45b7d7b537ffa6197 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 +Subject: [PATCH 35/53] openssh-7.6p1-audit --- Makefile.in | 2 +- @@ -21,34 +21,34 @@ Subject: [PATCH 39/50] openssh-7.6p1-audit kex.h | 2 + mac.c | 14 +++ mac.h | 1 + - monitor.c | 194 +++++++++++++++++++++++++++-- + monitor.c | 193 +++++++++++++++++++++++++++-- monitor.h | 8 +- monitor_wrap.c | 130 +++++++++++++++++++- monitor_wrap.h | 11 +- packet.c | 98 +++++++++++++-- packet.h | 1 + - session.c | 83 ++++++++++++- + session.c | 82 ++++++++++++- session.h | 10 +- - sshd-session.c | 104 ++++++++++++++-- + sshd-session.c | 98 +++++++++++++-- sshd.c | 10 ++ - 27 files changed, 1258 insertions(+), 104 deletions(-) + 27 files changed, 1251 insertions(+), 103 deletions(-) create mode 100644 auditstub.c diff --git a/Makefile.in b/Makefile.in -index 6c417ef7..a2942392 100644 +index a36eb82ed..20d134c02 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -119,7 +119,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -110,7 +110,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 +- sshbuf-io.o misc-agent.o ++ sshbuf-io.o misc-agent.o auditstub.o - SKOBJS= ssh-sk-client.o + P11OBJS= ssh-pkcs11-client.o diff --git a/audit-bsm.c b/audit-bsm.c -index ccfcf6f7..a49abb92 100644 +index 4bce22c37..a6292cb8f 100644 --- a/audit-bsm.c +++ b/audit-bsm.c @@ -373,12 +373,25 @@ audit_connection_from(const char *host, int port) @@ -92,7 +92,7 @@ index ccfcf6f7..a49abb92 100644 audit_event(struct ssh *ssh, ssh_audit_event_t event) { @@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) - debug("%s: unhandled event %d", __func__, event); + debug_f("unhandled event %d", event); } } + @@ -121,10 +121,10 @@ index ccfcf6f7..a49abb92 100644 +} #endif /* BSM */ diff --git a/audit-linux.c b/audit-linux.c -index 3fcbe5c5..d484b82b 100644 +index 954eabe27..4d3e9d41e 100644 --- a/audit-linux.c +++ b/audit-linux.c -@@ -33,27 +33,40 @@ +@@ -33,29 +33,42 @@ #include "log.h" #include "audit.h" @@ -164,6 +164,8 @@ index 3fcbe5c5..d484b82b 100644 - return 0; /* Must prevent login */ + goto fatal_report; /* Must prevent login */ } + if (hostname != NULL && strcmp(hostname, "UNKNOWN") == 0) + hostname = NULL; - rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, + rc = audit_log_acct_message(audit_fd, event, NULL, "login", username ? username : "(unknown)", @@ -172,7 +174,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, +@@ -67,9 +80,96 @@ linux_audit_record_event(int uid, const char *username, const char *hostname, rc = 0; errno = saved_errno; @@ -270,7 +272,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) +@@ -78,49 +178,211 @@ audit_connection_from(const char *host, int port) /* not implemented */ } @@ -379,7 +381,7 @@ index 3fcbe5c5..d484b82b 100644 + ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; default: - debug("%s: unhandled event %d", __func__, event); + debug_f("unhandled event %d", event); break; } } @@ -495,7 +497,7 @@ index 3fcbe5c5..d484b82b 100644 +} #endif /* USE_LINUX_AUDIT */ diff --git a/audit.c b/audit.c -index dd2f0355..d0433c3a 100644 +index dd2f03558..d0433c3a0 100644 --- a/audit.c +++ b/audit.c @@ -34,6 +34,12 @@ @@ -676,7 +678,7 @@ index dd2f0355..d0433c3a 100644 # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ diff --git a/audit.h b/audit.h -index 38cb5ad3..45d66ccf 100644 +index 38cb5ad31..45d66ccff 100644 --- a/audit.h +++ b/audit.h @@ -26,6 +26,7 @@ @@ -723,7 +725,7 @@ index 38cb5ad3..45d66ccf 100644 #endif /* _SSH_AUDIT_H */ diff --git a/auditstub.c b/auditstub.c new file mode 100644 -index 00000000..639a798d +index 000000000..639a798df --- /dev/null +++ b/auditstub.c @@ -0,0 +1,52 @@ @@ -780,10 +782,10 @@ index 00000000..639a798d +{ +} diff --git a/auth.c b/auth.c -index e4578169..e10e804f 100644 +index d25653ee4..38c34298e 100644 --- a/auth.c +++ b/auth.c -@@ -501,9 +501,6 @@ getpwnamallow(struct ssh *ssh, const char *user) +@@ -499,9 +499,6 @@ getpwnamallow(struct ssh *ssh, const char *user) record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif @@ -794,7 +796,7 @@ index e4578169..e10e804f 100644 } if (!allowed_user(ssh, pw)) diff --git a/auth.h b/auth.h -index 39163035..6be52d70 100644 +index 391630350..6be52d70b 100644 --- a/auth.h +++ b/auth.h @@ -215,6 +215,8 @@ struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *); @@ -816,7 +818,7 @@ index 39163035..6be52d70 100644 FILE *auth_openprincipals(const char *, struct passwd *, int); diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index a3be6e49..8cebaffd 100644 +index 976484fc5..e9421a868 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -157,7 +157,7 @@ userauth_hostbased(struct ssh *ssh, const char *method) @@ -850,10 +852,10 @@ index a3be6e49..8cebaffd 100644 int hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index 0d5ae0df..99cb810f 100644 +index b7300ca9e..9f3371c07 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c -@@ -235,7 +235,7 @@ userauth_pubkey(struct ssh *ssh, const char *method) +@@ -233,7 +233,7 @@ userauth_pubkey(struct ssh *ssh, const char *method) /* test for correct signature */ authenticated = 0; if (mm_user_key_allowed(ssh, pw, key, 1, &authopts) && @@ -862,7 +864,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: +@@ -326,6 +326,20 @@ done: return authenticated; } @@ -884,7 +886,7 @@ index 0d5ae0df..99cb810f 100644 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 +index 5a4b932a9..da24f7bcb 100644 --- a/auth2.c +++ b/auth2.c @@ -310,9 +310,6 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) @@ -898,7 +900,7 @@ index 8ec41de2..4a8515ea 100644 #ifdef USE_PAM if (options.use_pam) diff --git a/cipher.c b/cipher.c -index 8a18da2d..57d55325 100644 +index 5e096cebf..9b42ffb9a 100644 --- a/cipher.c +++ b/cipher.c @@ -64,25 +64,6 @@ struct sshcipher_ctx { @@ -927,7 +929,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, +@@ -411,7 +392,7 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, void cipher_free(struct sshcipher_ctx *cc) { @@ -937,7 +939,7 @@ index 8a18da2d..57d55325 100644 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_free(cc->cp_ctx); diff --git a/cipher.h b/cipher.h -index 6533ff2b..2e05a021 100644 +index 6533ff2bb..2e05a0210 100644 --- a/cipher.h +++ b/cipher.h @@ -47,7 +47,25 @@ @@ -968,10 +970,10 @@ index 6533ff2b..2e05a021 100644 const struct sshcipher *cipher_by_name(const char *); diff --git a/kex.c b/kex.c -index 8b200ff4..62f607d6 100644 +index 5f9530908..44f350ce8 100644 --- a/kex.c +++ b/kex.c -@@ -68,6 +68,7 @@ +@@ -66,6 +66,7 @@ #include "sshbuf.h" #include "digest.h" #include "xmalloc.h" @@ -979,7 +981,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) +@@ -820,12 +821,16 @@ kex_start_rekex(struct ssh *ssh) } static int @@ -998,7 +1000,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) +@@ -846,8 +851,12 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); @@ -1012,7 +1014,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) +@@ -860,12 +869,16 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) } static int @@ -1031,7 +1033,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) +@@ -1029,7 +1042,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) 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 +1042,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) +@@ -1044,7 +1057,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) peer[nmac] = NULL; goto out; } @@ -1049,7 +1051,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) +@@ -1067,6 +1080,10 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) 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 +1062,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) +@@ -1336,6 +1353,36 @@ dump_digest(const char *msg, const u_char *digest, int len) } #endif @@ -1098,10 +1100,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 +index 206ce60ed..cb06e85a3 100644 --- a/kex.h +++ b/kex.h -@@ -255,6 +255,8 @@ int kexgss_client(struct ssh *); +@@ -260,6 +260,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1111,10 +1113,10 @@ index 0e080ea3..6a55aadf 100644 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 +index c95f5ea06..354cfb408 100644 --- a/mac.c +++ b/mac.c -@@ -239,6 +239,20 @@ mac_clear(struct sshmac *mac) +@@ -230,6 +230,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1136,7 +1138,7 @@ index f3dda669..bf051baa 100644 #define MAC_SEP "," int diff --git a/mac.h b/mac.h -index 0b119d7a..5fb593b9 100644 +index 0b119d7a1..5fb593b9e 100644 --- a/mac.h +++ b/mac.h @@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, @@ -1147,10 +1149,10 @@ index 0b119d7a..5fb593b9 100644 #endif /* SSHMAC_H */ diff --git a/monitor.c b/monitor.c -index 43c10a4e..fbc35782 100644 +index 453469665..b2f501790 100644 --- a/monitor.c +++ b/monitor.c -@@ -93,6 +93,7 @@ +@@ -83,6 +83,7 @@ #include "compat.h" #include "ssh2.h" #include "authfd.h" @@ -1158,7 +1160,7 @@ index 43c10a4e..fbc35782 100644 #include "match.h" #include "ssherr.h" #include "sk-api.h" -@@ -110,6 +111,8 @@ extern struct sshbuf *loginmsg; +@@ -100,6 +101,8 @@ extern struct sshbuf *loginmsg; extern struct include_list includes; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ @@ -1167,7 +1169,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 *); +@@ -144,6 +147,11 @@ int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); #ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(struct ssh *, int, struct sshbuf *); int mm_answer_audit_command(struct ssh *, int, struct sshbuf *); @@ -1179,7 +1181,7 @@ index 43c10a4e..fbc35782 100644 #endif static Authctxt *authctxt; -@@ -214,6 +222,10 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -204,6 +212,10 @@ struct mon_table mon_dispatch_proto20[] = { #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1190,7 +1192,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[] = { +@@ -239,6 +251,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 +1204,7 @@ index 43c10a4e..fbc35782 100644 #endif {0, 0, NULL} }; -@@ -1569,8 +1586,10 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1575,8 +1592,10 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) int r, ret, req_presence = 0, req_verify = 0, valid_data = 0; int encoded_ret; struct sshkey_sig_details *sig_details = NULL; @@ -1214,7 +1216,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) +@@ -1585,6 +1604,8 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal_f("bad key, not previously allowed"); @@ -1223,7 +1225,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) +@@ -1600,14 +1621,19 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) case MM_USERKEY: valid_data = monitor_valid_userblob(ssh, data, datalen); auth_method = "publickey"; @@ -1243,7 +1245,7 @@ index 43c10a4e..fbc35782 100644 break; } if (!valid_data) -@@ -1613,8 +1639,6 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1619,8 +1645,6 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) SSH_FP_DEFAULT)) == NULL) fatal_f("sshkey_fingerprint failed"); @@ -1252,7 +1254,7 @@ index 43c10a4e..fbc35782 100644 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) +@@ -1708,13 +1732,19 @@ mm_record_login(struct ssh *ssh, Session *s, struct passwd *pw) } static void @@ -1273,7 +1275,7 @@ index 43c10a4e..fbc35782 100644 session_unused(s->self); } -@@ -1775,7 +1805,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1781,7 +1811,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) error: if (s != NULL) @@ -1282,7 +1284,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) +@@ -1800,7 +1830,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, int sock, struct sshbuf *m) if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) fatal_fr(r, "parse tty"); if ((s = session_by_tty(tty)) != NULL) @@ -1291,7 +1293,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) +@@ -1822,6 +1852,8 @@ mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req) sshpam_cleanup(); #endif @@ -1300,16 +1302,15 @@ 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) +@@ -1868,12 +1900,46 @@ mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) { char *cmd; int r; + Session *s; - debug3("%s entering", __func__); + debug3_f("entering"); if ((r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ + fatal_fr(r, "buffer error"); /* sanity check command, if so how? */ - audit_run_command(cmd); + s = session_new(); @@ -1349,7 +1350,7 @@ index 43c10a4e..fbc35782 100644 free(cmd); return (0); } -@@ -1940,6 +2007,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1946,6 +2012,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) void mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { @@ -1357,7 +1358,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) +@@ -1953,6 +2020,19 @@ mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3_f("GOT new keys"); @@ -1377,7 +1378,7 @@ index 43c10a4e..fbc35782 100644 } -@@ -2234,3 +2315,102 @@ mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { +@@ -2240,3 +2320,102 @@ mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { #endif /* GSSAPI */ @@ -1481,7 +1482,7 @@ index 43c10a4e..fbc35782 100644 +} +#endif /* SSH_AUDIT_EVENTS */ diff --git a/monitor.h b/monitor.h -index d4d631dd..2c64f07d 100644 +index d4d631ddc..2c64f07dc 100644 --- a/monitor.h +++ b/monitor.h @@ -66,7 +66,13 @@ enum monitor_reqtype { @@ -1500,10 +1501,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 +index 08dc29e12..fb44ae733 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, +@@ -578,7 +578,7 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, */ int @@ -1512,7 +1513,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, +@@ -594,7 +594,8 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -1522,7 +1523,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, +@@ -627,6 +628,22 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, return 0; } @@ -1545,7 +1546,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) +@@ -1043,11 +1060,12 @@ mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) sshbuf_free(m); } @@ -1558,10 +1559,10 @@ index b6e3b3f3..1a079c15 100644 int r; + int handle; - debug3("%s entering command %s", __func__, command); + debug3_f("entering command %s", command); -@@ -1046,6 +1064,30 @@ mm_audit_run_command(const char *command) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); +@@ -1057,6 +1075,30 @@ mm_audit_run_command(const char *command) + fatal_fr(r, "buffer error"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, m); @@ -1591,7 +1592,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) +@@ -1305,3 +1347,83 @@ server_get_connection_info(struct ssh *ssh, int populate, int use_dns) return &ci; } @@ -1676,10 +1677,10 @@ index b6e3b3f3..1a079c15 100644 +} +#endif /* SSH_AUDIT_EVENTS */ diff --git a/monitor_wrap.h b/monitor_wrap.h -index 672dce52..661ed63b 100644 +index 12c489c33..1bcbfd305 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, +@@ -62,7 +62,9 @@ int mm_user_key_allowed(struct ssh *ssh, struct passwd *, struct sshkey *, int, struct sshauthopt **); int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, const char *, struct sshkey *); @@ -1690,7 +1691,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 *); +@@ -89,7 +91,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(struct ssh *, ssh_audit_event_t); @@ -1705,10 +1706,10 @@ index 672dce52..661ed63b 100644 struct Session; diff --git a/packet.c b/packet.c -index 9dea2cfc..344b5f54 100644 +index 5dd8269c2..bc22b8625 100644 --- a/packet.c +++ b/packet.c -@@ -81,6 +81,7 @@ +@@ -77,6 +77,7 @@ #endif #include "xmalloc.h" @@ -1716,7 +1717,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) +@@ -513,6 +514,13 @@ ssh_packet_get_connection_out(struct ssh *ssh) return ssh->state->connection_out; } @@ -1730,10 +1731,10 @@ 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) - { +@@ -683,22 +691,19 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) struct session_state *state = ssh->state; u_int mode; + struct packet *p; + u_int had_keys = packet_state_has_keys(state); if (!state->initialized) @@ -1755,10 +1756,10 @@ index 9dea2cfc..344b5f54 100644 + state->outgoing_packet = NULL; sshbuf_free(state->incoming_packet); + state->incoming_packet = NULL; - 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) + while ((p = TAILQ_FIRST(&state->outgoing))) { + sshbuf_free(p->payload); + TAILQ_REMOVE(&state->outgoing, p, next); +@@ -739,8 +744,18 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); @@ -1777,7 +1778,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) +@@ -1004,6 +1019,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode) (unsigned long long)state->p_send.bytes, (unsigned long long)state->p_send.blocks); kex_free_newkeys(state->newkeys[mode]); @@ -1785,7 +1786,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) +@@ -2345,6 +2361,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1859,7 +1860,7 @@ index 9dea2cfc..344b5f54 100644 static int ssh_packet_set_postauth(struct ssh *ssh) diff --git a/packet.h b/packet.h -index 49bb87f0..44a39a9e 100644 +index 072f27425..e087d4c8a 100644 --- a/packet.h +++ b/packet.h @@ -223,4 +223,5 @@ const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); @@ -1869,19 +1870,18 @@ index 49bb87f0..44a39a9e 100644 +void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ diff --git a/session.c b/session.c -index 28bbb8a7..83fc9418 100644 +index d034f5c65..107edcf91 100644 --- a/session.c +++ b/session.c -@@ -145,7 +145,7 @@ extern char *__progname; +@@ -139,6 +139,7 @@ static int session_pty_req(struct ssh *, Session *); + extern ServerOptions options; + extern char *__progname; extern int debug_flag; - extern u_int utmp_len; - extern int startup_pipe; --extern void destroy_sensitive_data(void); +extern void destroy_sensitive_data(struct ssh *); 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) +@@ -617,6 +618,14 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1895,8 +1895,8 @@ 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) + session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); +@@ -707,15 +716,19 @@ do_exec(struct ssh *ssh, Session *s, const char *command) s->self); #ifdef SSH_AUDIT_EVENTS @@ -1918,7 +1918,7 @@ 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) +@@ -1495,7 +1508,11 @@ do_child(struct ssh *ssh, Session *s, const char *command) sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); /* remove keys from memory */ @@ -1930,7 +1930,7 @@ index 28bbb8a7..83fc9418 100644 /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1750,6 +1766,9 @@ session_unused(int id) +@@ -1710,6 +1727,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1940,7 +1940,7 @@ 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) +@@ -1788,6 +1808,19 @@ session_open(Authctxt *authctxt, int chanid) return 1; } @@ -1960,7 +1960,7 @@ index 28bbb8a7..83fc9418 100644 Session * session_by_tty(char *tty) { -@@ -2445,6 +2477,32 @@ session_exit_message(struct ssh *ssh, Session *s, int status) +@@ -2405,6 +2438,32 @@ session_exit_message(struct ssh *ssh, Session *s, int status) chan_write_failed(ssh, c); } @@ -1993,7 +1993,7 @@ index 28bbb8a7..83fc9418 100644 void session_close(struct ssh *ssh, Session *s) { -@@ -2458,6 +2516,10 @@ session_close(struct ssh *ssh, Session *s) +@@ -2418,6 +2477,10 @@ session_close(struct ssh *ssh, Session *s) if (s->ttyfd != -1) session_pty_cleanup(s); @@ -2004,7 +2004,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) +@@ -2494,14 +2557,14 @@ session_close_by_channel(struct ssh *ssh, int id, int force, void *arg) } void @@ -2021,7 +2021,7 @@ index 28bbb8a7..83fc9418 100644 else session_close(ssh, s); } -@@ -2668,6 +2730,15 @@ do_authenticated2(struct ssh *ssh, Authctxt *authctxt) +@@ -2627,6 +2690,15 @@ do_authenticated2(struct ssh *ssh, Authctxt *authctxt) server_loop2(ssh, authctxt); } @@ -2037,7 +2037,7 @@ index 28bbb8a7..83fc9418 100644 void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2731,7 +2802,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2690,7 +2762,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) * or if running in monitor. */ if (mm_is_monitor()) @@ -2047,7 +2047,7 @@ 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 +index 344a1ddf9..a41c6efcd 100644 --- a/session.h +++ b/session.h @@ -61,6 +61,12 @@ struct Session { @@ -2078,10 +2078,10 @@ index 344a1ddf..a41c6efc 100644 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 +index d6bece941..e49e4fb51 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -194,8 +194,8 @@ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); +@@ -188,8 +188,8 @@ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); struct sshbuf *loginmsg; /* Prototypes for various functions defined later in this file. */ @@ -2092,7 +2092,7 @@ index 81d30152..a808ac9a 100644 /* XXX reduce to stub once postauth split */ int -@@ -208,6 +208,41 @@ mm_is_monitor(void) +@@ -202,6 +202,35 @@ mm_is_monitor(void) return (pmonitor && pmonitor->m_pid > 0); } @@ -2108,12 +2108,6 @@ index 81d30152..a808ac9a 100644 + RSA_get0_key(rsa, NULL, NULL, &d); + return d != NULL; + } -+ case KEY_DSA_CERT: -+ case KEY_DSA: { -+ const BIGNUM *priv_key; -+ DSA_get0_key(k->dsa, NULL, &priv_key); -+ return priv_key != NULL; -+ } +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: { @@ -2134,7 +2128,7 @@ index 81d30152..a808ac9a 100644 /* * 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) +@@ -230,18 +259,40 @@ grace_alarm_handler(int sig) _exit(EXIT_LOGIN_GRACE); } @@ -2178,7 +2172,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) +@@ -250,20 +301,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2218,7 +2212,7 @@ index 81d30152..a808ac9a 100644 } /* Certs do not need demotion */ } -@@ -463,7 +538,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -441,7 +510,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ @@ -2227,7 +2221,7 @@ index 81d30152..a808ac9a 100644 reseed_prngs(); -@@ -1387,6 +1462,9 @@ main(int ac, char **av) +@@ -1365,6 +1434,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ @@ -2237,7 +2231,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, +@@ -1410,6 +1482,14 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, void cleanup_exit(int i) { @@ -2252,7 +2246,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) +@@ -1426,7 +1506,9 @@ cleanup_exit(int i) } #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ @@ -2264,10 +2258,10 @@ index 81d30152..a808ac9a 100644 #endif /* Override default fatal exit value when auth was attempted */ diff --git a/sshd.c b/sshd.c -index c9ea8e38..8a99f0b2 100644 +index 3ab81e268..ed7faf96d 100644 --- a/sshd.c +++ b/sshd.c -@@ -217,6 +217,15 @@ close_listen_socks(void) +@@ -213,6 +213,15 @@ close_listen_socks(void) num_listen_socks = 0; } @@ -2283,7 +2277,7 @@ index c9ea8e38..8a99f0b2 100644 /* 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, +@@ -958,6 +967,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); @@ -2292,5 +2286,5 @@ index c9ea8e38..8a99f0b2 100644 if (options.pid_file != NULL) unlink(options.pid_file); -- -2.49.0 +2.52.0 diff --git a/0040-openssh-7.1p2-audit-race-condition.patch b/0036-openssh-7.1p2-audit-race-condition.patch similarity index 85% rename from 0040-openssh-7.1p2-audit-race-condition.patch rename to 0036-openssh-7.1p2-audit-race-condition.patch index fe732a6..863f700 100644 --- a/0040-openssh-7.1p2-audit-race-condition.patch +++ b/0036-openssh-7.1p2-audit-race-condition.patch @@ -1,7 +1,7 @@ -From c288d4a26ad44dc481c9d18d2920c9d70474833c Mon Sep 17 00:00:00 2001 +From ffa3fdb2ad2c7afc91993d9301e35d2e9a83ea47 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 +Subject: [PATCH 36/53] openssh-7.1p2-audit-race-condition --- monitor_wrap.c | 46 +++++++++++++++++++++++++++++++++++++ @@ -10,10 +10,10 @@ Subject: [PATCH 40/50] openssh-7.1p2-audit-race-condition 3 files changed, 102 insertions(+), 7 deletions(-) diff --git a/monitor_wrap.c b/monitor_wrap.c -index 1a079c15..768a59f9 100644 +index fb44ae733..17a6c9786 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_ +@@ -1426,4 +1426,50 @@ mm_audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m); sshbuf_free(m); } @@ -65,10 +65,10 @@ index 1a079c15..768a59f9 100644 +} #endif /* SSH_AUDIT_EVENTS */ diff --git a/monitor_wrap.h b/monitor_wrap.h -index 661ed63b..e957ba6e 100644 +index 1bcbfd305..2b814dbd1 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -93,6 +93,8 @@ void mm_audit_unsupported_body(struct ssh *, int); +@@ -97,6 +97,8 @@ void mm_audit_unsupported_body(struct ssh *, 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); @@ -78,10 +78,10 @@ index 661ed63b..e957ba6e 100644 struct Session; diff --git a/session.c b/session.c -index 83fc9418..b4753d93 100644 +index 107edcf91..80282dfd8 100644 --- a/session.c +++ b/session.c -@@ -167,6 +167,10 @@ static Session *sessions = NULL; +@@ -161,6 +161,10 @@ static Session *sessions = NULL; login_cap_t *lc; #endif @@ -92,7 +92,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) +@@ -358,6 +362,8 @@ xauth_valid_string(const char *s) return 1; } @@ -101,7 +101,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) +@@ -481,6 +487,8 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) close(err[0]); #endif @@ -110,7 +110,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) +@@ -595,6 +603,9 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) /* Close the extra descriptor for the pseudo tty. */ close(ttyfd); @@ -120,7 +120,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) +@@ -729,6 +740,8 @@ do_exec(struct ssh *ssh, Session *s, const char *command) } if (s->command != NULL && s->ptyfd == -1) s->command_handle = mm_audit_run_command(ssh, s->command); @@ -129,7 +129,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) +@@ -744,6 +757,20 @@ do_exec(struct ssh *ssh, Session *s, const char *command) */ sshbuf_reset(loginmsg); @@ -150,7 +150,7 @@ index 83fc9418..b4753d93 100644 return ret; } -@@ -1532,6 +1559,33 @@ child_close_fds(struct ssh *ssh) +@@ -1490,6 +1517,33 @@ child_close_fds(struct ssh *ssh) log_redirect_stderr_to(NULL); } @@ -184,7 +184,7 @@ 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) +@@ -1507,13 +1561,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); @@ -199,5 +199,5 @@ index 83fc9418..b4753d93 100644 if (s->authctxt->force_pwchange) { do_setusercontext(pw); -- -2.49.0 +2.52.0 diff --git a/0041-openssh-9.0p1-audit-log.patch b/0037-openssh-9.0p1-audit-log.patch similarity index 92% rename from 0041-openssh-9.0p1-audit-log.patch rename to 0037-openssh-9.0p1-audit-log.patch index e04f31b..c58a5fe 100644 --- a/0041-openssh-9.0p1-audit-log.patch +++ b/0037-openssh-9.0p1-audit-log.patch @@ -1,7 +1,7 @@ -From 80d967a18261156573e7385f8e534a89d2767d67 Mon Sep 17 00:00:00 2001 +From ef05b1fceddc64cfc7eb40daac60a137634d0a9f 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 +Subject: [PATCH 37/53] openssh-9.0p1-audit-log --- audit-bsm.c | 2 +- @@ -11,7 +11,7 @@ Subject: [PATCH 41/50] openssh-9.0p1-audit-log 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/audit-bsm.c b/audit-bsm.c -index a49abb92..c6f56553 100644 +index a6292cb8f..0f2ef8235 100644 --- a/audit-bsm.c +++ b/audit-bsm.c @@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li) @@ -24,7 +24,7 @@ index a49abb92..c6f56553 100644 /* not implemented */ } diff --git a/audit-linux.c b/audit-linux.c -index d484b82b..dcfde3a9 100644 +index 4d3e9d41e..d2bc0b526 100644 --- a/audit-linux.c +++ b/audit-linux.c @@ -52,7 +52,7 @@ extern u_int utmp_len; @@ -36,8 +36,8 @@ 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, - } +@@ -68,7 +68,7 @@ linux_audit_user_logxxx(int uid, const char *username, + hostname = NULL; rc = audit_log_acct_message(audit_fd, event, NULL, "login", username ? username : "(unknown)", - username == NULL ? uid : -1, NULL, ip, ttyn, success); @@ -45,7 +45,7 @@ index d484b82b..dcfde3a9 100644 saved_errno = errno; close(audit_fd); -@@ -137,10 +137,12 @@ fatal_report: +@@ -139,10 +139,12 @@ fatal_report: } int @@ -59,7 +59,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) +@@ -152,14 +154,44 @@ audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) else return 0; /* Must prevent login */ } @@ -107,7 +107,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) +@@ -181,26 +213,34 @@ audit_connection_from(const char *host, int port) int audit_run_command(struct ssh *ssh, const char *command) { @@ -142,7 +142,7 @@ index d484b82b..dcfde3a9 100644 } void -@@ -211,31 +251,41 @@ void +@@ -213,31 +253,41 @@ void audit_session_open(struct logininfo *li) { if (!user_login_count++) @@ -189,7 +189,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) +@@ -257,9 +307,11 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) if (user_login_count) { while (user_login_count--) linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, @@ -201,7 +201,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) +@@ -268,12 +320,14 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) case SSH_CONNECTION_ABANDON: case SSH_INVALID_USER: linux_audit_user_logxxx(-1, audit_username(), @@ -209,7 +209,7 @@ index d484b82b..dcfde3a9 100644 ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; default: - debug("%s: unhandled event %d", __func__, event); + debug_f("unhandled event %d", event); break; } + free(audit_hostname); @@ -217,7 +217,7 @@ index d484b82b..dcfde3a9 100644 void diff --git a/audit.c b/audit.c -index d0433c3a..28d51a14 100644 +index d0433c3a0..28d51a146 100644 --- a/audit.c +++ b/audit.c @@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev) @@ -248,7 +248,7 @@ index d0433c3a..28d51a14 100644 void diff --git a/audit.h b/audit.h -index 45d66ccf..05ac132c 100644 +index 45d66ccff..05ac132cf 100644 --- a/audit.h +++ b/audit.h @@ -64,7 +64,7 @@ void audit_session_close(struct logininfo *); @@ -261,5 +261,5 @@ index 45d66ccf..05ac132c 100644 void audit_unsupported(struct ssh *, int); void audit_kex(struct ssh *, int, char *, char *, char *, char *); -- -2.49.0 +2.52.0 diff --git a/0042-openssh-7.7p1-fips.patch b/0038-openssh-7.7p1-fips.patch similarity index 77% rename from 0042-openssh-7.7p1-fips.patch rename to 0038-openssh-7.7p1-fips.patch index f4729d7..18ebed3 100644 --- a/0042-openssh-7.7p1-fips.patch +++ b/0038-openssh-7.7p1-fips.patch @@ -1,7 +1,7 @@ -From 6e0e7462959e8bc6a99f50dbf9a5b42ae74c2c87 Mon Sep 17 00:00:00 2001 +From d7dd45f9e19a71269828bc5f8567613a02f6feef Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy -Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 42/50] openssh-7.7p1-fips +Date: Thu, 28 Aug 2025 14:01:38 +0200 +Subject: [PATCH 38/53] openssh-7.7p1-fips --- dh.c | 41 ++++++++++++++++++++++ @@ -13,19 +13,19 @@ Subject: [PATCH 42/50] openssh-7.7p1-fips myproposal.h | 33 ++++++++++++++++++ readconf.c | 16 ++++++--- sandbox-seccomp-filter.c | 3 ++ - servconf.c | 16 ++++++--- + servconf.c | 18 +++++++--- ssh-ed25519.c | 9 +++++ - ssh-keygen.c | 22 ++++++++++-- + ssh-gss.h | 5 +++ + ssh-keygen.c | 20 +++++++++-- ssh-rsa.c | 3 ++ ssh.c | 5 +++ - sshconnect2.c | 61 ++++++++++++++++++--------------- - sshd-auth.c | 13 ++++--- + sshconnect2.c | 9 ++++- sshd.c | 13 +++++++ sshkey.c | 37 ++++++++++++++++++++ - 18 files changed, 301 insertions(+), 60 deletions(-) + 18 files changed, 271 insertions(+), 30 deletions(-) diff --git a/dh.c b/dh.c -index 168dea1d..8c9a29fa 100644 +index 168dea1dd..8c9a29fa7 100644 --- a/dh.c +++ b/dh.c @@ -36,6 +36,7 @@ @@ -89,7 +89,7 @@ index 168dea1d..8c9a29fa 100644 + #endif /* WITH_OPENSSL */ diff --git a/dh.h b/dh.h -index c6326a39..e51e292b 100644 +index c6326a39d..e51e292b8 100644 --- a/dh.h +++ b/dh.h @@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); @@ -101,7 +101,7 @@ index c6326a39..e51e292b 100644 u_int dh_estimate(int); void dh_set_moduli_file(const char *); diff --git a/kex-names.c b/kex-names.c -index 6c0b7c2b..cd3902ad 100644 +index 31e395aa2..1360a4095 100644 --- a/kex-names.c +++ b/kex-names.c @@ -33,6 +33,7 @@ @@ -112,7 +112,7 @@ index 6c0b7c2b..cd3902ad 100644 #include #endif -@@ -206,7 +207,10 @@ kex_names_valid(const char *names) +@@ -208,7 +209,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,10 +125,10 @@ index 6c0b7c2b..cd3902ad 100644 return 0; } diff --git a/kex.c b/kex.c -index 62f607d6..71fbe5cb 100644 +index 44f350ce8..da2a537ce 100644 --- a/kex.c +++ b/kex.c -@@ -40,6 +40,7 @@ +@@ -38,6 +38,7 @@ #ifdef WITH_OPENSSL #include #include @@ -136,7 +136,7 @@ index 62f607d6..71fbe5cb 100644 # ifdef HAVE_EVP_KDF_CTX_NEW # include # include -@@ -109,7 +110,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], +@@ -107,7 +108,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], /* Append EXT_INFO signalling to KexAlgorithms */ if (kexalgos == NULL) @@ -146,7 +146,7 @@ index 62f607d6..71fbe5cb 100644 "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 15df591c..eecdceba 100644 +index 58edc79ad..9a970adf1 100644 --- a/kexgen.c +++ b/kexgen.c @@ -31,6 +31,7 @@ @@ -159,7 +159,7 @@ index 15df591c..eecdceba 100644 #include "kex.h" @@ -115,13 +116,28 @@ kex_gen_client(struct ssh *ssh) break; - #endif + #endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: - r = kex_c25519_keypair(kex); + if (FIPS_mode()) { @@ -191,7 +191,7 @@ index 15df591c..eecdceba 100644 r = SSH_ERR_INVALID_ARGUMENT; @@ -189,15 +205,30 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) break; - #endif + #endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: - r = kex_c25519_dec(kex, server_blob, &shared_secret); + if (FIPS_mode()) { @@ -227,7 +227,7 @@ index 15df591c..eecdceba 100644 r = SSH_ERR_INVALID_ARGUMENT; @@ -312,16 +343,31 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) break; - #endif + #endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: - r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, - &shared_secret); @@ -264,7 +264,7 @@ index 15df591c..eecdceba 100644 default: r = SSH_ERR_INVALID_ARGUMENT; diff --git a/kexgexc.c b/kexgexc.c -index e99e0cf2..4c3feae0 100644 +index 097d83f30..ccbb9b580 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -28,6 +28,7 @@ @@ -274,7 +274,7 @@ index e99e0cf2..4c3feae0 100644 +#include #include - #include + #include "openbsd-compat/openssl-compat.h" @@ -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; @@ -287,7 +287,7 @@ index e99e0cf2..4c3feae0 100644 /* generate and send 'e', client DH public key */ diff --git a/myproposal.h b/myproposal.h -index 8fe9276c..3e0ec682 100644 +index 8fe9276c2..3e0ec6826 100644 --- a/myproposal.h +++ b/myproposal.h @@ -58,6 +58,18 @@ @@ -338,10 +338,10 @@ index 8fe9276c..3e0ec682 100644 #define SSH_ALLOWED_CA_SIGALGS \ "ssh-ed25519," \ diff --git a/readconf.c b/readconf.c -index f340bf50..ea9d293c 100644 +index 3f67f4de4..b6ad47b49 100644 --- a/readconf.c +++ b/readconf.c -@@ -43,6 +43,7 @@ +@@ -39,6 +39,7 @@ #include #include #include @@ -349,7 +349,7 @@ index f340bf50..ea9d293c 100644 #ifdef USE_SYSTEM_GLOB # include #else -@@ -3043,11 +3044,16 @@ fill_default_options(Options * options) +@@ -3078,11 +3079,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 */ @@ -372,10 +372,10 @@ index f340bf50..ea9d293c 100644 do { \ if ((r = kex_assemble_names(&options->what, \ diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 1fabf99d..ccb61586 100644 +index e0f2d4289..c52f64897 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c -@@ -230,6 +230,9 @@ static const struct sock_filter preauth_insns[] = { +@@ -258,6 +258,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_open SC_DENY(__NR_open, EACCES), #endif @@ -386,18 +386,21 @@ index 1fabf99d..ccb61586 100644 SC_DENY(__NR_openat, EACCES), #endif diff --git a/servconf.c b/servconf.c -index 84891544..8b708cbf 100644 +index ac84b74d9..f78615c28 100644 --- a/servconf.c +++ b/servconf.c -@@ -37,6 +37,7 @@ +@@ -37,7 +37,10 @@ #include #include #include +#include - #ifdef HAVE_UTIL_H ++#ifdef HAVE_UTIL_H #include - #endif -@@ -247,11 +248,16 @@ assemble_algorithms(ServerOptions *o) ++#endif + #ifdef USE_SYSTEM_GLOB + # include + #else +@@ -244,11 +247,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 */ @@ -420,7 +423,7 @@ index 84891544..8b708cbf 100644 do { \ if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ diff --git a/ssh-ed25519.c b/ssh-ed25519.c -index 22d8db02..41942f4e 100644 +index c8caa2221..4bcd9ef81 100644 --- a/ssh-ed25519.c +++ b/ssh-ed25519.c @@ -24,6 +24,7 @@ @@ -431,7 +434,7 @@ index 22d8db02..41942f4e 100644 #include "log.h" #include "sshbuf.h" -@@ -164,6 +165,10 @@ ssh_ed25519_sign(struct sshkey *key, +@@ -163,6 +164,10 @@ ssh_ed25519_sign(struct sshkey *key, key->ed25519_sk == NULL || datalen >= INT_MAX - crypto_sign_ed25519_BYTES) return SSH_ERR_INVALID_ARGUMENT; @@ -442,7 +445,7 @@ index 22d8db02..41942f4e 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, +@@ -244,6 +249,10 @@ ssh_ed25519_verify(const struct sshkey *key, dlen >= INT_MAX - crypto_sign_ed25519_BYTES || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; @@ -453,40 +456,54 @@ index 22d8db02..41942f4e 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 16cff947..792aafde 100644 +index 3c582a83a..afa279097 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c -@@ -20,6 +20,7 @@ - - #ifdef WITH_OPENSSL +@@ -22,6 +22,7 @@ + #include "openbsd-compat/openssl-compat.h" + #include #include +#include #include - #include "openbsd-compat/openssl-compat.h" #endif + @@ -68,6 +69,7 @@ - #include "cipher.h" + #endif #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) + * Default number of bits in the RSA and ECDSA keys. These value can be +@@ -195,6 +197,10 @@ 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) + case KEY_RSA: + if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE) +@@ -248,7 +254,7 @@ ask_filename(struct passwd *pw, const char *prompt) char *name = NULL; if (key_type_name == NULL) @@ -494,15 +511,15 @@ index 16cff947..792aafde 100644 + 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) + #ifdef OPENSSL_HAS_ECC +@@ -1057,9 +1063,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)) { ++ if (FIPS_mode() && type == KEY_ED25519) { + logit("Skipping %s key in FIPS mode", + key_types[i].key_type_display); + goto next; @@ -514,7 +531,7 @@ index 16cff947..792aafde 100644 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) +@@ -3757,7 +3771,7 @@ main(int argc, char **argv) } if (key_type_name == NULL) @@ -524,11 +541,11 @@ index 16cff947..792aafde 100644 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 3ad1fddc..6c2f771a 100644 +index fe1518984..9428df8d1 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c -@@ -23,6 +23,7 @@ - +@@ -25,6 +25,7 @@ + #include #include #include +#include @@ -545,10 +562,10 @@ index 3ad1fddc..6c2f771a 100644 goto out; } diff --git a/ssh.c b/ssh.c -index 98b103c9..abc8b843 100644 +index 8d27f6379..7d6ba516e 100644 --- a/ssh.c +++ b/ssh.c -@@ -78,6 +78,7 @@ +@@ -74,6 +74,7 @@ #include #include #endif @@ -556,7 +573,7 @@ index 98b103c9..abc8b843 100644 #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -1642,6 +1643,10 @@ main(int ac, char **av) +@@ -1664,6 +1665,10 @@ main(int ac, char **av) exit(0); } @@ -568,7 +585,7 @@ index 98b103c9..abc8b843 100644 if (options.sk_provider != NULL && *options.sk_provider == '$' && strlen(options.sk_provider) > 1) { diff --git a/sshconnect2.c b/sshconnect2.c -index 0af15bcc..14f7671a 100644 +index b253f991b..fffa66c8d 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -45,6 +45,8 @@ @@ -580,119 +597,40 @@ index 0af15bcc..14f7671a 100644 #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -262,36 +264,41 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +@@ -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) { -- /* 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]; ++ char * gss_kex_filtered = FIPS_mode() ? ++ match_filter_allowlist(options.gss_kex_algorithms, GSS_KEX_DEFAULT_KEX_FIPS) : xstrdup(options.gss_kex_algorithms); + -+ 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); -+ } + /* 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, } - } - #endif -diff --git a/sshd-auth.c b/sshd-auth.c -index 897db9b4..eaf32981 100644 ---- a/sshd-auth.c -+++ b/sshd-auth.c -@@ -58,6 +58,7 @@ - #ifdef WITH_OPENSSL - #include - #include -+#include - #endif - #include "xmalloc.h" -@@ -859,10 +860,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); + 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.c b/sshd.c -index 8a99f0b2..5ff0b5ff 100644 +index ed7faf96d..de2baa5e4 100644 --- a/sshd.c +++ b/sshd.c -@@ -52,6 +52,7 @@ - #endif +@@ -44,6 +44,7 @@ + #include #include #include +#include #include #include #include -@@ -63,6 +64,7 @@ +@@ -55,6 +56,7 @@ #ifdef WITH_OPENSSL #include #include @@ -700,7 +638,7 @@ index 8a99f0b2..5ff0b5ff 100644 #include "openbsd-compat/openssl-compat.h" #endif -@@ -1611,6 +1613,13 @@ main(int ac, char **av) +@@ -1613,6 +1615,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]); @@ -714,7 +652,7 @@ index 8a99f0b2..5ff0b5ff 100644 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) +@@ -1836,6 +1845,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); @@ -726,10 +664,10 @@ index 8a99f0b2..5ff0b5ff 100644 * Chdir to the root directory so that the current disk can be * unmounted if desired. diff --git a/sshkey.c b/sshkey.c -index 4e41a78c..ca1cdb64 100644 +index 148fee2b7..394d9b105 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -35,6 +35,7 @@ +@@ -36,6 +36,7 @@ #include #include #include @@ -737,15 +675,15 @@ index 4e41a78c..ca1cdb64 100644 #endif #include "crypto_api.h" -@@ -59,6 +60,7 @@ +@@ -58,6 +59,7 @@ #define SSHKEY_INTERNAL #include "sshkey.h" #include "match.h" +#include "log.h" #include "ssh-sk.h" + #include "ssh-pkcs11.h" - #ifdef WITH_XMSS -@@ -408,6 +410,18 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -386,6 +388,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; @@ -764,7 +702,7 @@ index 4e41a78c..ca1cdb64 100644 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) +@@ -1418,6 +1432,20 @@ sshkey_read(struct sshkey *ret, char **cpp) return SSH_ERR_EC_CURVE_MISMATCH; } @@ -785,7 +723,7 @@ index 4e41a78c..ca1cdb64 100644 /* Fill in ret from parsed key */ sshkey_free_contents(ret); *ret = *k; -@@ -2275,6 +2303,11 @@ sshkey_sign(struct sshkey *key, +@@ -2251,6 +2279,11 @@ sshkey_sign(struct sshkey *key, *lenp = 0; if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; @@ -797,7 +735,7 @@ index 4e41a78c..ca1cdb64 100644 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, +@@ -2290,6 +2323,10 @@ sshkey_verify(const struct sshkey *key, *detailsp = NULL; if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; @@ -809,5 +747,5 @@ index 4e41a78c..ca1cdb64 100644 return SSH_ERR_KEY_TYPE_UNKNOWN; return impl->funcs->verify(key, sig, siglen, data, dlen, -- -2.49.0 +2.52.0 diff --git a/0043-openssh-8.7p1-ssh-manpage.patch b/0039-openssh-8.7p1-ssh-manpage.patch similarity index 87% rename from 0043-openssh-8.7p1-ssh-manpage.patch rename to 0039-openssh-8.7p1-ssh-manpage.patch index 89c6ea1..d0e984d 100644 --- a/0043-openssh-8.7p1-ssh-manpage.patch +++ b/0039-openssh-8.7p1-ssh-manpage.patch @@ -1,14 +1,14 @@ -From 299a602802d7c7d121306eb2aeae1502871a35cb Mon Sep 17 00:00:00 2001 +From 7167a191776dacf7e31cf8a8a2ed89887e49f4ee 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 +Subject: [PATCH 39/53] 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 +index 6a9fbdc5b..755cdef2b 100644 --- a/ssh.1 +++ b/ssh.1 @@ -510,12 +510,12 @@ For full details of the options listed below, and their possible values, see @@ -43,5 +43,5 @@ index 6a9fbdc5..755cdef2 100644 .It RevokedHostKeys .It SecurityKeyProvider -- -2.49.0 +2.52.0 diff --git a/0044-openssh-8.7p1-negotiate-supported-algs.patch b/0040-openssh-8.7p1-negotiate-supported-algs.patch similarity index 95% rename from 0044-openssh-8.7p1-negotiate-supported-algs.patch rename to 0040-openssh-8.7p1-negotiate-supported-algs.patch index f4c3b8a..29f8213 100644 --- a/0044-openssh-8.7p1-negotiate-supported-algs.patch +++ b/0040-openssh-8.7p1-negotiate-supported-algs.patch @@ -1,7 +1,7 @@ -From 5c92430c08ac392b5b2ace899cc043247c923734 Mon Sep 17 00:00:00 2001 +From 53e44bd1f669ecd6a7429e94b55beec8e3c0c529 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 +Subject: [PATCH 40/53] openssh-8.7p1-negotiate-supported-algs --- regress/hostkey-agent.sh | 32 +++++++++++++++++++++++++------- @@ -9,7 +9,7 @@ Subject: [PATCH 44/50] openssh-8.7p1-negotiate-supported-algs 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh -index 28dcfe17..b9e716dc 100644 +index 28dcfe170..b9e716dcd 100644 --- a/regress/hostkey-agent.sh +++ b/regress/hostkey-agent.sh @@ -17,8 +17,21 @@ trace "make CA key" @@ -84,7 +84,7 @@ index 28dcfe17..b9e716dc 100644 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 +index fffa66c8d..f43c81ad9 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, @@ -129,5 +129,5 @@ index 14f7671a..ad3f560f 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) -- -2.49.0 +2.52.0 diff --git a/0045-openssh-9.0p1-evp-fips-kex.patch b/0041-openssh-9.0p1-evp-fips-kex.patch similarity index 95% rename from 0045-openssh-9.0p1-evp-fips-kex.patch rename to 0041-openssh-9.0p1-evp-fips-kex.patch index 610cea0..24ef8e8 100644 --- a/0045-openssh-9.0p1-evp-fips-kex.patch +++ b/0041-openssh-9.0p1-evp-fips-kex.patch @@ -1,7 +1,7 @@ -From be23afbab800c9b5ffea56b3f410a04156c08df2 Mon Sep 17 00:00:00 2001 +From 1c0d3b6e9868ef31b97be1679389e3db2616eccd 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 +Subject: [PATCH 41/53] openssh-9.0p1-evp-fips-kex --- dh.c | 98 +++++++++++++++++++++++++++++++++----- @@ -12,7 +12,7 @@ Subject: [PATCH 45/50] openssh-9.0p1-evp-fips-kex 5 files changed, 382 insertions(+), 42 deletions(-) diff --git a/dh.c b/dh.c -index 8c9a29fa..ea0a0b09 100644 +index 8c9a29fa7..ea0a0b093 100644 --- a/dh.c +++ b/dh.c @@ -37,6 +37,9 @@ @@ -140,10 +140,10 @@ index 8c9a29fa..ea0a0b09 100644 DH * diff --git a/kex.c b/kex.c -index 71fbe5cb..ce6a7b81 100644 +index da2a537ce..56c80395c 100644 --- a/kex.c +++ b/kex.c -@@ -1614,3 +1614,142 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, +@@ -1613,3 +1613,142 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, return r; } @@ -287,7 +287,7 @@ index 71fbe5cb..ce6a7b81 100644 +} +#endif /* WITH_OPENSSL */ diff --git a/kex.h b/kex.h -index 6a55aadf..48f3bb87 100644 +index cb06e85a3..6daafb159 100644 --- a/kex.h +++ b/kex.h @@ -37,6 +37,9 @@ @@ -300,7 +300,7 @@ index 6a55aadf..48f3bb87 100644 # ifdef OPENSSL_HAS_ECC # include # else /* OPENSSL_HAS_ECC */ -@@ -311,6 +314,9 @@ int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], +@@ -316,6 +319,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))); @@ -311,12 +311,12 @@ index 6a55aadf..48f3bb87 100644 #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 +index 6d5a7813d..b05277aa1 100644 --- a/kexdh.c +++ b/kexdh.c -@@ -35,6 +35,10 @@ - +@@ -36,6 +36,10 @@ #include "openbsd-compat/openssl-compat.h" + #include #include +#include +#include @@ -325,7 +325,7 @@ index 0faab21b..32e1de51 100644 #include "sshkey.h" #include "kex.h" -@@ -83,9 +87,12 @@ int +@@ -84,9 +88,12 @@ int kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) { BIGNUM *shared_secret = NULL; @@ -339,7 +339,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) +@@ -101,24 +108,59 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) r = SSH_ERR_MESSAGE_INCOMPLETE; goto out; } @@ -404,12 +404,12 @@ index 0faab21b..32e1de51 100644 } diff --git a/kexecdh.c b/kexecdh.c -index efb2e55a..d92ba54f 100644 +index 500ec5725..1a1bae35e 100644 --- a/kexecdh.c +++ b/kexecdh.c -@@ -35,17 +35,57 @@ - #include +@@ -36,17 +36,57 @@ + #include #include +#include +#include @@ -465,7 +465,7 @@ index efb2e55a..d92ba54f 100644 int kex_ecdh_keypair(struct kex *kex) { -@@ -55,11 +95,7 @@ kex_ecdh_keypair(struct kex *kex) +@@ -56,11 +96,7 @@ kex_ecdh_keypair(struct kex *kex) struct sshbuf *buf = NULL; int r; @@ -478,7 +478,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, +@@ -102,11 +138,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, *server_blobp = NULL; *shared_secretp = NULL; @@ -491,7 +491,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, +@@ -141,11 +173,21 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, { struct sshbuf *buf = NULL; BIGNUM *shared_secret = NULL; @@ -516,7 +516,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, +@@ -154,45 +196,82 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, } if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0) goto out; @@ -612,5 +612,5 @@ index efb2e55a..d92ba54f 100644 return r; } -- -2.49.0 +2.52.0 diff --git a/0046-openssh-8.7p1-nohostsha1proof.patch b/0042-openssh-8.7p1-nohostsha1proof.patch similarity index 83% rename from 0046-openssh-8.7p1-nohostsha1proof.patch rename to 0042-openssh-8.7p1-nohostsha1proof.patch index 9e75c8a..681d051 100644 --- a/0046-openssh-8.7p1-nohostsha1proof.patch +++ b/0042-openssh-8.7p1-nohostsha1proof.patch @@ -1,24 +1,24 @@ -From e4ca3b9dba1cc832a9974493c91207d42e218a68 Mon Sep 17 00:00:00 2001 +From 1cd47036353899fe066f5241d3d70778f103c0e0 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 +Subject: [PATCH 42/53] openssh-8.7p1-nohostsha1proof --- - compat.c | 6 +++++ + compat.c | 6 ++++++ compat.h | 2 +- - monitor.c | 27 ++++++++++++++++------ + 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 ++++- + regress/unittests/sshkey/test_sshkey.c | 30 ++++++++++++++++---------- + serverloop.c | 6 +++++- ssh-rsa.c | 3 ++- sshconnect2.c | 8 +++++++ - sshd-session.c | 21 +++++++++++++++++ - 11 files changed, 90 insertions(+), 24 deletions(-) + sshd-session.c | 21 ++++++++++++++++++ + 11 files changed, 88 insertions(+), 24 deletions(-) diff --git a/compat.c b/compat.c -index b59f0bfc..4e611dc3 100644 +index b59f0bfc0..4e611dc39 100644 --- a/compat.c +++ b/compat.c @@ -42,6 +42,7 @@ void @@ -52,7 +52,7 @@ 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 +index 1a19060fc..2e6db5bf9 100644 --- a/compat.h +++ b/compat.h @@ -30,7 +30,7 @@ @@ -65,10 +65,10 @@ index 1a19060f..2e6db5bf 100644 /* #define unused 0x00000020 */ #define SSH_BUG_DEBUG 0x00000040 diff --git a/monitor.c b/monitor.c -index fbc35782..19cb058e 100644 +index b2f501790..6c83739ee 100644 --- a/monitor.c +++ b/monitor.c -@@ -747,11 +747,12 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -754,11 +754,12 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) struct sshkey *pubkey, *key; struct sshbuf *sigbuf = NULL; u_char *p = NULL, *signature = NULL; @@ -85,7 +85,7 @@ index fbc35782..19cb058e 100644 debug3_f("entering"); -@@ -809,18 +810,30 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -816,18 +817,30 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) } if ((key = get_hostkey_by_index(keyid)) != NULL) { @@ -120,13 +120,13 @@ index fbc35782..19cb058e 100644 sshbuf_reset(m); diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c -index caf8f57f..09016aea 100644 +index 16c2f2dff..f4700deeb 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) - memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); - if (kex != NULL) - kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; +@@ -110,7 +110,8 @@ do_kex_with_key(char *kex, char *cipher, char *mac, + kex_params.proposal[PROPOSAL_MAC_ALGS_CTOS] = mac; + kex_params.proposal[PROPOSAL_MAC_ALGS_STOC] = mac; + } - keyname = strdup(sshkey_ssh_name(private)); + keyname = (strcmp(sshkey_ssh_name(private), "ssh-rsa")) ? + strdup(sshkey_ssh_name(private)) : strdup("rsa-sha2-256"); @@ -134,10 +134,10 @@ index caf8f57f..09016aea 100644 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 +index e412b75d8..5b06bc905 100644 --- a/regress/unittests/sshkey/test_file.c +++ b/regress/unittests/sshkey/test_file.c -@@ -109,6 +109,7 @@ sshkey_file_tests(void) +@@ -106,6 +106,7 @@ sshkey_file_tests(void) sshkey_free(k2); TEST_DONE(); @@ -145,7 +145,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) +@@ -113,7 +114,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); @@ -155,10 +155,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 +index d0f47d7cf..ba4d506d5 100644 --- a/regress/unittests/sshkey/test_fuzz.c +++ b/regress/unittests/sshkey/test_fuzz.c -@@ -338,13 +338,14 @@ sshkey_fuzz_tests(void) +@@ -273,13 +273,14 @@ sshkey_fuzz_tests(void) TEST_DONE(); #ifdef WITH_OPENSSL @@ -175,10 +175,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 +index d0c46a90b..7b5e51b83 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, +@@ -59,6 +59,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type, u_char *sigblob; size_t siglen; @@ -188,7 +188,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, +@@ -100,8 +103,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type, 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,14 +200,12 @@ 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, +@@ -118,16 +122,20 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, { size_t len; u_char *sig; -+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp in RHEL, permitted in Fedora */ ++ /* ssh-rsa implies SHA1, forbidden in DEFAULT crypto policies */ + int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 0) : 0; -+ if (k && (sshkey_type_plain(k->type) == KEY_DSA || sshkey_type_plain(k->type) == KEY_DSA_CERT)) -+ expected = sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 0); ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, - NULL, NULL, 0), 0); @@ -231,7 +229,7 @@ index 5bf4b65c..6d0a35bb 100644 free(sig); } -@@ -526,7 +536,7 @@ sshkey_tests(void) +@@ -552,7 +560,7 @@ sshkey_tests(void) ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); k3 = get_private("rsa_1"); @@ -241,10 +239,10 @@ index 5bf4b65c..6d0a35bb 100644 SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); ASSERT_PTR_EQ(k4, NULL); diff --git a/serverloop.c b/serverloop.c -index 40ddfb04..9c5b1567 100644 +index 5d3b194d1..55411a6b4 100644 --- a/serverloop.c +++ b/serverloop.c -@@ -80,6 +80,7 @@ +@@ -76,6 +76,7 @@ #include "auth-options.h" #include "serverloop.h" #include "ssherr.h" @@ -252,7 +250,7 @@ index 40ddfb04..9c5b1567 100644 extern ServerOptions options; -@@ -699,7 +700,10 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) +@@ -721,7 +722,10 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) sigalg = "rsa-sha2-256"; } @@ -265,10 +263,10 @@ index 40ddfb04..9c5b1567 100644 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 +index 9428df8d1..7843f3e26 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c -@@ -509,7 +509,8 @@ ssh_rsa_verify(const struct sshkey *key, +@@ -533,7 +533,8 @@ ssh_rsa_verify(const struct sshkey *key, ret = SSH_ERR_INVALID_ARGUMENT; goto out; } @@ -279,7 +277,7 @@ index 6c2f771a..8dd4ab01 100644 goto out; } diff --git a/sshconnect2.c b/sshconnect2.c -index ad3f560f..3941e089 100644 +index f43c81ad9..2d98fc3da 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1434,6 +1434,14 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp, @@ -298,10 +296,10 @@ index ad3f560f..3941e089 100644 } diff --git a/sshd-session.c b/sshd-session.c -index a808ac9a..c3349a8a 100644 +index e49e4fb51..a558bbc33 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1316,6 +1316,27 @@ main(int ac, char **av) +@@ -1288,6 +1288,27 @@ main(int ac, char **av) check_ip_options(ssh); @@ -330,5 +328,5 @@ index a808ac9a..c3349a8a 100644 channel_init_channels(ssh); channel_set_af(ssh, options.address_family); -- -2.49.0 +2.52.0 diff --git a/0048-openssh-9.9p1-separate-keysign.patch b/0043-openssh-9.9p1-separate-keysign.patch similarity index 76% rename from 0048-openssh-9.9p1-separate-keysign.patch rename to 0043-openssh-9.9p1-separate-keysign.patch index 8d0f691..60a6d4f 100644 --- a/0048-openssh-9.9p1-separate-keysign.patch +++ b/0043-openssh-9.9p1-separate-keysign.patch @@ -1,14 +1,14 @@ -From b97b1040bc0918fe9be89cdb482d046270e92d9c Mon Sep 17 00:00:00 2001 +From 1799ea7ad21a579b864a536709d732f4a8e533dc 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 +Subject: [PATCH 43/53] 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 +index 8ac5e1633..a06fbfa11 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -797,7 +797,7 @@ or @@ -21,5 +21,5 @@ index a43b2a27..9d5da2a6 100644 Sets the escape character (default: .Ql ~ ) . -- -2.49.0 +2.52.0 diff --git a/0049-openssh-9.9p1-openssl-mlkem.patch b/0044-openssh-9.9p1-openssl-mlkem.patch similarity index 91% rename from 0049-openssh-9.9p1-openssl-mlkem.patch rename to 0044-openssh-9.9p1-openssl-mlkem.patch index e04d194..3e72647 100644 --- a/0049-openssh-9.9p1-openssl-mlkem.patch +++ b/0044-openssh-9.9p1-openssl-mlkem.patch @@ -1,19 +1,19 @@ -From 0a621a2ccb8444e4c6da906b0e112e0522658122 Mon Sep 17 00:00:00 2001 +From 21202362f4ddaeb630d873fb426039004ac82338 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 +Subject: [PATCH 44/53] openssh-9.9p1-openssl-mlkem --- - kex-names.c | 20 +++ + kex-names.c | 23 +++- kexmlkem768x25519.c | 291 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 311 insertions(+) + 2 files changed, 313 insertions(+), 1 deletion(-) diff --git a/kex-names.c b/kex-names.c -index cd3902ad..36a953ab 100644 +index 1360a4095..9c96e5cb0 100644 --- a/kex-names.c +++ b/kex-names.c -@@ -108,6 +108,19 @@ static const struct kexalg gss_kexalgs[] = { - { NULL, 0, -1, -1}, +@@ -109,6 +109,19 @@ static const struct kexalg gss_kexalgs[] = { + { NULL, 0, -1, -1, 0}, }; +static int is_mlkem768_available() @@ -32,17 +32,21 @@ index cd3902ad..36a953ab 100644 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) +@@ -116,8 +129,12 @@ kex_alg_list_internal(char sep, const struct kexalg *algs) const struct kexalg *k; + char sep_str[2] = {sep, '\0'}; - for (k = algs; k->name != NULL; k++) { +- for (k = kexalgs; k->name != NULL; k++) ++ for (k = kexalgs; 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) + xextendf(&ret, sep_str, "%s", k->name); ++ } + + return ret; + } +@@ -139,6 +156,10 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -54,10 +58,10 @@ index cd3902ad..36a953ab 100644 if (strcmp(k->name, name) == 0) return k; diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c -index 2b5d3960..670049dc 100644 +index 2585d1db3..ab6167221 100644 --- a/kexmlkem768x25519.c +++ b/kexmlkem768x25519.c -@@ -48,10 +48,127 @@ +@@ -44,10 +44,127 @@ #ifdef USE_MLKEM768X25519 #include "libcrux_mlkem768_sha3.h" @@ -185,7 +189,7 @@ index 2b5d3960..670049dc 100644 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) +@@ -82,6 +199,36 @@ kex_kem_mlkem768x25519_keypair(struct kex *kex) explicit_bzero(rnd, sizeof(rnd)); sshbuf_free(buf); return r; @@ -222,7 +226,7 @@ index 2b5d3960..670049dc 100644 } int -@@ -93,6 +240,7 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, +@@ -89,6 +236,7 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, const struct sshbuf *client_blob, struct sshbuf **server_blobp, struct sshbuf **shared_secretp) { @@ -230,7 +234,7 @@ index 2b5d3960..670049dc 100644 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, +@@ -181,12 +329,97 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, sshbuf_free(server_blob); sshbuf_free(buf); return r; @@ -328,7 +332,7 @@ index 2b5d3960..670049dc 100644 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, +@@ -254,6 +487,64 @@ kex_kem_mlkem768x25519_dec(struct kex *kex, explicit_bzero(mlkem_key, sizeof(mlkem_key)); sshbuf_free(buf); return r; @@ -394,5 +398,5 @@ index 2b5d3960..670049dc 100644 #else /* USE_MLKEM768X25519 */ int -- -2.49.0 +2.52.0 diff --git a/0050-openssh-9.9p2-error_processing.patch b/0045-openssh-9.9p2-error_processing.patch similarity index 68% rename from 0050-openssh-9.9p2-error_processing.patch rename to 0045-openssh-9.9p2-error_processing.patch index aed1c30..48aa76a 100644 --- a/0050-openssh-9.9p2-error_processing.patch +++ b/0045-openssh-9.9p2-error_processing.patch @@ -1,17 +1,17 @@ -From fd32e753ae7f3b314712e6aa8b2bed3c1fca1ef5 Mon Sep 17 00:00:00 2001 +From edbbdc306c1710dae777ef315a0d2c5f43134d33 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 +Subject: [PATCH 45/53] 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 +index df241379c..dc246066d 100644 --- a/ssh-agent.c +++ b/ssh-agent.c -@@ -1377,6 +1377,8 @@ process_add_identity(SocketEntry *e) +@@ -1346,6 +1346,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) { @@ -21,5 +21,5 @@ index 798bf9b6..dfb6ac72 100644 goto out; } -- -2.49.0 +2.52.0 diff --git a/0051-Provide-better-error-for-non-supported-private-keys.patch b/0046-Provide-better-error-for-non-supported-private-keys.patch similarity index 67% rename from 0051-Provide-better-error-for-non-supported-private-keys.patch rename to 0046-Provide-better-error-for-non-supported-private-keys.patch index 9c1aa4d..dd30967 100644 --- a/0051-Provide-better-error-for-non-supported-private-keys.patch +++ b/0046-Provide-better-error-for-non-supported-private-keys.patch @@ -1,7 +1,7 @@ -From 4965cdbc1ee1e6a0c665797bb8b944d96d3d411f Mon Sep 17 00:00:00 2001 +From 0772377e00b13f5afaa1b146ce32d0218e9f0d24 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 +Subject: [PATCH 46/53] Provide better error for non-supported private keys Signed-off-by: Zoltan Fridrich --- @@ -9,10 +9,10 @@ Signed-off-by: Zoltan Fridrich 1 file changed, 3 insertions(+) diff --git a/sshkey.c b/sshkey.c -index ca1cdb642..aada474e0 100644 +index 394d9b105..eba55ef92 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -3582,6 +3582,9 @@ translate_libcrypto_error(unsigned long pem_err) +@@ -3539,6 +3539,9 @@ translate_libcrypto_error(unsigned long pem_err) return SSH_ERR_LIBCRYPTO_ERROR; } case ERR_LIB_ASN1: @@ -23,5 +23,5 @@ index ca1cdb642..aada474e0 100644 } return SSH_ERR_LIBCRYPTO_ERROR; -- -2.49.0 +2.52.0 diff --git a/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch b/0047-Ignore-bad-hostkeys-in-known_hosts-file.patch similarity index 88% rename from 0052-Ignore-bad-hostkeys-in-known_hosts-file.patch rename to 0047-Ignore-bad-hostkeys-in-known_hosts-file.patch index f071225..3bfab92 100644 --- a/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch +++ b/0047-Ignore-bad-hostkeys-in-known_hosts-file.patch @@ -1,7 +1,7 @@ -From 9ed09ef158a113e21be7b3fefa7c5f932632749b Mon Sep 17 00:00:00 2001 +From d458a65ccac2283563c0fc0962519bb5a9bbd315 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 +Subject: [PATCH 47/53] Ignore bad hostkeys in known_hosts file Signed-off-by: Zoltan Fridrich --- @@ -11,7 +11,7 @@ Signed-off-by: Zoltan Fridrich 3 files changed, 18 insertions(+) diff --git a/hostfile.c b/hostfile.c -index c5669c703..5c402f501 100644 +index 4cec57da5..652d15762 100644 --- a/hostfile.c +++ b/hostfile.c @@ -63,6 +63,14 @@ @@ -62,10 +62,10 @@ index a24a4e329..0e9b1a19a 100644 #endif diff --git a/ssh.c b/ssh.c -index abc8b8439..33787a8d4 100644 +index 7d6ba516e..320ac6834 100644 --- a/ssh.c +++ b/ssh.c -@@ -110,6 +110,7 @@ +@@ -106,6 +106,7 @@ #include "ssherr.h" #include "myproposal.h" #include "utf8.h" @@ -73,7 +73,7 @@ index abc8b8439..33787a8d4 100644 #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" -@@ -1397,6 +1398,7 @@ main(int ac, char **av) +@@ -1409,6 +1410,7 @@ main(int ac, char **av) options.update_hostkeys = 0; } } @@ -82,5 +82,5 @@ index abc8b8439..33787a8d4 100644 fatal("Invalid number of ConnectionAttempts"); -- -2.49.0 +2.52.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/0053-support-authentication-indicators-in-GSSAPI.patch b/0048-support-authentication-indicators-in-GSSAPI.patch similarity index 94% rename from 0053-support-authentication-indicators-in-GSSAPI.patch rename to 0048-support-authentication-indicators-in-GSSAPI.patch index 237e45d..664a006 100644 --- a/0053-support-authentication-indicators-in-GSSAPI.patch +++ b/0048-support-authentication-indicators-in-GSSAPI.patch @@ -1,7 +1,7 @@ -From 5d5a66e96ad03132f65371070f4fa475f10207d9 Mon Sep 17 00:00:00 2001 +From 1cf5e40e14d707de2318747758b012fc7245cb7b 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 +Subject: [PATCH 48/53] 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 @@ -29,10 +29,10 @@ Signed-off-by: Alexander Bokovoy 7 files changed, 228 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac -index d92a85809..2cbe20bf3 100644 +index 805be4b5e..9d3b19925 100644 --- a/configure.ac +++ b/configure.ac -@@ -5004,6 +5004,7 @@ AC_ARG_WITH([kerberos5], +@@ -5050,6 +5050,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]) @@ -143,7 +143,7 @@ index 03188d9b3..2c786ef14 100644 return retval; } diff --git a/gss-serv.c b/gss-serv.c -index 9d5435eda..5c0491cf1 100644 +index d2bc03486..be80e17ca 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -54,7 +54,7 @@ extern ServerOptions options; @@ -285,10 +285,10 @@ index 9d5435eda..5c0491cf1 100644 sizeof(ssh_gssapi_client)); return 0; diff --git a/servconf.c b/servconf.c -index e7e4ad046..aab653244 100644 +index f78615c28..e53e8ea30 100644 --- a/servconf.c +++ b/servconf.c -@@ -147,6 +147,7 @@ initialize_server_options(ServerOptions *options) +@@ -146,6 +146,7 @@ initialize_server_options(ServerOptions *options) options->gss_strict_acceptor = -1; options->gss_store_rekey = -1; options->gss_kex_algorithms = NULL; @@ -296,7 +296,7 @@ index e7e4ad046..aab653244 100644 options->use_kuserok = -1; options->enable_k5users = -1; options->password_authentication = -1; -@@ -598,7 +599,7 @@ typedef enum { +@@ -591,7 +592,7 @@ typedef enum { sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, @@ -305,7 +305,7 @@ index e7e4ad046..aab653244 100644 sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -694,6 +695,7 @@ static struct { +@@ -687,6 +688,7 @@ static struct { { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, @@ -313,7 +313,7 @@ index e7e4ad046..aab653244 100644 #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -703,6 +705,7 @@ static struct { +@@ -696,6 +698,7 @@ static struct { { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, { "gssapienablek5users", sUnsupported, SSHCFG_ALL }, @@ -321,7 +321,7 @@ index e7e4ad046..aab653244 100644 #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1730,6 +1733,15 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1722,6 +1725,15 @@ process_server_config_line_depth(ServerOptions *options, char *line, options->gss_kex_algorithms = xstrdup(arg); break; @@ -337,7 +337,7 @@ index e7e4ad046..aab653244 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3351,6 +3363,7 @@ dump_config(ServerOptions *o) +@@ -3344,6 +3356,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); @@ -346,10 +346,10 @@ index e7e4ad046..aab653244 100644 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --git a/servconf.h b/servconf.h -index 7c7e5d434..7c41df417 100644 +index c08cf6a7a..c7cec5ece 100644 --- a/servconf.h +++ b/servconf.h -@@ -181,6 +181,7 @@ typedef struct { +@@ -179,6 +179,7 @@ typedef struct { char **allow_groups; u_int num_deny_groups; char **deny_groups; @@ -357,7 +357,7 @@ index 7c7e5d434..7c41df417 100644 u_int num_subsystems; char **subsystem_name; -@@ -310,6 +311,7 @@ TAILQ_HEAD(include_list, include_item); +@@ -308,6 +309,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); \ @@ -366,7 +366,7 @@ index 7c7e5d434..7c41df417 100644 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 +index 329dc9da0..1506719a9 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -34,6 +34,12 @@ @@ -382,7 +382,7 @@ index a894e23c9..59cf46d47 100644 #ifdef KRB5 # ifndef HEIMDAL # ifdef HAVE_GSSAPI_GENERIC_H -@@ -107,6 +113,7 @@ typedef struct { +@@ -112,6 +118,7 @@ typedef struct { ssh_gssapi_ccache store; int used; int updated; @@ -391,7 +391,7 @@ index a894e23c9..59cf46d47 100644 typedef struct ssh_gssapi_mech_struct { diff --git a/sshd_config.5 b/sshd_config.5 -index 583a01cdb..90ab87edd 100644 +index c172d5aab..676d6d4d2 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -785,6 +785,50 @@ gss-nistp256-sha256- @@ -446,5 +446,5 @@ index 583a01cdb..90ab87edd 100644 The default is handled system-wide by .Xr crypto-policies 7 . -- -2.49.0 +2.52.0 diff --git a/0049-NIST-curves-hybrid-KEX-implementation.patch b/0049-NIST-curves-hybrid-KEX-implementation.patch new file mode 100644 index 0000000..9ce23be --- /dev/null +++ b/0049-NIST-curves-hybrid-KEX-implementation.patch @@ -0,0 +1,1216 @@ +From 3642efdf9be4d377cfd802d6a33cb083f0d846b8 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Mon, 20 Oct 2025 16:07:31 +0200 +Subject: [PATCH 49/53] NIST curves hybrid KEX implementation + +--- + crypto_api.h | 4 + + kex-names.c | 78 +++- + kex.c | 1 + + kex.h | 19 + + kexgen.c | 56 ++- + kexmlkem768x25519.c | 678 +++++++++++++++++++++++++++++-- + monitor.c | 2 + + myproposal.h | 4 + + regress/unittests/kex/test_kex.c | 4 + + ssh-keyscan.c | 2 + + ssh_api.c | 4 + + sshconnect2.c | 2 + + sshd-auth.c | 2 + + 13 files changed, 819 insertions(+), 37 deletions(-) + +diff --git a/crypto_api.h b/crypto_api.h +index 693b67bbc..ec3d2f277 100644 +--- a/crypto_api.h ++++ b/crypto_api.h +@@ -56,4 +56,8 @@ int crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk); + #define crypto_kem_mlkem768_CIPHERTEXTBYTES 1088 + #define crypto_kem_mlkem768_BYTES 32 + ++#define crypto_kem_mlkem1024_PUBLICKEYBYTES 1568 ++#define crypto_kem_mlkem1024_SECRETKEYBYTES 3168 ++#define crypto_kem_mlkem1024_CIPHERTEXTBYTES 1568 ++ + #endif /* crypto_api_h */ +diff --git a/kex-names.c b/kex-names.c +index 9c96e5cb0..ceecd9312 100644 +--- a/kex-names.c ++++ b/kex-names.c +@@ -91,6 +91,10 @@ static const struct kexalg kexalgs[] = { + #ifdef USE_MLKEM768X25519 + { KEX_MLKEM768X25519_SHA256, KEX_KEM_MLKEM768X25519_SHA256, 0, + SSH_DIGEST_SHA256, KEX_IS_PQ }, ++ { KEX_MLKEM768NISTP256_SHA256, KEX_KEM_MLKEM768NISTP256_SHA256, 0, ++ SSH_DIGEST_SHA256, KEX_IS_PQ }, ++ { KEX_MLKEM1024NISTP384_SHA384, KEX_KEM_MLKEM1024NISTP384_SHA384, 0, ++ SSH_DIGEST_SHA384, KEX_IS_PQ }, + #endif + #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ + { NULL, 0, -1, -1, 0 }, +@@ -109,13 +113,30 @@ static const struct kexalg gss_kexalgs[] = { + { NULL, 0, -1, -1, 0}, + }; + ++/* ++ * 0 - unavailable ++ * 1 - available in non-FIPS mode ++ * 2 - available in FIPS mode ++ */ + 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 *mlkem768 = NULL; ++ ++ if (FIPS_mode() == 1) { ++ mlkem768 = EVP_KEM_fetch(NULL, "mlkem768", NULL); ++ is_fetched = mlkem768 != NULL ? 2 : 0; ++ ++ if (is_fetched == 0) { ++ mlkem768 = EVP_KEM_fetch(NULL, "mlkem768", "provider=default,-fips"); ++ is_fetched = mlkem768 != NULL ? 1 : 0; ++ } ++ } else { ++ mlkem768 = EVP_KEM_fetch(NULL, "mlkem768", NULL); ++ is_fetched = mlkem768 != NULL ? 1 : 0; ++ } + EVP_KEM_free(mlkem768); + } + +@@ -128,11 +149,32 @@ kex_alg_list_internal(char sep, const struct kexalg *algs) + char *ret = NULL; + const struct kexalg *k; + char sep_str[2] = {sep, '\0'}; ++ int x25519mlkem_available = 0, nistmlkem_available = 0; + +- for (k = kexalgs; k->name != NULL; k++) { +- if (strcmp(k->name, KEX_MLKEM768X25519_SHA256) == 0 +- && !is_mlkem768_available()) ++ /* ++ * FIPS provider can provide ML-KEMs and then all hybrids are available ++ * Otherwise only NIST hybrids are available ++ * */ ++ if (FIPS_mode()) { ++ if (is_mlkem768_available() == 2) { ++ x25519mlkem_available = 1; ++ nistmlkem_available = 1; ++ } else if (is_mlkem768_available() == 1) { ++ nistmlkem_available = 1; ++ } ++ } else { ++ if (is_mlkem768_available() > 0) { ++ x25519mlkem_available = 1; ++ nistmlkem_available = 1; ++ } ++ } ++ ++ for (k = algs; k->name != NULL; k++) { ++ if ( (strcmp(k->name, KEX_MLKEM768X25519_SHA256) == 0 && x25519mlkem_available == 0) ++ || (strcmp(k->name, KEX_MLKEM768NISTP256_SHA256) == 0 && nistmlkem_available == 0) ++ || (strcmp(k->name, KEX_MLKEM1024NISTP384_SHA384) == 0 && nistmlkem_available == 0)) + continue; ++ + xextendf(&ret, sep_str, "%s", k->name); + } + +@@ -155,10 +197,30 @@ static const struct kexalg * + kex_alg_by_name(const char *name) + { + const struct kexalg *k; ++ int x25519mlkem_available = 0, nistmlkem_available = 0; + +- if (strcmp(name, KEX_MLKEM768X25519_SHA256) == 0 +- && !is_mlkem768_available()) +- return NULL; ++ /* ++ * FIPS provider can provide ML-KEMs and then all hybrids are available ++ * Otherwise only NIST hybrids are available ++ * */ ++ if (FIPS_mode()) { ++ if (is_mlkem768_available() == 2) { ++ x25519mlkem_available = 1; ++ nistmlkem_available = 1; ++ } else if (is_mlkem768_available() == 1) { ++ nistmlkem_available = 1; ++ } ++ } else { ++ if (is_mlkem768_available() > 0) { ++ x25519mlkem_available = 1; ++ nistmlkem_available = 1; ++ } ++ } ++ ++ if ( (strcmp(name, KEX_MLKEM768X25519_SHA256) == 0 && x25519mlkem_available == 0) ++ || (strcmp(name, KEX_MLKEM768NISTP256_SHA256) == 0 && nistmlkem_available == 0) ++ || (strcmp(name, KEX_MLKEM1024NISTP384_SHA384) == 0 && nistmlkem_available == 0)) ++ return NULL; + + for (k = kexalgs; k->name != NULL; k++) { + if (strcmp(k->name, name) == 0) +diff --git a/kex.c b/kex.c +index 56c80395c..7dd16ba2b 100644 +--- a/kex.c ++++ b/kex.c +@@ -751,6 +751,7 @@ kex_free(struct kex *kex) + #ifdef OPENSSL_HAS_ECC + EC_KEY_free(kex->ec_client_key); + #endif /* OPENSSL_HAS_ECC */ ++ EVP_PKEY_free(kex->ec_hybrid_client_key); + #endif /* WITH_OPENSSL */ + for (mode = 0; mode < MODE_MAX; mode++) { + kex_free_newkeys(kex->newkeys[mode]); +diff --git a/kex.h b/kex.h +index 6daafb159..354f312e8 100644 +--- a/kex.h ++++ b/kex.h +@@ -72,6 +72,8 @@ + #define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512" + #define KEX_SNTRUP761X25519_SHA512_OLD "sntrup761x25519-sha512@openssh.com" + #define KEX_MLKEM768X25519_SHA256 "mlkem768x25519-sha256" ++#define KEX_MLKEM768NISTP256_SHA256 "mlkem768nistp256-sha256" ++#define KEX_MLKEM1024NISTP384_SHA384 "mlkem1024nistp384-sha384" + + #define COMP_NONE 0 + #define COMP_DELAYED 2 +@@ -110,6 +112,8 @@ enum kex_exchange { + KEX_C25519_SHA256, + KEX_KEM_SNTRUP761X25519_SHA512, + KEX_KEM_MLKEM768X25519_SHA256, ++ KEX_KEM_MLKEM768NISTP256_SHA256, ++ KEX_KEM_MLKEM1024NISTP384_SHA384, + #ifdef GSSAPI + KEX_GSS_GRP1_SHA1, + KEX_GSS_GRP14_SHA1, +@@ -210,6 +214,9 @@ struct kex { + u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */ + u_char mlkem768_client_key[crypto_kem_mlkem768_SECRETKEYBYTES]; /* KEM */ + struct sshbuf *client_pub; ++ /* FIXME */ ++ EVP_PKEY *ec_hybrid_client_key; /* NIST hybrids */ ++ u_char mlkem1024_client_key[crypto_kem_mlkem1024_SECRETKEYBYTES]; /* ML-KEM 1024 + NIST */ + }; + + int kex_name_valid(const char *); +@@ -292,6 +299,18 @@ int kex_kem_mlkem768x25519_enc(struct kex *, const struct sshbuf *, + int kex_kem_mlkem768x25519_dec(struct kex *, const struct sshbuf *, + struct sshbuf **); + ++int kex_kem_mlkem768nistp256_keypair(struct kex *); ++int kex_kem_mlkem768nistp256_enc(struct kex *, const struct sshbuf *, ++ struct sshbuf **, struct sshbuf **); ++int kex_kem_mlkem768nistp256_dec(struct kex *, const struct sshbuf *, ++ struct sshbuf **); ++ ++int kex_kem_mlkem1024nistp384_keypair(struct kex *); ++int kex_kem_mlkem1024nistp384_enc(struct kex *, const struct sshbuf *, ++ struct sshbuf **, struct sshbuf **); ++int kex_kem_mlkem1024nistp384_dec(struct kex *, const struct sshbuf *, ++ struct sshbuf **); ++ + int kex_dh_keygen(struct kex *); + int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); + +diff --git a/kexgen.c b/kexgen.c +index 9a970adf1..79faa0b3e 100644 +--- a/kexgen.c ++++ b/kexgen.c +@@ -133,12 +133,24 @@ kex_gen_client(struct ssh *ssh) + break; + case KEX_KEM_MLKEM768X25519_SHA256: + if (FIPS_mode()) { +- logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode"); +- r = SSH_ERR_INVALID_ARGUMENT; ++ EVP_KEM *mlkem = EVP_KEM_fetch(NULL, "mlkem768", NULL); ++ if (mlkem == NULL) { ++ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ EVP_KEM_free(mlkem); ++ r = kex_kem_mlkem768x25519_keypair(kex); ++ } + } else { + r = kex_kem_mlkem768x25519_keypair(kex); + } + break; ++ case KEX_KEM_MLKEM768NISTP256_SHA256: ++ r = kex_kem_mlkem768nistp256_keypair(kex); ++ break; ++ case KEX_KEM_MLKEM1024NISTP384_SHA384: ++ r = kex_kem_mlkem1024nistp384_keypair(kex); ++ break; + default: + r = SSH_ERR_INVALID_ARGUMENT; + break; +@@ -223,13 +235,28 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) + break; + case KEX_KEM_MLKEM768X25519_SHA256: + if (FIPS_mode()) { +- logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode"); +- r = SSH_ERR_INVALID_ARGUMENT; ++ EVP_KEM *mlkem = EVP_KEM_fetch(NULL, "mlkem768", NULL); ++ if (mlkem == NULL) { ++ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ EVP_KEM_free(mlkem); ++ r = kex_kem_mlkem768x25519_dec(kex, server_blob, ++ &shared_secret); ++ } + } else { + r = kex_kem_mlkem768x25519_dec(kex, server_blob, + &shared_secret); + } + break; ++ case KEX_KEM_MLKEM768NISTP256_SHA256: ++ r = kex_kem_mlkem768nistp256_dec(kex, server_blob, ++ &shared_secret); ++ break; ++ case KEX_KEM_MLKEM1024NISTP384_SHA384: ++ r = kex_kem_mlkem1024nistp384_dec(kex, server_blob, ++ &shared_secret); ++ break; + default: + r = SSH_ERR_INVALID_ARGUMENT; + break; +@@ -283,6 +310,8 @@ out: + sizeof(kex->sntrup761_client_key)); + explicit_bzero(kex->mlkem768_client_key, + sizeof(kex->mlkem768_client_key)); ++ explicit_bzero(kex->mlkem1024_client_key, ++ sizeof(kex->mlkem1024_client_key)); + sshbuf_free(server_host_key_blob); + free(signature); + sshbuf_free(tmp); +@@ -362,13 +391,28 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) + break; + case KEX_KEM_MLKEM768X25519_SHA256: + if (FIPS_mode()) { +- logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode"); +- r = SSH_ERR_INVALID_ARGUMENT; ++ EVP_KEM *mlkem = EVP_KEM_fetch(NULL, "mlkem768", NULL); ++ if (mlkem == NULL) { ++ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode"); ++ r = SSH_ERR_INVALID_ARGUMENT; ++ } else { ++ EVP_KEM_free(mlkem); ++ r = kex_kem_mlkem768x25519_enc(kex, client_pubkey, ++ &server_pubkey, &shared_secret); ++ } + } else { + r = kex_kem_mlkem768x25519_enc(kex, client_pubkey, + &server_pubkey, &shared_secret); + } + break; ++ case KEX_KEM_MLKEM768NISTP256_SHA256: ++ r = kex_kem_mlkem768nistp256_enc(kex, client_pubkey, ++ &server_pubkey, &shared_secret); ++ break; ++ case KEX_KEM_MLKEM1024NISTP384_SHA384: ++ r = kex_kem_mlkem1024nistp384_enc(kex, client_pubkey, ++ &server_pubkey, &shared_secret); ++ break; + default: + r = SSH_ERR_INVALID_ARGUMENT; + break; +diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c +index ab6167221..c56d67ff4 100644 +--- a/kexmlkem768x25519.c ++++ b/kexmlkem768x25519.c +@@ -44,19 +44,33 @@ + #ifdef USE_MLKEM768X25519 + + #include "libcrux_mlkem768_sha3.h" ++#include ++#include + #include + #include ++#include + #include + ++#define FIPS_FALLBACK_PROPQ "provider=default,-fips" ++ + static int +-mlkem768_keypair_gen(unsigned char *pubkeybuf, unsigned char *privkeybuf) ++mlkem_keypair_gen(const char *algname, unsigned char *pubkeybuf, size_t pubkey_size, ++ unsigned char *privkeybuf, size_t privkey_size) + { + 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; ++ size_t got_pub_size = pubkey_size, got_priv_size = privkey_size; ++ ++ ctx = EVP_PKEY_CTX_new_from_name(NULL, algname, NULL); ++ ++ if (ctx == NULL && FIPS_mode()) { ++ /* We have filtered x25519 + ML-KEM in FIPS mode earlier ++ * so if we are in FIPS mode and ML-KEM is not available with default propq, ++ * we can fetch it from the default provider */ ++ ctx = EVP_PKEY_CTX_new_from_name(NULL, algname, FIPS_FALLBACK_PROPQ); ++ } + +- ctx = EVP_PKEY_CTX_new_from_name(NULL, "mlkem768", NULL); + if (ctx == NULL) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto err; +@@ -68,17 +82,23 @@ mlkem768_keypair_gen(unsigned char *pubkeybuf, unsigned char *privkeybuf) + 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) { ++ if (EVP_PKEY_get_raw_public_key(pkey, NULL, &got_pub_size) <= 0 ++ || EVP_PKEY_get_raw_private_key(pkey, NULL, &got_priv_size) <= 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto err; + } + +- if (privkey_size != crypto_kem_mlkem768_SECRETKEYBYTES +- || pubkey_size != crypto_kem_mlkem768_PUBLICKEYBYTES) { ++ if (privkey_size != got_priv_size || pubkey_size != got_pub_size) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto err; + } ++ ++ if (EVP_PKEY_get_raw_public_key(pkey, pubkeybuf, &got_pub_size) <= 0 ++ || EVP_PKEY_get_raw_private_key(pkey, privkeybuf, &got_priv_size) <= 0) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto err; ++ } ++ + ret = 0; + + err: +@@ -90,27 +110,57 @@ mlkem768_keypair_gen(unsigned char *pubkeybuf, unsigned char *privkeybuf) + } + + static int +-mlkem768_encap_secret(const u_char *pubkeybuf, u_char *secret, u_char *out) ++mlkem768_keypair_gen(unsigned char *pubkeybuf, unsigned char *privkeybuf) ++{ ++ return mlkem_keypair_gen("mlkem768", pubkeybuf, crypto_kem_mlkem768_PUBLICKEYBYTES, ++ privkeybuf, crypto_kem_mlkem768_SECRETKEYBYTES); ++} ++ ++static int ++mlkem1024_keypair_gen(unsigned char *pubkeybuf, unsigned char *privkeybuf) ++{ ++ return mlkem_keypair_gen("mlkem1024", pubkeybuf, crypto_kem_mlkem1024_PUBLICKEYBYTES, ++ privkeybuf, crypto_kem_mlkem1024_SECRETKEYBYTES); ++} ++ ++static int ++mlkem_encap_secret(const char *mlkem_alg, 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; ++ size_t outlen, expected_outlen, publen, secretlen = crypto_kem_mlkem768_BYTES; ++ int fips_fallback = 0; ++ ++ if (strcmp(mlkem_alg, "mlkem768") == 0) { ++ outlen = crypto_kem_mlkem768_CIPHERTEXTBYTES; ++ publen = crypto_kem_mlkem768_PUBLICKEYBYTES; ++ } else if (strcmp(mlkem_alg, "mlkem1024") == 0) { ++ outlen = crypto_kem_mlkem1024_CIPHERTEXTBYTES; ++ publen = crypto_kem_mlkem1024_PUBLICKEYBYTES; ++ } else ++ return r; + +- pkey = EVP_PKEY_new_raw_public_key_ex(NULL, "mlkem768", NULL, +- pubkeybuf, crypto_kem_mlkem768_PUBLICKEYBYTES); ++ expected_outlen = outlen; ++ ++ pkey = EVP_PKEY_new_raw_public_key_ex(NULL, mlkem_alg, NULL, ++ pubkeybuf, publen); ++ if (pkey == NULL && FIPS_mode()) { ++ pkey = EVP_PKEY_new_raw_public_key_ex(NULL, mlkem_alg, FIPS_FALLBACK_PROPQ, ++ pubkeybuf, publen); ++ fips_fallback = 1; ++ } + if (pkey == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto err; + } + +- ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); ++ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, fips_fallback ? FIPS_FALLBACK_PROPQ : NULL); + if (ctx == NULL + || EVP_PKEY_encapsulate_init(ctx, NULL) <= 0 +- || EVP_PKEY_encapsulate(ctx, out, &outlen, secret, &secretlen) <= 0 ++ || EVP_PKEY_encapsulate(ctx, out, &expected_outlen, secret, &secretlen) <= 0 + || secretlen != crypto_kem_mlkem768_BYTES +- || outlen != crypto_kem_mlkem768_CIPHERTEXTBYTES) { ++ || outlen != expected_outlen) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto err; + } +@@ -126,25 +176,45 @@ mlkem768_encap_secret(const u_char *pubkeybuf, u_char *secret, u_char *out) + } + + static int +-mlkem768_decap_secret(const u_char *privkeybuf, const u_char *wrapped, u_char *secret) ++mlkem768_encap_secret(const u_char *pubkeybuf, u_char *secret, u_char *out) ++{ ++ return mlkem_encap_secret("mlkem768", pubkeybuf, secret, out); ++} ++ ++static int ++mlkem1024_encap_secret(const u_char *pubkeybuf, u_char *secret, u_char *out) ++{ ++ return mlkem_encap_secret("mlkem1024", pubkeybuf, secret, out); ++} ++ ++static int ++mlkem_decap_secret(const char *algname, ++ const u_char *privkeybuf, size_t privkey_len, ++ const u_char *wrapped, size_t wrapped_len, ++ 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; ++ size_t secretlen = crypto_kem_mlkem768_BYTES; ++ int fips_fallback = 0; + +- pkey = EVP_PKEY_new_raw_private_key_ex(NULL, "mlkem768", NULL, +- privkeybuf, crypto_kem_mlkem768_SECRETKEYBYTES); ++ pkey = EVP_PKEY_new_raw_private_key_ex(NULL, algname, ++ NULL, privkeybuf, privkey_len); ++ if (pkey == NULL && FIPS_mode()) { ++ pkey = EVP_PKEY_new_raw_private_key_ex(NULL, algname, ++ FIPS_FALLBACK_PROPQ, privkeybuf, privkey_len); ++ fips_fallback = 1; ++ } + if (pkey == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto err; + } + +- ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); ++ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, fips_fallback ? FIPS_FALLBACK_PROPQ : NULL); + if (ctx == NULL + || EVP_PKEY_decapsulate_init(ctx, NULL) <= 0 +- || EVP_PKEY_decapsulate(ctx, secret, &secretlen, wrapped, wrappedlen) <= 0 ++ || EVP_PKEY_decapsulate(ctx, secret, &secretlen, wrapped, wrapped_len) <= 0 + || secretlen != crypto_kem_mlkem768_BYTES) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto err; +@@ -161,6 +231,20 @@ mlkem768_decap_secret(const u_char *privkeybuf, const u_char *wrapped, u_char *s + return r; + } + ++static int ++mlkem768_decap_secret(const u_char *privkeybuf, const u_char *wrapped, u_char *secret) ++{ ++ return mlkem_decap_secret("mlkem768", privkeybuf, crypto_kem_mlkem768_SECRETKEYBYTES, ++ wrapped, crypto_kem_mlkem768_CIPHERTEXTBYTES, secret); ++} ++ ++static int ++mlkem1024_decap_secret(const u_char *privkeybuf, const u_char *wrapped, u_char *secret) ++{ ++ return mlkem_decap_secret("mlkem1024", privkeybuf, crypto_kem_mlkem1024_SECRETKEYBYTES, ++ wrapped, crypto_kem_mlkem1024_CIPHERTEXTBYTES, secret); ++} ++ + int + kex_kem_mlkem768x25519_keypair(struct kex *kex) + { +@@ -337,7 +421,7 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t need; + int r = SSH_ERR_INTERNAL_ERROR; +- struct libcrux_mlkem768_enc_result enc; /* FIXME */ ++ struct libcrux_mlkem768_enc_result enc; + + *server_blobp = NULL; + *shared_secretp = NULL; +@@ -546,6 +630,519 @@ kex_kem_mlkem768x25519_dec(struct kex *kex, + return r; + #endif + } ++ ++#define NIST_P256_COMPRESSED_LEN 33 ++#define NIST_P256_UNCOMPRESSED_LEN 65 ++#define NIST_P384_COMPRESSED_LEN 49 ++#define NIST_P384_UNCOMPRESSED_LEN 97 ++#define NIST_BUF_MAX_SIZE NIST_P384_UNCOMPRESSED_LEN ++ ++static const char ec256[] = "P-256"; ++static const char ec384[] = "P-384"; ++static const char *len2curve_name(size_t len) ++{ ++ switch (len) { ++ case NIST_P256_COMPRESSED_LEN: ++ case NIST_P256_UNCOMPRESSED_LEN: ++ return ec256; ++ break; ++ case NIST_P384_COMPRESSED_LEN: ++ case NIST_P384_UNCOMPRESSED_LEN: ++ return ec384; ++ break; ++ } ++ return NULL; ++} ++ ++static EVP_PKEY * ++buf2nist_key(const unsigned char *pub_key_buf, size_t pub_key_len) ++{ ++ EVP_PKEY *pkey = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ OSSL_PARAM params[3]; ++ const char *curve_name = len2curve_name(pub_key_len); ++ ++ if (curve_name == NULL) ++ return NULL; ++ ++ ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); ++ if (!ctx) ++ goto err; ++ ++ if (EVP_PKEY_fromdata_init(ctx) <= 0) ++ goto err; ++ ++ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, curve_name, 0); ++ params[1] = OSSL_PARAM_construct_octet_string( ++ OSSL_PKEY_PARAM_PUB_KEY, (void *)pub_key_buf, pub_key_len); ++ params[2] = OSSL_PARAM_construct_end(); ++ ++ if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0) ++ goto err; ++ ++ EVP_PKEY_CTX_free(ctx); ++ return pkey; ++ ++err: ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(pkey); ++ return NULL; ++} ++ ++static int ++kex_nist_shared_key_ext(EVP_PKEY *priv_key, ++ const u_char *pub_key_buf, size_t pub_key_len, struct sshbuf *out) ++{ ++ EVP_PKEY_CTX *ctx = NULL; ++ unsigned char *shared_secret = NULL; ++ size_t shared_secret_len = 0; ++ EVP_PKEY *peer_key = buf2nist_key(pub_key_buf, pub_key_len); ++ int r = SSH_ERR_INTERNAL_ERROR; ++ ++ if (peer_key == NULL) ++ return SSH_ERR_KEY_LENGTH; ++ ++ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, priv_key, NULL); ++ if (!ctx) ++ goto end; ++ ++ if ((EVP_PKEY_derive_init(ctx) <= 0) ++ || EVP_PKEY_derive_set_peer(ctx, peer_key) <= 0 ++ || EVP_PKEY_derive(ctx, NULL, &shared_secret_len) <= 0) ++ goto end; ++ ++ shared_secret = OPENSSL_malloc(shared_secret_len); ++ if (shared_secret == NULL) ++ goto end; ++ ++ if (EVP_PKEY_derive(ctx, shared_secret, &shared_secret_len) <= 0) ++ goto end; ++ ++ if ((r = sshbuf_put(out, shared_secret, shared_secret_len)) != 0) ++ goto end; ++ ++ r = 0; ++ ++end: ++ EVP_PKEY_free(peer_key); ++ if (shared_secret) ++ OPENSSL_clear_free(shared_secret, shared_secret_len); ++ EVP_PKEY_CTX_free(ctx); ++ ++ return r; ++} ++ ++static EVP_PKEY * ++nist_pkey_keygen(size_t pub_key_len) ++{ ++ const char *curve_name = len2curve_name(pub_key_len); ++ EVP_PKEY_CTX *pctx = NULL; ++ EVP_PKEY *pkey = NULL; ++ OSSL_PARAM params[2]; ++ ++ if (curve_name == NULL) ++ return NULL; ++ ++ pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); ++ if (!pctx) ++ return NULL; ++ ++ if (EVP_PKEY_keygen_init(pctx) <= 0) { ++ EVP_PKEY_CTX_free(pctx); ++ return NULL; ++ } ++ ++ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, curve_name, 0); ++ params[1] = OSSL_PARAM_construct_end(); ++ ++ if (EVP_PKEY_CTX_set_params(pctx, params) <= 0 ++ || EVP_PKEY_keygen(pctx, &pkey) <= 0) { ++ EVP_PKEY_CTX_free(pctx); ++ return NULL; ++ } ++ ++ EVP_PKEY_CTX_free(pctx); ++ return pkey; ++} ++ ++static size_t decompress_pub_key(void *pub, size_t compressed_len, size_t decompressed_len) ++{ ++ EC_GROUP *group = NULL; ++ EC_POINT *point = NULL; ++ BN_CTX *ctx = NULL; ++ size_t len = 0; ++ int group_nid = NID_undef; ++ ++ switch (compressed_len) { ++ case NIST_P256_COMPRESSED_LEN: ++ group_nid = NID_X9_62_prime256v1; ++ break; ++ case NIST_P384_COMPRESSED_LEN: ++ group_nid = NID_secp384r1; ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ ctx = BN_CTX_new(); ++ group = EC_GROUP_new_by_curve_name(group_nid); ++ if (ctx == NULL || group == NULL) ++ goto err; ++ ++ point = EC_POINT_new(group); ++ if (point == NULL) ++ goto err; ++ ++ if (!EC_POINT_oct2point(group, point, pub, compressed_len, ctx)) ++ goto err; ++ ++ len = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, pub, decompressed_len, ctx); ++ ++err: ++ EC_POINT_free(point); ++ EC_GROUP_free(group); ++ BN_CTX_free(ctx); ++ ++ return len; ++} ++ ++static int ++get_uncompressed_ec_pubkey(EVP_PKEY *pkey, unsigned char *buf, size_t buf_len) ++{ ++ OSSL_PARAM params[2]; ++ size_t required_len = 0, out_len = 0; ++ ++ params[0] = OSSL_PARAM_construct_utf8_string( ++ OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, ++ "uncompressed", 0); ++ params[1] = OSSL_PARAM_construct_end(); ++ ++ if (EVP_PKEY_set_params(pkey, params) <= 0 ++ || EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, ++ buf, buf_len, &required_len) <= 0) { ++ return SSH_ERR_LIBCRYPTO_ERROR; ++ } ++ ++ if (required_len != buf_len) { ++ /* Red Hat certified FIPS provider ignores OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT ++ * We may have to perform the conversion manually */ ++ if (len2curve_name(required_len) == len2curve_name(buf_len)) { ++ out_len = decompress_pub_key(buf, required_len, buf_len); ++ if (out_len != buf_len) { ++ debug_f("Error decompressing the compressed public key"); ++ return SSH_ERR_LIBCRYPTO_ERROR; ++ } else { ++ return 0; ++ } ++ } else { ++ debug_f("Unexpected length of uncompressed public key: expected %d, got %d", buf_len, required_len); ++ return SSH_ERR_LIBCRYPTO_ERROR; ++ } ++ } ++ ++ return 0; ++} ++/* nist_bytes_len should always be uncompressed */ ++static int ++kex_kem_mlkem_nist_keypair(struct kex *kex, size_t mlkem_bytes_len, size_t nist_bytes_len) ++{ ++ struct sshbuf *buf = NULL; ++ u_char *cp = NULL; ++ size_t need; ++ int r = SSH_ERR_INTERNAL_ERROR; ++ u_char *client_key = NULL; ++ ++ if ((buf = sshbuf_new()) == NULL) ++ return SSH_ERR_ALLOC_FAIL; ++ need = mlkem_bytes_len + nist_bytes_len; ++ if ((r = sshbuf_reserve(buf, need, &cp)) != 0) ++ goto out; ++ ++ if (mlkem_bytes_len == crypto_kem_mlkem768_PUBLICKEYBYTES) { ++ client_key = kex->mlkem768_client_key; ++ r = mlkem768_keypair_gen(cp, client_key); ++ } ++ ++ if (mlkem_bytes_len == crypto_kem_mlkem1024_PUBLICKEYBYTES) { ++ client_key = kex->mlkem1024_client_key; ++ r = mlkem1024_keypair_gen(cp, client_key); ++ } ++ ++ if (client_key == NULL) ++ goto out; ++ ++ if (r != 0) ++ goto out; ++#ifdef DEBUG_KEXECDH ++ dump_digest("client public key mlkemXXX:", cp, mlkem_bytes_len); ++#endif ++ cp += mlkem_bytes_len; ++ if ((kex->ec_hybrid_client_key = nist_pkey_keygen(nist_bytes_len)) == NULL) ++ goto out; ++ ++ if ((r = get_uncompressed_ec_pubkey(kex->ec_hybrid_client_key, cp, nist_bytes_len)) != 0) ++ goto out; ++ ++#ifdef DEBUG_KEXECDH ++ dump_digest("client public key NIST:", cp, nist_bytes_len); ++#endif ++ /* success */ ++ r = 0; ++ kex->client_pub = buf; ++ buf = NULL; ++ out: ++ sshbuf_free(buf); ++ if (r == SSH_ERR_LIBCRYPTO_ERROR) ++ ERR_print_errors_fp(stderr); ++ ++ return r; ++} ++ ++static int ++kex_kem_mlkem_nist_enc(struct kex *kex, const char *nist_curve, ++ const struct sshbuf *client_blob, struct sshbuf **server_blobp, ++ struct sshbuf **shared_secretp) ++{ ++ struct sshbuf *server_blob = NULL; ++ struct sshbuf *buf = NULL; ++ const u_char *client_pub; ++ u_char server_pub[NIST_BUF_MAX_SIZE]; ++ u_char enc_out[crypto_kem_mlkem1024_CIPHERTEXTBYTES]; ++ u_char secret[crypto_kem_mlkem768_BYTES]; ++ EVP_PKEY *server_key = NULL; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ size_t client_buf_len, mlkem_buf_len, ecdh_buf_len, server_key_len, enc_out_len; ++ int r = SSH_ERR_INTERNAL_ERROR; ++ ++ *server_blobp = NULL; ++ *shared_secretp = NULL; ++ ++ client_buf_len = sshbuf_len(client_blob); ++ /* client_blob contains both KEM and ECDH client pubkeys */ ++ if (strcmp(nist_curve, "P-256") == 0) { ++ if (crypto_kem_mlkem768_PUBLICKEYBYTES > client_buf_len) ++ return r; ++ ++ ecdh_buf_len = client_buf_len - crypto_kem_mlkem768_PUBLICKEYBYTES; ++ if (ecdh_buf_len != NIST_P256_COMPRESSED_LEN && ++ ecdh_buf_len != NIST_P256_UNCOMPRESSED_LEN) ++ return r; ++ mlkem_buf_len = crypto_kem_mlkem768_PUBLICKEYBYTES; ++ enc_out_len = crypto_kem_mlkem768_CIPHERTEXTBYTES; ++ server_key_len = NIST_P256_UNCOMPRESSED_LEN; ++ } else if (strcmp(nist_curve, "P-384") == 0) { ++ if (crypto_kem_mlkem1024_PUBLICKEYBYTES > client_buf_len) ++ return r; ++ ++ ecdh_buf_len = client_buf_len - crypto_kem_mlkem1024_PUBLICKEYBYTES; ++ if (ecdh_buf_len != NIST_P384_COMPRESSED_LEN && ++ ecdh_buf_len != NIST_P384_UNCOMPRESSED_LEN) ++ return r; ++ mlkem_buf_len = crypto_kem_mlkem1024_PUBLICKEYBYTES; ++ enc_out_len = crypto_kem_mlkem1024_CIPHERTEXTBYTES; ++ server_key_len = NIST_P384_UNCOMPRESSED_LEN; ++ } else ++ return r; ++ ++ client_pub = sshbuf_ptr(client_blob); ++#ifdef DEBUG_KEXECDH ++ dump_digest("client public key mlkem:", client_pub, mlkem_buf_len); ++ dump_digest("client public key NIST:", client_pub + mlkem_buf_len, ecdh_buf_len); ++#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; ++ } ++ r = (mlkem_buf_len == crypto_kem_mlkem768_PUBLICKEYBYTES) ? ++ mlkem768_encap_secret(client_pub, secret, enc_out) : ++ mlkem1024_encap_secret(client_pub, secret, enc_out); ++ ++ if (r != 0) ++ goto out; ++ ++ /* generate ECDH key pair, store server pubkey after ciphertext */ ++ server_key = nist_pkey_keygen(server_key_len); ++ ++ if ((r = get_uncompressed_ec_pubkey(server_key, server_pub, server_key_len) != 0) || ++ (r = sshbuf_put(buf, secret, sizeof(secret))) != 0 || ++ (r = sshbuf_put(server_blob, enc_out, enc_out_len) != 0)|| ++ (r = sshbuf_put(server_blob, server_pub, server_key_len)) != 0) ++ goto out; ++ ++ /* append ECDH shared key */ ++ client_pub += mlkem_buf_len; ++ if ((r = kex_nist_shared_key_ext(server_key, client_pub, ecdh_buf_len, buf)) < 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 NIST:", server_pub, server_key_len); ++ dump_digest("server cipher text:", enc_out, enc_out_len); ++ dump_digest("server kem key:", secret, sizeof(secret)); ++ 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)); ++ EVP_PKEY_free(server_key); ++ explicit_bzero(enc_out, sizeof(enc_out)); ++ explicit_bzero(secret, sizeof(secret)); ++ sshbuf_free(server_blob); ++ sshbuf_free(buf); ++ return r; ++} ++ ++static int ++kex_kem_mlkem_nist_dec(struct kex *kex, ++ const struct sshbuf *server_blob, struct sshbuf **shared_secretp, ++ size_t mlkem_len) ++{ ++ struct sshbuf *buf = NULL; ++ const u_char *ciphertext, *server_pub; ++ u_char hash[SSH_DIGEST_MAX_LENGTH]; ++ u_char decap[crypto_kem_mlkem768_BYTES]; ++ int r; ++ size_t nist_len; ++ ++ *shared_secretp = NULL; ++ ++ if (sshbuf_len(server_blob) < mlkem_len) { ++ r = SSH_ERR_SIGNATURE_INVALID; ++ goto out; ++ } ++ ++ nist_len = sshbuf_len(server_blob) - mlkem_len; ++ ++ switch (mlkem_len) { ++ case crypto_kem_mlkem768_CIPHERTEXTBYTES: ++ if (nist_len != NIST_P256_COMPRESSED_LEN ++ && nist_len != NIST_P256_UNCOMPRESSED_LEN) { ++ r = SSH_ERR_SIGNATURE_INVALID; ++ goto out; ++ } ++ break; ++ case crypto_kem_mlkem1024_CIPHERTEXTBYTES: ++ if (nist_len != NIST_P384_COMPRESSED_LEN ++ && nist_len != NIST_P384_UNCOMPRESSED_LEN) { ++ r = SSH_ERR_SIGNATURE_INVALID; ++ goto out; ++ } ++ break; ++ } ++ ++ ciphertext = sshbuf_ptr(server_blob); ++ server_pub = ciphertext + mlkem_len; ++ /* 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, mlkem_len); ++ dump_digest("server public key NIST:", server_pub, nist_len); ++#endif ++ r = (mlkem_len == crypto_kem_mlkem768_CIPHERTEXTBYTES) ? ++ mlkem768_decap_secret(kex->mlkem768_client_key, ciphertext, decap) : ++ mlkem1024_decap_secret(kex->mlkem1024_client_key, ciphertext, decap); ++ ++ if (r != 0) ++ goto out; ++ if ((r = sshbuf_put(buf, decap, sizeof(decap))) != 0) ++ goto out; ++ if ((r = kex_nist_shared_key_ext(kex->ec_hybrid_client_key, server_pub, ++ nist_len, buf)) < 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; ++} ++ ++int ++kex_kem_mlkem768nistp256_keypair(struct kex *kex) ++{ ++ return kex_kem_mlkem_nist_keypair(kex, crypto_kem_mlkem768_PUBLICKEYBYTES, NIST_P256_UNCOMPRESSED_LEN); ++} ++ ++int ++kex_kem_mlkem768nistp256_enc(struct kex *kex, const struct sshbuf *client_blob, ++ struct sshbuf **server_blobp, struct sshbuf **shared_secretp) ++{ ++ return kex_kem_mlkem_nist_enc(kex, "P-256", client_blob, server_blobp, shared_secretp); ++} ++ ++int ++kex_kem_mlkem768nistp256_dec(struct kex *kex, const struct sshbuf *server_blob, ++ struct sshbuf **shared_secretp) ++{ ++ return kex_kem_mlkem_nist_dec(kex, server_blob, shared_secretp, ++ crypto_kem_mlkem768_CIPHERTEXTBYTES); ++} ++ ++int ++kex_kem_mlkem1024nistp384_keypair(struct kex *kex) ++{ ++ return kex_kem_mlkem_nist_keypair(kex, crypto_kem_mlkem1024_PUBLICKEYBYTES, NIST_P384_UNCOMPRESSED_LEN); ++} ++ ++int ++kex_kem_mlkem1024nistp384_enc(struct kex *kex, const struct sshbuf *client_blob, ++ struct sshbuf **server_blobp, struct sshbuf **shared_secretp) ++{ ++ return kex_kem_mlkem_nist_enc(kex, "P-384", client_blob, server_blobp, shared_secretp); ++} ++ ++int ++kex_kem_mlkem1024nistp384_dec(struct kex *kex, const struct sshbuf *server_blob, ++ struct sshbuf **shared_secretp) ++{ ++ return kex_kem_mlkem_nist_dec(kex, server_blob, shared_secretp, ++ crypto_kem_mlkem1024_CIPHERTEXTBYTES); ++} ++ + #else /* USE_MLKEM768X25519 */ + int + kex_kem_mlkem768x25519_keypair(struct kex *kex) +@@ -567,4 +1164,39 @@ kex_kem_mlkem768x25519_dec(struct kex *kex, + { + return SSH_ERR_SIGN_ALG_UNSUPPORTED; + } ++ ++int kex_kem_mlkem768nistp256_keypair(struct kex *) ++{ ++ return SSH_ERR_SIGN_ALG_UNSUPPORTED; ++} ++ ++int kex_kem_mlkem768nistp256_enc(struct kex *, const struct sshbuf *, ++ struct sshbuf **, struct sshbuf **) ++{ ++ return SSH_ERR_SIGN_ALG_UNSUPPORTED; ++} ++ ++int kex_kem_mlkem768nistp256_dec(struct kex *, const struct sshbuf *, ++ struct sshbuf **) ++{ ++ return SSH_ERR_SIGN_ALG_UNSUPPORTED; ++} ++ ++int kex_kem_mlkem1024nistp384_keypair(struct kex *) ++{ ++ return SSH_ERR_SIGN_ALG_UNSUPPORTED; ++} ++ ++int kex_kem_mlkem1024nistp384_enc(struct kex *, const struct sshbuf *, ++ struct sshbuf **, struct sshbuf **) ++{ ++ return SSH_ERR_SIGN_ALG_UNSUPPORTED; ++} ++ ++int kex_kem_mlkem1024nistp384_dec(struct kex *, const struct sshbuf *, ++ struct sshbuf **) ++{ ++ return SSH_ERR_SIGN_ALG_UNSUPPORTED; ++} ++ + #endif /* USE_MLKEM768X25519 */ +diff --git a/monitor.c b/monitor.c +index 6c83739ee..2f154a3d7 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -2014,6 +2014,8 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) + 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; ++ kex->kex[KEX_KEM_MLKEM768NISTP256_SHA256] = kex_gen_server; ++ kex->kex[KEX_KEM_MLKEM1024NISTP384_SHA384] = kex_gen_server; + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; + kex->host_key_index=&get_hostkey_index; +diff --git a/myproposal.h b/myproposal.h +index 3e0ec6826..007347fc3 100644 +--- a/myproposal.h ++++ b/myproposal.h +@@ -26,6 +26,8 @@ + + #define KEX_SERVER_KEX \ + "mlkem768x25519-sha256," \ ++ "mlkem768nistp256-sha256," \ ++ "mlkem1024nistp384-sha384," \ + "sntrup761x25519-sha512," \ + "sntrup761x25519-sha512@openssh.com," \ + "curve25519-sha256," \ +@@ -97,6 +99,8 @@ + "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ + "aes128-gcm@openssh.com,aes256-gcm@openssh.com" + #define KEX_DEFAULT_KEX_FIPS \ ++ "mlkem768nistp256-sha256," \ ++ "mlkem1024nistp384-sha384," \ + "ecdh-sha2-nistp256," \ + "ecdh-sha2-nistp384," \ + "ecdh-sha2-nistp521," \ +diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c +index f4700deeb..99a8e3b46 100644 +--- a/regress/unittests/kex/test_kex.c ++++ b/regress/unittests/kex/test_kex.c +@@ -171,6 +171,8 @@ do_kex_with_key(char *kex, char *cipher, char *mac, + server2->kex->kex[KEX_C25519_SHA256] = kex_gen_server; + server2->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + server2->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; ++ server2->kex->kex[KEX_KEM_MLKEM768NISTP256_SHA256] = kex_gen_server; ++ server2->kex->kex[KEX_KEM_MLKEM1024NISTP384_SHA384] = kex_gen_server; + server2->kex->load_host_public_key = server->kex->load_host_public_key; + server2->kex->load_host_private_key = server->kex->load_host_private_key; + server2->kex->sign = server->kex->sign; +@@ -248,6 +250,8 @@ kex_tests(void) + } + # ifdef USE_MLKEM768X25519 + do_kex("mlkem768x25519-sha256"); ++ do_kex("mlkem768nistp256-sha256"); ++ do_kex("mlkem1024nistp384-sha384"); + # endif /* USE_MLKEM768X25519 */ + # ifdef USE_SNTRUP761X25519 + do_kex("sntrup761x25519-sha512"); +diff --git a/ssh-keyscan.c b/ssh-keyscan.c +index 11618ae8a..2f4037972 100644 +--- a/ssh-keyscan.c ++++ b/ssh-keyscan.c +@@ -290,6 +290,8 @@ keygrab_ssh2(con *c) + c->c_ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; + c->c_ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; + c->c_ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client; ++ c->c_ssh->kex->kex[KEX_KEM_MLKEM768NISTP256_SHA256] = kex_gen_client; ++ c->c_ssh->kex->kex[KEX_KEM_MLKEM1024NISTP384_SHA384] = kex_gen_client; + ssh_set_verify_host_key_callback(c->c_ssh, key_print_wrapper); + /* + * do the key-exchange until an error occurs or until +diff --git a/ssh_api.c b/ssh_api.c +index 7bdcee148..d20b03a00 100644 +--- a/ssh_api.c ++++ b/ssh_api.c +@@ -135,6 +135,8 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) + ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_server; + ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; ++ ssh->kex->kex[KEX_KEM_MLKEM768NISTP256_SHA256] = kex_gen_server; ++ ssh->kex->kex[KEX_KEM_MLKEM1024NISTP384_SHA384] = kex_gen_server; + ssh->kex->load_host_public_key=&_ssh_host_public_key; + ssh->kex->load_host_private_key=&_ssh_host_private_key; + ssh->kex->sign=&_ssh_host_key_sign; +@@ -154,6 +156,8 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) + 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->kex[KEX_KEM_MLKEM768NISTP256_SHA256] = kex_gen_client; ++ ssh->kex->kex[KEX_KEM_MLKEM1024NISTP384_SHA384] = kex_gen_client; + ssh->kex->verify_host_key =&_ssh_verify_host_key; + } + *sshp = ssh; +diff --git a/sshconnect2.c b/sshconnect2.c +index 2d98fc3da..88e27955a 100644 +--- a/sshconnect2.c ++++ b/sshconnect2.c +@@ -347,6 +347,8 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, + 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->kex[KEX_KEM_MLKEM768NISTP256_SHA256] = kex_gen_client; ++ ssh->kex->kex[KEX_KEM_MLKEM1024NISTP384_SHA384] = kex_gen_client; + ssh->kex->verify_host_key=&verify_host_key_callback; + + #if defined(GSSAPI) && defined(WITH_OPENSSL) +diff --git a/sshd-auth.c b/sshd-auth.c +index f3c38a7d1..698ef83f3 100644 +--- a/sshd-auth.c ++++ b/sshd-auth.c +@@ -893,6 +893,8 @@ do_ssh2_kex(struct ssh *ssh) + 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; ++ kex->kex[KEX_KEM_MLKEM768NISTP256_SHA256] = kex_gen_server; ++ kex->kex[KEX_KEM_MLKEM1024NISTP384_SHA384] = kex_gen_server; + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; + kex->host_key_index=&get_hostkey_index; +-- +2.52.0 + diff --git a/0050-Provide-a-way-to-disable-GSSAPIDelegateCredentials-s.patch b/0050-Provide-a-way-to-disable-GSSAPIDelegateCredentials-s.patch new file mode 100644 index 0000000..85c4140 --- /dev/null +++ b/0050-Provide-a-way-to-disable-GSSAPIDelegateCredentials-s.patch @@ -0,0 +1,139 @@ +From 71190d3d862113d97708a42b4a7daa7aa3c4e0ec Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Fri, 5 Dec 2025 14:55:38 +0100 +Subject: [PATCH 50/53] Provide a way to disable GSSAPIDelegateCredentials + server-side + +--- + gss-serv.c | 5 +++++ + servconf.c | 13 ++++++++++++- + servconf.h | 1 + + sshd_config.0 | 3 +++ + sshd_config.5 | 3 +++ + 5 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/gss-serv.c b/gss-serv.c +index be80e17ca..165484db0 100644 +--- a/gss-serv.c ++++ b/gss-serv.c +@@ -509,6 +509,11 @@ ssh_gssapi_cleanup_creds(void) + int + ssh_gssapi_storecreds(void) + { ++ if (options.gss_deleg_creds == 0) { ++ debug_f("delegate credential is disabled, doing nothing"); ++ return 0; ++ } ++ + if (gssapi_client.mech && gssapi_client.mech->storecreds) { + return (*gssapi_client.mech->storecreds)(&gssapi_client); + } else +diff --git a/servconf.c b/servconf.c +index e53e8ea30..fb1d150cd 100644 +--- a/servconf.c ++++ b/servconf.c +@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions *options) + options->gss_authentication=-1; + options->gss_keyex = -1; + options->gss_cleanup_creds = -1; ++ options->gss_deleg_creds = -1; + options->gss_strict_acceptor = -1; + options->gss_store_rekey = -1; + options->gss_kex_algorithms = NULL; +@@ -396,6 +397,8 @@ fill_default_server_options(ServerOptions *options) + options->gss_keyex = 0; + if (options->gss_cleanup_creds == -1) + options->gss_cleanup_creds = 1; ++ if (options->gss_deleg_creds == -1) ++ options->gss_deleg_creds = 1; + if (options->gss_strict_acceptor == -1) + options->gss_strict_acceptor = 1; + if (options->gss_store_rekey == -1) +@@ -591,7 +594,8 @@ typedef enum { + sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, + sPerSourcePenalties, sPerSourcePenaltyExemptList, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, +- sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, ++ sGssAuthentication, sGssCleanupCreds, sGssDelegateCreds, ++ sGssEnablek5users, sGssStrictAcceptor, + sGssKeyEx, sGssIndicators, sGssKexAlgorithms, sGssStoreRekey, + sAcceptEnv, sSetEnv, sPermitTunnel, + sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, +@@ -683,6 +687,7 @@ static struct { + { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, + { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL }, ++ { "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, + { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, +@@ -693,6 +698,7 @@ static struct { + { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, + { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, + { "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, ++ { "gssapidelegatecredentials", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, + { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, + { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, +@@ -1705,6 +1711,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, + intptr = &options->gss_cleanup_creds; + goto parse_flag; + ++ case sGssDelegateCreds: ++ intptr = &options->gss_deleg_creds; ++ goto parse_flag; ++ + case sGssStrictAcceptor: + intptr = &options->gss_strict_acceptor; + goto parse_flag; +@@ -3352,6 +3362,7 @@ dump_config(ServerOptions *o) + #ifdef GSSAPI + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); + dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); ++ dump_cfg_fmtint(sGssDelegateCreds, o->gss_deleg_creds); + dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); + dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); +diff --git a/servconf.h b/servconf.h +index c7cec5ece..9b1a73b8d 100644 +--- a/servconf.h ++++ b/servconf.h +@@ -156,6 +156,7 @@ typedef struct { + 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 */ ++ int gss_deleg_creds; /* If true, accept delegated GSS credentials */ + 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. */ +diff --git a/sshd_config.0 b/sshd_config.0 +index 8c5217c0b..cda9c9182 100644 +--- a/sshd_config.0 ++++ b/sshd_config.0 +@@ -453,6 +453,9 @@ DESCRIPTION + Specifies whether to automatically destroy the user's credentials + cache on logout. The default is yes. + ++ GSSAPIDelegateCredentials ++ Accept delegated credentials on the server side. The default is yes. ++ + GSSAPIStrictAcceptorCheck + Determines whether to be strict about the identity of the GSSAPI + acceptor a client authenticates against. If set to yes then the +diff --git a/sshd_config.5 b/sshd_config.5 +index 676d6d4d2..4ae4bebee 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -733,6 +733,9 @@ Specifies whether to automatically destroy the user's credentials cache + on logout. + The default is + .Cm yes . ++.It Cm GSSAPIDelegateCredentials ++Accept delegated credentials on the server side. The default is ++.CM yes . + .It Cm GSSAPIEnablek5users + Specifies whether to look at .k5users file for GSSAPI authentication + access control. Further details are described in +-- +2.52.0 + diff --git a/0025-openssh-7.3p1-x11-max-displays.patch b/0051-openssh-7.3p1-x11-max-displays.patch similarity index 82% rename from 0025-openssh-7.3p1-x11-max-displays.patch rename to 0051-openssh-7.3p1-x11-max-displays.patch index 68d679c..422107c 100644 --- a/0025-openssh-7.3p1-x11-max-displays.patch +++ b/0051-openssh-7.3p1-x11-max-displays.patch @@ -1,7 +1,7 @@ -From 36e3430d1f81397d5f40600e075272a81f7effce Mon Sep 17 00:00:00 2001 +From 763c65f6f349a7bab344a58991246891700e4fa0 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 +Date: Fri, 12 Dec 2025 15:35:14 +0100 +Subject: [PATCH 51/53] openssh-7.3p1-x11-max-displays --- channels.c | 9 ++++++--- @@ -13,10 +13,10 @@ Subject: [PATCH 25/50] openssh-7.3p1-x11-max-displays 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/channels.c b/channels.c -index d46531ce..7438c1a5 100644 +index 26ed9945f..c26380e25 100644 --- a/channels.c +++ b/channels.c -@@ -4996,7 +4996,7 @@ rdynamic_connect_finish(struct ssh *ssh, Channel *c) +@@ -5067,7 +5067,7 @@ rdynamic_connect_finish(struct ssh *ssh, Channel *c) */ int x11_create_display_inet(struct ssh *ssh, int x11_display_offset, @@ -25,7 +25,7 @@ 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, +@@ -5080,8 +5080,11 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS) return -1; @@ -33,25 +33,25 @@ index d46531ce..7438c1a5 100644 + x11_max_displays = x11_max_displays + x11_display_offset; + for (display_number = x11_display_offset; -- display_number < MAX_DISPLAYS; +- display_number < x11_display_offset + MAX_DISPLAYS; + display_number < x11_max_displays; display_number++) { port = X11_BASE_PORT + display_number; memset(&hints, 0, sizeof(hints)); -@@ -5065,7 +5068,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +@@ -5146,7 +5149,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, if (num_socks > 0) break; } -- if (display_number >= MAX_DISPLAYS) { +- if (display_number >= x11_display_offset + MAX_DISPLAYS) { + if (display_number >= x11_max_displays || port < X11_BASE_PORT ) { error("Failed to allocate internet-domain X11 display socket."); return -1; } diff --git a/channels.h b/channels.h -index 134528d5..8a09a820 100644 +index 7456541f8..754bd98ee 100644 --- a/channels.h +++ b/channels.h -@@ -379,7 +379,7 @@ int permitopen_port(const char *); +@@ -389,7 +389,7 @@ int permitopen_port(const char *); void channel_set_x11_refuse_time(struct ssh *, time_t); int x11_connect_display(struct ssh *); @@ -61,10 +61,10 @@ index 134528d5..8a09a820 100644 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 +index fb1d150cd..956205f6d 100644 --- a/servconf.c +++ b/servconf.c -@@ -117,6 +117,7 @@ initialize_server_options(ServerOptions *options) +@@ -118,6 +118,7 @@ initialize_server_options(ServerOptions *options) options->print_lastlog = -1; options->x11_forwarding = -1; options->x11_display_offset = -1; @@ -72,7 +72,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) +@@ -357,6 +358,8 @@ fill_default_server_options(ServerOptions *options) options->x11_forwarding = 0; if (options->x11_display_offset == -1) options->x11_display_offset = 10; @@ -81,7 +81,7 @@ 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 { +@@ -582,7 +585,7 @@ typedef enum { sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -90,7 +90,7 @@ index 105e301d..15c99b30 100644 sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, -@@ -714,6 +717,7 @@ static struct { +@@ -725,6 +728,7 @@ static struct { { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, @@ -98,7 +98,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, +@@ -1775,6 +1779,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, *intptr = value; break; @@ -109,7 +109,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) +@@ -3037,6 +3045,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); M_CP_INTOPT(x11_display_offset); M_CP_INTOPT(x11_forwarding); @@ -117,7 +117,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) +@@ -3332,6 +3341,7 @@ dump_config(ServerOptions *o) #endif dump_cfg_int(sLoginGraceTime, o->login_grace_time); dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); @@ -126,7 +126,7 @@ index 105e301d..15c99b30 100644 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 +index 9b1a73b8d..6bfdf6305 100644 --- a/servconf.h +++ b/servconf.h @@ -38,6 +38,7 @@ @@ -146,10 +146,10 @@ index c08cf6a7..7c7e5d43 100644 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 +index 80282dfd8..e53d044a0 100644 --- a/session.c +++ b/session.c -@@ -2611,8 +2611,9 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) +@@ -2681,8 +2681,9 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) return 0; } if (x11_create_display_inet(ssh, options.x11_display_offset, @@ -162,10 +162,10 @@ index 54da09d5..28bbb8a7 100644 return 0; } diff --git a/sshd_config.5 b/sshd_config.5 -index fe246fc2..26fcdc84 100644 +index 4ae4bebee..3dbce55fc 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1391,6 +1391,7 @@ Available keywords are +@@ -1403,6 +1403,7 @@ Available keywords are .Cm TrustedUserCAKeys , .Cm UnusedConnectionTimeout , .Cm X11DisplayOffset , @@ -173,7 +173,7 @@ index fe246fc2..26fcdc84 100644 .Cm X11Forwarding and .Cm X11UseLocalhost . -@@ -2111,6 +2112,12 @@ Specifies the first display number available for +@@ -2112,6 +2113,12 @@ Specifies the first display number available for X11 forwarding. This prevents sshd from interfering with real X11 servers. The default is 10. @@ -187,5 +187,5 @@ index fe246fc2..26fcdc84 100644 Specifies whether X11 forwarding is permitted. The argument must be -- -2.49.0 +2.52.0 diff --git a/0028-openssh-8.0p1-pkcs11-uri.patch b/0052-openssh-10.2p1-pkcs11-uri.patch similarity index 86% rename from 0028-openssh-8.0p1-pkcs11-uri.patch rename to 0052-openssh-10.2p1-pkcs11-uri.patch index 73e890b..b486fee 100644 --- a/0028-openssh-8.0p1-pkcs11-uri.patch +++ b/0052-openssh-10.2p1-pkcs11-uri.patch @@ -1,45 +1,59 @@ -From 5d6ec35c1a0e06452a2c087decb0baf6e8063e21 Mon Sep 17 00:00:00 2001 +From f32f2a8a37e8585c1259fea2a970319d229e2cc7 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 +Date: Mon, 15 Dec 2025 14:24:07 +0100 +Subject: [PATCH 52/53] openssh-10.2p1-pkcs11-uri --- - Makefile.in | 20 +- + Makefile.in | 24 +- configure.ac | 37 ++ - regress/Makefile | 8 +- - regress/pkcs11.sh | 349 +++++++++++++++ + regress/Makefile | 4 +- + regress/pkcs11.sh | 349 ++++++++++++++ regress/unittests/Makefile | 2 +- - regress/unittests/pkcs11/tests.c | 346 ++++++++++++++ + regress/unittests/pkcs11/tests.c | 353 ++++++++++++++ ssh-add.c | 48 +- - ssh-agent.c | 103 ++++- + ssh-agent.c | 104 ++++- ssh-keygen.c | 7 +- - ssh-pkcs11-client.c | 3 + + ssh-pkcs11-client.c | 17 + ssh-pkcs11-uri.c | 437 ++++++++++++++++++ ssh-pkcs11-uri.h | 43 ++ - ssh-pkcs11.c | 745 +++++++++++++++++++++++-------- + ssh-pkcs11.c | 760 ++++++++++++++++++++++--------- ssh-pkcs11.h | 4 + ssh.c | 104 ++++- ssh_config.5 | 15 + - 16 files changed, 2024 insertions(+), 247 deletions(-) + 16 files changed, 2039 insertions(+), 269 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 +index 20d134c02..f8cbd545d 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 +@@ -112,7 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ + sshbuf-io.o misc-agent.o auditstub.o + +-P11OBJS= ssh-pkcs11-client.o ++P11OBJS= ssh-pkcs11-client.o ssh-pkcs11-uri.o + + SKOBJS= ssh-sk-client.o + +@@ -161,11 +161,11 @@ SSHADD_OBJS= ssh-add.o $(P11OBJS) $(SKOBJS) + + SSHAGENT_OBJS= ssh-agent.o $(P11OBJS) $(SKOBJS) + +-SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o ssh-pkcs11.o $(SKOBJS) ++SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o ssh-pkcs11.o ssh-pkcs11-uri.o $(SKOBJS) + + SSHKEYSIGN_OBJS=ssh-keysign.o readconf.o uidswap.o $(P11OBJS) $(SKOBJS) + +-P11HELPER_OBJS= ssh-pkcs11-helper.o ssh-pkcs11.o $(SKOBJS) ++P11HELPER_OBJS= ssh-pkcs11-helper.o ssh-pkcs11.o ssh-pkcs11-uri.o $(SKOBJS) + + SKHELPER_OBJS= ssh-sk-helper.o ssh-sk.o sk-usbhid.o + +@@ -331,6 +331,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) @@ -48,7 +62,7 @@ index 78f65948..6c417ef7 100644 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 +@@ -369,6 +371,8 @@ distclean: regressclean rm -f regress/unittests/sshsig/test_sshsig rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 @@ -57,7 +71,7 @@ index 78f65948..6c417ef7 100644 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: +@@ -549,6 +553,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshkey $(MKDIR_P) `pwd`/regress/unittests/sshsig $(MKDIR_P) `pwd`/regress/unittests/utf8 @@ -65,7 +79,7 @@ index 78f65948..6c417ef7 100644 $(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): \ +@@ -724,6 +729,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) @@ -73,16 +87,16 @@ index 78f65948..6c417ef7 100644 + regress/unittests/pkcs11/tests.o + +regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} ssh-pkcs11-uri.o \ + 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) ++ ssh-pkcs11-uri.o -lssh -lopenbsd-compat -lcrypto $(LIBS) -lm + # 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) \ +@@ -769,7 +784,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) \ @@ -93,10 +107,10 @@ index 78f65948..6c417ef7 100644 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 +index 9d3b19925..e33462027 100644 --- a/configure.ac +++ b/configure.ac -@@ -2172,12 +2172,14 @@ AC_LINK_IFELSE( +@@ -2246,12 +2246,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -111,7 +125,7 @@ index 13c70a98..d9bd2f51 100644 fi ] ) -@@ -2207,6 +2209,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2281,6 +2283,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -152,7 +166,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" +@@ -5904,6 +5940,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -161,10 +175,10 @@ index 13c70a98..d9bd2f51 100644 echo "" diff --git a/regress/Makefile b/regress/Makefile -index 7e7f95b5..f36de51e 100644 +index ece093a2b..a851549f6 100644 --- a/regress/Makefile +++ b/regress/Makefile -@@ -137,7 +137,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ +@@ -139,7 +139,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -174,21 +188,17 @@ 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: - V="" ; \ - test "x${USE_VALGRIND}" = "x" || \ - V=${.CURDIR}/valgrind-unit.sh ; \ -- $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ -- $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ -+ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ -+ $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ -+ $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -d ${.CURDIR}/unittests/sshkey/testdata ; \ - $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ - -d ${.CURDIR}/unittests/sshsig/testdata ; \ +@@ -288,6 +289,7 @@ unit unit-bench: + test "x${UNITTEST_VERBOSE}" = "x" || ARGS="$$ARGS -v"; \ + test "x${UNITTEST_BENCH_DETAIL}" = "x" || ARGS="$$ARGS -B"; \ + test "x${UNITTEST_BENCH_ONLY}" = "x" || ARGS="$$ARGS -O ${UNITTEST_BENCH_ONLY}"; \ ++ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf $${ARGS}; \ + $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + -d ${.CURDIR}/unittests/sshkey/testdata $${ARGS}; \ diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh new file mode 100644 -index 00000000..a91aee94 +index 000000000..a91aee94f --- /dev/null +++ b/regress/pkcs11.sh @@ -0,0 +1,349 @@ @@ -542,7 +552,7 @@ index 00000000..a91aee94 + ${SSHAGENT} -k > /dev/null +fi diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index e370900e..d6c89c12 100644 +index e370900e4..d6c89c129 100644 --- a/regress/unittests/Makefile +++ b/regress/unittests/Makefile @@ -1,6 +1,6 @@ @@ -555,10 +565,10 @@ index e370900e..d6c89c12 100644 .include diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c new file mode 100644 -index 00000000..7d4fa499 +index 000000000..89ba45c4e --- /dev/null +++ b/regress/unittests/pkcs11/tests.c -@@ -0,0 +1,346 @@ +@@ -0,0 +1,353 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -905,20 +915,27 @@ index 00000000..7d4fa499 + test_parse_invalid(); + test_generate_valid(); +} ++ ++void ++benchmarks(void) ++{ ++ printf("no benchmarks\n"); ++} ++ diff --git a/ssh-add.c b/ssh-add.c -index 0035cb84..b0f47f4d 100644 +index 2d5bec89c..aae82a794 100644 --- a/ssh-add.c +++ b/ssh-add.c -@@ -69,6 +69,7 @@ +@@ -70,6 +70,7 @@ #include "ssh-sk.h" #include "sk-api.h" #include "hostfile.h" +#include "ssh-pkcs11-uri.h" - /* argv0 */ - extern char *__progname; -@@ -242,6 +243,38 @@ delete_all(int agent_fd, int qflag) - return ret; + #define CERT_EXPIRY_GRACE (5*60) + +@@ -257,6 +258,38 @@ check_cert_lifetime(const struct sshkey *cert, int cert_lifetime) + return MINIMUM(cert_lifetime, (int)n); } +#ifdef ENABLE_PKCS11 @@ -955,8 +972,8 @@ 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 + int qflag, int Nflag, const char *skprovider, +@@ -447,15 +480,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,8 +991,8 @@ 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, - char *file, int qflag, const char *skprovider, +@@ -637,6 +669,14 @@ do_file(int agent_fd, int deleting, int key_only, int cert_only, + char *file, int qflag, int Nflag, const char *skprovider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { +#ifdef ENABLE_PKCS11 @@ -989,20 +1006,20 @@ 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) +@@ -1009,7 +1049,7 @@ main(int argc, char **argv) if (update_card(agent_fd, !deleting, pkcs11provider, qflag, key_only, cert_only, dest_constraints, ndest_constraints, - certs, ncerts) == -1) + certs, ncerts, NULL) == -1) ret = 1; - goto done; - } + for (n = 0; n < ncerts; n++) + sshkey_free(certs[n]); diff --git a/ssh-agent.c b/ssh-agent.c -index c27c5a95..798bf9b6 100644 +index dc246066d..c3e94e2b1 100644 --- a/ssh-agent.c +++ b/ssh-agent.c -@@ -1569,10 +1569,74 @@ add_p11_identity(struct sshkey *key, char *comment, const char *provider, +@@ -1540,10 +1540,75 @@ add_p11_identity(struct sshkey *key, char *comment, const char *provider, idtab->nentries++; } @@ -1030,6 +1047,7 @@ index c27c5a95..798bf9b6 100644 + + 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 */ @@ -1078,7 +1096,7 @@ 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) +@@ -1572,25 +1637,18 @@ process_add_smartcard_key(SocketEntry *e) "providers is disabled", provider); goto send; } @@ -1109,7 +1127,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) +@@ -1600,13 +1658,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 +1143,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) +@@ -1619,6 +1677,7 @@ process_add_smartcard_key(SocketEntry *e) send: free(pin); free(provider); @@ -1133,7 +1151,7 @@ index c27c5a95..798bf9b6 100644 free(keys); free(comments); free_dest_constraints(dest_constraints, ndest_constraints); -@@ -1660,7 +1718,7 @@ send: +@@ -1631,7 +1690,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1142,7 +1160,7 @@ index c27c5a95..798bf9b6 100644 int r, success = 0; Identity *id, *nxt; -@@ -1672,30 +1730,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -1643,30 +1702,29 @@ process_remove_smartcard_key(SocketEntry *e) } free(pin); @@ -1180,10 +1198,10 @@ index c27c5a95..798bf9b6 100644 } #endif /* ENABLE_PKCS11 */ diff --git a/ssh-keygen.c b/ssh-keygen.c -index 89c3ed28..16cff947 100644 +index afa279097..7af08fcdf 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c -@@ -906,8 +906,11 @@ do_download(struct passwd *pw) +@@ -831,8 +831,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1198,10 +1216,30 @@ 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 +index 85afb62ac..7b7eaf533 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, +@@ -378,6 +378,19 @@ pkcs11_start_helper(const char *path) + return helper; + } + ++int ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, struct sshkey ***keyp, char ***labelsp) ++{ ++ int nkeys = 0; ++ char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug_f("called, provider_uri = %s", provider_uri); ++ ++ nkeys = pkcs11_add_provider(provider_uri, pin, keyp, labelsp); ++ ++ return nkeys; ++} ++ + int + pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, + char ***labelsp) +@@ -389,6 +403,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, struct sshbuf *msg; struct helper *helper; @@ -1210,17 +1248,17 @@ 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, +@@ -413,6 +429,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); + debug_f("nkeys = %u", nkeys); for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ - if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || + if ((r = sshkey_froms(msg, &k)) != 0 || diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c new file mode 100644 -index 00000000..8bd97e9e +index 000000000..8bd97e9e2 --- /dev/null +++ b/ssh-pkcs11-uri.c @@ -0,0 +1,437 @@ @@ -1663,7 +1701,7 @@ 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 +index 000000000..29e9f7327 --- /dev/null +++ b/ssh-pkcs11-uri.h @@ -0,0 +1,43 @@ @@ -1711,18 +1749,26 @@ index 00000000..29e9f732 +char *pkcs11_uri_get(struct pkcs11_uri *uri); + diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index 31b9360f..b96f5b89 100644 +index c88179473..1a443824d 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c -@@ -38,6 +38,7 @@ +@@ -39,6 +39,7 @@ #include #include #include +#include + #endif #define CRYPTOKI_COMPAT - #include "pkcs11.h" -@@ -55,8 +56,8 @@ struct pkcs11_slotinfo { +@@ -51,6 +52,7 @@ + #include "misc.h" + #include "sshbuf.h" + #include "ssh-pkcs11.h" ++#include "ssh-pkcs11-uri.h" + #include "digest.h" + #include "xmalloc.h" + #include "crypto_api.h" +@@ -61,8 +63,8 @@ struct pkcs11_slotinfo { int logged_in; }; @@ -1733,7 +1779,7 @@ index 31b9360f..b96f5b89 100644 void *handle; CK_FUNCTION_LIST *function_list; CK_INFO info; -@@ -65,6 +66,13 @@ struct pkcs11_provider { +@@ -71,6 +73,13 @@ struct pkcs11_provider { struct pkcs11_slotinfo *slotinfo; int valid; int refcount; @@ -1747,15 +1793,15 @@ index 31b9360f..b96f5b89 100644 TAILQ_ENTRY(pkcs11_provider) next; }; -@@ -75,6 +83,7 @@ struct pkcs11_key { +@@ -82,6 +91,7 @@ struct pkcs11_key { CK_ULONG slotidx; char *keyid; int keyid_len; + char *label; + TAILQ_ENTRY(pkcs11_key) next; }; - int pkcs11_interactive = 0; -@@ -106,26 +115,61 @@ pkcs11_init(int interactive) +@@ -108,26 +118,61 @@ ossl_error(const char *msg) * this is called when a provider gets unregistered. */ static void @@ -1828,7 +1874,7 @@ index 31b9360f..b96f5b89 100644 } /* -@@ -137,11 +181,9 @@ pkcs11_provider_unref(struct pkcs11_provider *p) +@@ -139,15 +184,27 @@ pkcs11_provider_unref(struct pkcs11_provider *p) { debug_f("provider \"%s\" refcount %d", p->name, p->refcount); if (--p->refcount <= 0) { @@ -1842,9 +1888,6 @@ index 31b9360f..b96f5b89 100644 free(p); } } -@@ -159,6 +201,20 @@ pkcs11_terminate(void) - } - } +/* lookup provider by module path */ +static struct pkcs11_module * @@ -1863,7 +1906,7 @@ index 31b9360f..b96f5b89 100644 /* lookup provider by name */ static struct pkcs11_provider * pkcs11_provider_lookup(char *provider_id) -@@ -173,19 +229,55 @@ pkcs11_provider_lookup(char *provider_id) +@@ -162,19 +219,55 @@ pkcs11_provider_lookup(char *provider_id) return (NULL); } @@ -1921,10 +1964,113 @@ index 31b9360f..b96f5b89 100644 + 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 */ + /* release a wrapped object */ +@@ -186,6 +279,7 @@ pkcs11_k11_free(struct pkcs11_key *k11) + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ free(k11->label); + sshbuf_free(k11->keyblob); + free(k11); + } +@@ -201,8 +295,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); +@@ -239,14 +333,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)); +@@ -276,13 +370,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); + } + + +@@ -298,13 +393,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; +@@ -335,13 +431,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) { +@@ -440,6 +537,12 @@ pkcs11_record_key(struct pkcs11_provider *provider, CK_ULONG slotidx, + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } ++ if (keyid_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(keyid_attrib->ulValueLen+1); ++ memcpy(k11->label, keyid_attrib->pValue, keyid_attrib->ulValueLen); ++ k11->label[keyid_attrib->ulValueLen] = 0; ++ } ++ + TAILQ_INSERT_TAIL(&pkcs11_keys, k11, next); + + return 0; +@@ -467,6 +570,42 @@ pkcs11_lookup_key(struct sshkey *key) + return found; + } +/* + * This can't be in the ssh-pkcs11-uri, becase we can not depend on @@ -1935,26 +2081,8 @@ index 31b9360f..b96f5b89 100644 +{ + char *p = NULL; + struct pkcs11_uri uri; -+ struct pkcs11_key *k11; ++ struct pkcs11_key *k11 = pkcs11_lookup_key(key); + -+ /* 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); @@ -1980,176 +2108,53 @@ index 31b9360f..b96f5b89 100644 + 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); + #ifdef WITH_OPENSSL + /* + * See: +@@ -571,8 +710,8 @@ pkcs11_sign_rsa(struct sshkey *key, + return SSH_ERR_AGENT_FAILURE; + } + +- 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 ((siglen = EVP_PKEY_size(key->pkey)) <= 0) + return SSH_ERR_INVALID_ARGUMENT; +@@ -661,8 +800,8 @@ pkcs11_sign_ecdsa(struct sshkey *key, + debug3_f("sign using provider %s slotidx %lu", + k11->provider->name, (u_long)k11->slotidx); + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + /* Prepare digest to be signed */ + if ((hashalg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) +@@ -746,8 +885,8 @@ pkcs11_sign_ed25519(struct sshkey *key, + debug3_f("sign using provider %s slotidx %lu", + k11->provider->name, (u_long)k11->slotidx); + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + xdata = xmalloc(datalen); + memcpy(xdata, data, datalen); +@@ -775,7 +914,8 @@ pkcs11_sign_ed25519(struct sshkey *key, + return ret; } -@@ -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, +@@ -807,8 +947,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, CK_SESSION_HANDLE session; int login_required, ret; @@ -2160,7 +2165,7 @@ index 31b9360f..b96f5b89 100644 login_required = si->token.flags & CKF_LOGIN_REQUIRED; -@@ -669,9 +832,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, +@@ -818,9 +958,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -2172,7 +2177,7 @@ index 31b9360f..b96f5b89 100644 return (-1); } if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -707,7 +870,8 @@ static struct sshkey * +@@ -857,7 +997,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2182,7 +2187,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -870,14 +1011,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; @@ -2203,7 +2208,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -888,19 +1030,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. */ @@ -2227,7 +2232,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -912,8 +1054,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2238,7 +2243,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -924,13 +1066,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2255,25 +2260,7 @@ index 31b9360f..b96f5b89 100644 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 * +@@ -992,7 +1134,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2283,7 +2270,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1003,14 +1146,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; @@ -2304,7 +2291,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1021,19 +1165,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. */ @@ -2328,7 +2315,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1045,8 +1189,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2339,25 +2326,112 @@ index 31b9360f..b96f5b89 100644 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; - +@@ -1078,7 +1222,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + /* success */ + success = 0; fail: - for (i = 0; i < 3; i++) + for (i = 0; i < nattr; i++) free(key_attr[i].pValue); RSA_free(rsa); + if (success != 0) { +@@ -1093,7 +1237,8 @@ static struct sshkey * + pkcs11_fetch_ed25519_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; +@@ -1113,14 +1258,15 @@ pkcs11_fetch_ed25519_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, -@@ -926,7 +1093,8 @@ static int + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_EC_POINT; /* XXX or CKA_VALUE ? */ +- key_attr[2].type = CKA_EC_PARAMS; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_EC_POINT; /* XXX or CKA_VALUE ? */ ++ 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); +@@ -1131,28 +1277,28 @@ pkcs11_fetch_ed25519_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; + } + + /* Expect one of the supported identifiers in CKA_EC_PARAMS */ +- d = (u_char *)key_attr[2].pValue; +- len = key_attr[2].ulValueLen; ++ d = (u_char *)key_attr[3].pValue; ++ len = key_attr[3].ulValueLen; + if ((len != sizeof(id1) || memcmp(d, id1, sizeof(id1)) != 0) && + (len != sizeof(id2) || memcmp(d, id2, sizeof(id2)) != 0)) { + hex = tohex(d, len); +@@ -1164,16 +1310,16 @@ pkcs11_fetch_ed25519_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + * Expect either a raw 32 byte pubkey or an OCTET STRING with + * a 32 byte pubkey in CKA_VALUE + */ +- d = (u_char *)key_attr[1].pValue; +- len = key_attr[1].ulValueLen; ++ d = (u_char *)key_attr[2].pValue; ++ len = key_attr[2].ulValueLen; + if (len == ED25519_PK_SZ + 2 && d[0] == 0x04 && d[1] == ED25519_PK_SZ) { + d += 2; + len -= 2; + } + if (len != ED25519_PK_SZ) { +- hex = tohex(key_attr[1].pValue, key_attr[1].ulValueLen); ++ hex = tohex(key_attr[2].pValue, key_attr[2].ulValueLen); + logit_f("CKA_EC_POINT invalid octet str: %s (len %lu)", +- hex, (u_long)key_attr[1].ulValueLen); ++ hex, (u_long)key_attr[2].ulValueLen); + goto fail; + } + +@@ -1193,7 +1339,7 @@ pkcs11_fetch_ed25519_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + key = NULL; + } + free(hex); +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + return key; + } +@@ -1203,7 +1349,8 @@ static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) { @@ -2367,7 +2441,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1229,14 +1376,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; @@ -2388,7 +2462,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1248,18 +1396,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 || @@ -2411,7 +2485,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1273,8 +1422,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, subject = xstrdup("invalid subject"); X509_NAME_free(x509_name); @@ -2422,25 +2496,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1384,7 +1533,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto out; } out: @@ -2449,7 +2505,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1427,11 +1576,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, @@ -2464,7 +2520,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1448,10 +1598,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2482,16 +2538,16 @@ index 31b9360f..b96f5b89 100644 + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - rv = f->C_FindObjectsInit(session, key_attr, 1); ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1227,11 +1411,12 @@ fail: +@@ -1533,11 +1696,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2506,7 +2562,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1553,10 +1717,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2533,7 +2589,7 @@ index 31b9360f..b96f5b89 100644 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, +@@ -1844,16 +2021,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, } #endif /* WITH_PKCS11_KEYGEN */ @@ -2552,7 +2608,7 @@ index 31b9360f..b96f5b89 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1550,162 +1742,309 @@ pkcs11_register_provider(char *provider_id, char *pin, +@@ -1862,128 +2033,126 @@ pkcs11_register_provider(char *provider_id, char *pin, CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2643,13 +2699,6 @@ index 31b9360f..b96f5b89 100644 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" @@ -2662,6 +2711,13 @@ index 31b9360f..b96f5b89 100644 - 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", @@ -2714,7 +2770,6 @@ index 31b9360f..b96f5b89 100644 - 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> " @@ -2725,39 +2780,77 @@ index 31b9360f..b96f5b89 100644 RMSPACE(token->label), RMSPACE(token->manufacturerID), RMSPACE(token->model), RMSPACE(token->serialNumber), token->flags); -+ } +- /* +- * open session, login with pin and retrieve public +- * keys (if keyp is provided) +- */ +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || +- keyp == NULL) +- continue; +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +-#ifdef WITH_OPENSSL +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +-#endif +- if (nkeys == 0 && !p->slotinfo[i].logged_in && +- pkcs11_interactive) { +- /* +- * Some tokens require login before they will +- * expose keys. +- */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], +- CKU_USER) < 0) { +- error("login failed"); +- continue; +- } +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +-#ifdef WITH_OPENSSL +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +-#endif +- } + } + 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 */ -+ + + /* now owned by caller */ + *providerp = p; +@@ -1991,21 +2160,22 @@ pkcs11_register_provider(char *provider_id, char *pin, + TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); + p->refcount++; /* add to provider list */ + +- return (nkeys); + return 0; -+fail: -+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -+ error("C_Finalize for provider %s failed: %lu", + fail: + if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + 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); -+} -+ -+/* + if (p) { + free(p->name); +- free(p->slotlist); +- free(p->slotinfo); + free(p); + } + if (handle) + dlclose(handle); +- if (ret > 0) +- ret = -1; + return (ret); + } + +@@ -2041,18 +2211,161 @@ pkcs11_terminate(void) + } + + /* +- * register a new provider and get number of keys hold by the token, +- * fails if provider already exists + * register a new provider, fails if provider already exists. if + * keyp is provided, fetch keys. -+ */ + */ +static int +pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, + struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, @@ -2819,37 +2912,28 @@ index 31b9360f..b96f5b89 100644 + 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 && ++ keyp == NULL) ++ continue; + 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], ++ pkcs11_interactive) { ++ /* ++ * Some tokens require login before they will ++ * expose keys. ++ */ + 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); ++ CKU_USER) < 0) { ++ error("login failed"); ++ continue; ++ } + pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); + pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + } @@ -2862,41 +2946,25 @@ index 31b9360f..b96f5b89 100644 + 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 */ -- ++ ++ /* now owned by caller */ ++ *providerp = p; ++ + 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); ++ return (nkeys); ++ fail: ++ if (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 -- */ ++ pkcs11_provider_unref(p); ++ } ++ if (ret > 0) ++ ret = -1; ++ return (ret); ++} ++ +static int +pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, + char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) @@ -2942,21 +3010,17 @@ index 31b9360f..b96f5b89 100644 /* 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, +@@ -2061,11 +2374,38 @@ 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 -+ */ + return (nkeys); + } + +int +pkcs11_add_provider(char *provider_id, char *pin, + struct sshkey ***keyp, char ***labelsp) @@ -2978,33 +3042,40 @@ index 31b9360f..b96f5b89 100644 + + nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); + pkcs11_uri_cleanup(uri); - - return (nkeys); - } ++ ++ return (nkeys); ++} ++ ++ + int + pkcs11_sign(struct sshkey *key, + u_char **sigp, size_t *lenp, diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h -index 52602231..9ce20c1f 100644 +index d86c506c1..32f2d0ccf 100644 --- a/ssh-pkcs11.h +++ b/ssh-pkcs11.h -@@ -22,10 +22,14 @@ +@@ -22,12 +22,16 @@ #define SSH_PKCS11_ERR_PIN_REQUIRED 4 #define SSH_PKCS11_ERR_PIN_LOCKED 5 +#include "ssh-pkcs11-uri.h" + + struct sshkey; + 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, + int pkcs11_sign(struct sshkey *, u_char **, size_t *, + const u_char *, size_t, const char *, const char *, + const char *, u_int); diff --git a/ssh.c b/ssh.c -index c23d3b9e..98b103c9 100644 +index 320ac6834..14965a4f1 100644 --- a/ssh.c +++ b/ssh.c -@@ -890,6 +890,14 @@ main(int ac, char **av) +@@ -904,6 +904,14 @@ main(int ac, char **av) options.gss_deleg_creds = 1; break; case 'i': @@ -3019,15 +3090,15 @@ index c23d3b9e..98b103c9 100644 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) +@@ -1872,6 +1880,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) + if (addrs != NULL) +@@ -2387,6 +2396,45 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -3073,7 +3144,7 @@ index c23d3b9e..98b103c9 100644 /* 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) +@@ -2401,11 +2449,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]; @@ -3085,7 +3156,7 @@ index c23d3b9e..98b103c9 100644 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) +@@ -2418,33 +2461,46 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -3152,10 +3223,10 @@ index c23d3b9e..98b103c9 100644 free(cp); check_load(sshkey_load_public(filename, &public, NULL), diff --git a/ssh_config.5 b/ssh_config.5 -index 3a8e246c..8d5d0722 100644 +index a06fbfa11..717b0938a 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -1263,6 +1263,21 @@ may also be used in conjunction with +@@ -1260,6 +1260,21 @@ may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. @@ -3178,5 +3249,5 @@ index 3a8e246c..8d5d0722 100644 Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. -- -2.49.0 +2.52.0 diff --git a/1000-openssh-coverity.patch b/1000-openssh-6.7p1-coverity.patch similarity index 73% rename from 1000-openssh-coverity.patch rename to 1000-openssh-6.7p1-coverity.patch index 88362eb..40c298e 100644 --- a/1000-openssh-coverity.patch +++ b/1000-openssh-6.7p1-coverity.patch @@ -1,7 +1,7 @@ -From 24c411970682dc67873c36bac05b4b460d68a628 Mon Sep 17 00:00:00 2001 +From aecc5861e1cf7094a32f893ae4bfd8409b77e5cd 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 +Date: Fri, 12 Dec 2025 14:25:41 +0100 +Subject: [PATCH 53/53] openssh-6.7p1-coverity --- auth-krb5.c | 2 ++ @@ -15,12 +15,10 @@ Subject: [PATCH 50/50] openssh-6.7p1-coverity readconf.c | 1 + servconf.c | 5 +++-- serverloop.c | 2 +- - ssh-agent.c | 1 + - ssh-keygen.c | 3 +++ - 13 files changed, 28 insertions(+), 11 deletions(-) + 11 files changed, 24 insertions(+), 11 deletions(-) diff --git a/auth-krb5.c b/auth-krb5.c -index bae153c9..209a3265 100644 +index b9c261a24..a37be93c3 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 @@ -40,10 +38,10 @@ index bae153c9..209a3265 100644 } /* make sure the KRB5CCNAME is set for non-standard location */ diff --git a/gss-genr.c b/gss-genr.c -index 3034370c..c357e973 100644 +index f2d6f59e5..91602e045 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, +@@ -178,8 +178,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); @@ -55,10 +53,10 @@ index 3034370c..c357e973 100644 (p = strsep(&cp, ","))) { if (sshbuf_len(buf) != 0 && diff --git a/krl.c b/krl.c -index 0d0f6953..d8517f12 100644 +index bea5b1b98..4dd8a24a9 100644 --- a/krl.c +++ b/krl.c -@@ -1202,6 +1202,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) +@@ -1205,6 +1205,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); @@ -66,7 +64,7 @@ index 0d0f6953..d8517f12 100644 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) +@@ -1215,6 +1216,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); @@ -74,7 +72,7 @@ index 0d0f6953..d8517f12 100644 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) +@@ -1226,6 +1228,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); @@ -83,10 +81,10 @@ index 0d0f6953..d8517f12 100644 KRL_DBG(("revoked by explicit key")); return SSH_ERR_KEY_REVOKED; diff --git a/loginrec.c b/loginrec.c -index c4a9bd48..2583612c 100644 +index 7d1c9dd43..a017e173b 100644 --- a/loginrec.c +++ b/loginrec.c -@@ -683,9 +683,11 @@ construct_utmp(struct logininfo *li, +@@ -677,9 +677,11 @@ construct_utmp(struct logininfo *li, */ /* Use strncpy because we don't necessarily want null termination */ @@ -99,10 +97,10 @@ index c4a9bd48..2583612c 100644 MIN_SIZEOF(ut->ut_host, li->hostname)); # endif diff --git a/misc.c b/misc.c -index 09722962..cd71c1b2 100644 +index 2fd14159d..d4c4e4164 100644 --- a/misc.c +++ b/misc.c -@@ -1556,6 +1556,8 @@ sanitise_stdfd(void) +@@ -1573,6 +1573,8 @@ sanitise_stdfd(void) } if (nullfd > STDERR_FILENO) close(nullfd); @@ -111,7 +109,7 @@ index 09722962..cd71c1b2 100644 } char * -@@ -2749,6 +2751,7 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) +@@ -2773,6 +2775,7 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) } if (devnull > STDERR_FILENO) close(devnull); @@ -120,10 +118,10 @@ index 09722962..cd71c1b2 100644 } diff --git a/monitor.c b/monitor.c -index 19cb058e..58fbac9d 100644 +index 2f154a3d7..f959e0124 100644 --- a/monitor.c +++ b/monitor.c -@@ -415,7 +415,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -405,7 +405,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) mm_get_keystate(ssh, pmonitor); /* Drain any buffered messages from the child */ @@ -131,8 +129,8 @@ index 19cb058e..58fbac9d 100644 + 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) + /* Wait for the child's exit status */ +@@ -1819,7 +1819,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); @@ -142,7 +140,7 @@ index 19cb058e..58fbac9d 100644 error: diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c -index 346c7fe5..f42792fd 100644 +index 346c7fe56..f42792fde 100644 --- a/openbsd-compat/bindresvport.c +++ b/openbsd-compat/bindresvport.c @@ -59,7 +59,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) @@ -155,7 +153,7 @@ index 346c7fe5..f42792fd 100644 if (sa == NULL) { diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c -index 26bdc3e0..8e2939b9 100644 +index 26bdc3e08..8e2939b95 100644 --- a/openbsd-compat/bsd-pselect.c +++ b/openbsd-compat/bsd-pselect.c @@ -85,13 +85,13 @@ pselect_notify_setup(void) @@ -186,10 +184,10 @@ index 26bdc3e0..8e2939b9 100644 FD_CLR(notify_pipe[0], readset); } diff --git a/readconf.c b/readconf.c -index ea9d293c..9680c38c 100644 +index b6ad47b49..75e1c953c 100644 --- a/readconf.c +++ b/readconf.c -@@ -2164,6 +2164,7 @@ parse_pubkey_algos: +@@ -2170,6 +2170,7 @@ parse_pubkey_algos: } else if (r != 0) { error("%.200s line %d: glob failed for %s.", filename, linenum, arg2); @@ -198,10 +196,10 @@ index ea9d293c..9680c38c 100644 } free(arg2); diff --git a/servconf.c b/servconf.c -index 8b708cbf..e7e4ad04 100644 +index 956205f6d..1093dcbac 100644 --- a/servconf.c +++ b/servconf.c -@@ -2293,8 +2293,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -2307,8 +2307,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, if (*activep && *charptr == NULL) { *charptr = tilde_expand_filename(arg, getuid()); /* increase optional counter */ @@ -214,10 +212,10 @@ index 8b708cbf..e7e4ad04 100644 break; diff --git a/serverloop.c b/serverloop.c -index 9c5b1567..768ee9fa 100644 +index 55411a6b4..acc721cd1 100644 --- a/serverloop.c +++ b/serverloop.c -@@ -511,7 +511,7 @@ server_request_tun(struct ssh *ssh) +@@ -533,7 +533,7 @@ server_request_tun(struct ssh *ssh) debug_f("invalid tun"); goto done; } @@ -226,32 +224,6 @@ index 9c5b1567..768ee9fa 100644 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 +2.52.0 diff --git a/openssh.spec b/openssh.spec index 4f98f19..ff38f4b 100644 --- a/openssh.spec +++ b/openssh.spec @@ -38,12 +38,12 @@ # rpm -ba|--rebuild --define "static_openssl 1" %{?static_openssl:%global static_libcrypto 1} -%global openssh_ver 10.0p1 +%global openssh_ver 10.2p1 Summary: An open source implementation of SSH protocol version 2 Name: openssh Version: %{openssh_ver} -Release: 5%{?dist} +Release: 1%{?dist} URL: http://www.openssh.com/portable.html Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz Source1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc @@ -67,124 +67,114 @@ Source23: parallel_test.Makefile #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch0001: 0001-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 +Patch0002: 0002-openssh-6.6p1-keycat.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1644 -Patch0004: 0004-openssh-6.6p1-allow-ip-opts.patch +Patch0003: 0003-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 -#https://bugzilla.mindrot.org/show_bug.cgi?id=1789 -Patch0007: 0007-openssh-7.2p2-x11.patch -Patch0008: 0008-openssh-5.1p1-askpass-progress.patch +Patch0004: 0004-openssh-5.9p1-ipv6man.patch +Patch0005: 0005-openssh-5.8p2-sigpipe.patch +Patch0006: 0006-openssh-7.2p2-x11.patch +Patch0007: 0007-openssh-5.1p1-askpass-progress.patch #https://bugzilla.redhat.com/show_bug.cgi?id=198332 -Patch0009: 0009-openssh-4.3p2-askpass-grab-info.patch +Patch0008: 0008-openssh-4.3p2-askpass-grab-info.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) -Patch0010: 0010-openssh-8.7p1-redhat.patch +Patch0009: 0009-openssh-8.7p1-redhat.patch # warn users for unsupported UsePAM=no (#757545) -Patch0011: 0011-openssh-7.8p1-UsePAM-warning.patch +Patch0010: 0010-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 +Patch0011: 0011-openssh-9.6p1-gssapi-keyex.patch #http://www.mail-archive.com/kerberos@mit.edu/msg17591.html -Patch0013: 0013-openssh-6.6p1-force_krb.patch +Patch0012: 0012-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 +Patch0013: 0013-openssh-7.7p1-gssapi-new-unique.patch # Respect k5login_directory option in krk5.conf (#1328243) -Patch0015: 0015-openssh-7.2p2-k5login_directory.patch +Patch0014: 0014-openssh-7.2p2-k5login_directory.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 -Patch0016: 0016-openssh-6.6p1-kuserok.patch +Patch0015: 0015-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 +Patch0016: 0016-openssh-6.4p1-fromto-remote.patch # log via monitor in chroots without /dev/log (#2681) -Patch0019: 0019-openssh-6.6.1p1-log-in-chroot.patch +Patch0017: 0017-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 +Patch0018: 0018-openssh-6.6.1p1-scp-non-existing-directory.patch # add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843) # CVE-2014-9278 -Patch0021: 0021-openssh-6.6p1-GSSAPIEnablek5users.patch +Patch0019: 0019-openssh-6.6p1-GSSAPIEnablek5users.patch # apply upstream patch and make sshd -T more consistent (#1187521) -Patch0022: 0022-openssh-6.8p1-sshdT-output.patch +Patch0020: 0020-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 +Patch0021: 0021-openssh-6.7p1-sftp-force-permission.patch # make s390 use /dev/ crypto devices -- ignore closefrom -Patch0024: 0024-openssh-7.2p2-s390-closefrom.patch -# Move MAX_DISPLAYS to a configuration option (#1341302) -Patch0025: 0025-openssh-7.3p1-x11-max-displays.patch +Patch0022: 0022-openssh-7.2p2-s390-closefrom.patch # Pass inetd flags for SELinux down to openbsd compat level -Patch0026: 0026-openssh-7.6p1-cleanup-selinux.patch +Patch0023: 0023-openssh-7.6p1-cleanup-selinux.patch # Sandbox adjustments for s390 and audit -Patch0027: 0027-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 +Patch0024: 0024-openssh-7.5p1-sandbox.patch # Unbreak scp between two IPv6 hosts (#1620333) -Patch0029: 0029-openssh-7.8p1-scp-ipv6.patch +Patch0025: 0025-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 +Patch0026: 0026-openssh-8.0p1-crypto-policies.patch # Use OpenSSL KDF (#1631761) -Patch0031: 0031-openssh-8.0p1-openssl-kdf.patch +Patch0027: 0027-openssh-8.0p1-openssl-kdf.patch # sk-dummy.so built with -fvisibility=hidden does not work -Patch0032: 0032-openssh-8.2p1-visibility.patch +Patch0028: 0028-openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 -Patch0033: 0033-openssh-8.2p1-x11-without-ipv6.patch +Patch0029: 0029-openssh-8.2p1-x11-without-ipv6.patch # sshd provides PAM an incorrect error code (#1879503) -Patch0034: 0034-openssh-8.0p1-preserve-pam-errors.patch +Patch0030: 0030-openssh-8.0p1-preserve-pam-errors.patch # Implement kill switch for SCP protocol -Patch0035: 0035-openssh-8.7p1-scp-kill-switch.patch +Patch0031: 0031-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 +Patch0032: 0032-openssh-8.7p1-recursive-scp.patch # Downstream alias for MinRSABits -Patch0037: 0037-openssh-8.7p1-minrsabits.patch +Patch0033: 0033-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 +Patch0034: 0034-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 +Patch0035: 0035-openssh-7.6p1-audit.patch # Audit race condition in forked child (#1310684) -Patch0040: 0040-openssh-7.1p2-audit-race-condition.patch +Patch0036: 0036-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 +Patch0037: 0037-openssh-9.0p1-audit-log.patch +Patch0038: 0038-openssh-7.7p1-fips.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 +Patch0039: 0039-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 +Patch0040: 0040-openssh-8.7p1-negotiate-supported-algs.patch +Patch0041: 0041-openssh-9.0p1-evp-fips-kex.patch +Patch0042: 0042-openssh-8.7p1-nohostsha1proof.patch +Patch0043: 0043-openssh-9.9p1-separate-keysign.patch +Patch0044: 0044-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 +Patch0045: 0045-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 +Patch0046: 0046-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 +Patch0047: 0047-Ignore-bad-hostkeys-in-known_hosts-file.patch # https://github.com/openssh/openssh-portable/pull/500 -Patch0053: 0053-support-authentication-indicators-in-GSSAPI.patch - +Patch0048: 0048-support-authentication-indicators-in-GSSAPI.patch +Patch0049: 0049-NIST-curves-hybrid-KEX-implementation.patch +# landed upstream, to be removed after 10.3 +Patch0050: 0050-Provide-a-way-to-disable-GSSAPIDelegateCredentials-s.patch +# Move MAX_DISPLAYS to a configuration option (#1341302) +Patch0051: 0051-openssh-7.3p1-x11-max-displays.patch +# PKCS#11 URIs (upstream #2817, seriously reworked on rebasing to 10.2) +# https://github.com/Jakuje/openssh-portable/commits/jjelen-pkcs11 +Patch0052: 0052-openssh-10.2p1-pkcs11-uri.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=2581 -Patch1000: 1000-openssh-coverity.patch +Patch1000: 1000-openssh-6.7p1-coverity.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 @@ -354,7 +344,6 @@ fi --with-ipaddr-display \ --with-pie=no \ --without-hardening `# The hardening flags are configured by system` \ - --with-systemd \ --with-default-pkcs11-provider=yes \ --with-security-key-builtin=yes \ --with-pam \ @@ -586,6 +575,24 @@ test -f %{sysconfig_anaconda} && \ %attr(0755,root,root) %{_libdir}/sshtest/sk-dummy.so %changelog +* Wed Dec 17 2025 Dmitry Belyavskiy - 10.2p1-1 +- Rebase to OpenSSH 10.2p1 + +* Wed Dec 10 2025 Pavol Žáčik - 10.0p1-10 +- Update gssapi-keyex patch to not abort KEX without hostkey + +* Mon Dec 01 2025 Dmitry Belyavskiy - 10.0p1-9 +- rebuilt + +* Mon Nov 03 2025 Dmitry Belyavskiy - 10.0p1-8 +- Implement mlkem768nistp256-sha256 and mlkem1024nistp384-sha384 KEX methods + +* Mon Sep 15 2025 Dmitry Belyavskiy - 10.0p1-7 +- rebuilt + +* Thu Aug 28 2025 Dmitry Belyavskiy - 10.0p1-6 +- Enable GSS KEX in FIPS mode + * Thu Jul 24 2025 Fedora Release Engineering - 10.0p1-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index 10b461b..318e485 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-10.2p1.tar.gz) = 66f3dd646179e71aaf41c33b6f14a207dc873d71d24f11c130a89dee317ee45398b818e5b94887b5913240964a38630d7bca3e481e0f1eff2e41d9e1cfdbdfc5 +SHA512 (openssh-10.2p1.tar.gz.asc) = f1f71700b1b0b2117aed505488b98b7ebb51ce26e53184b08df0b07aa2c5a1e54dc4d3cbcbe871b5ad849a2a0e22b02af318ff22a68c980ab53b04be03c9bf3c SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21