diff --git a/.gitignore b/.gitignore index 98996cc..c400ff6 100644 --- a/.gitignore +++ b/.gitignore @@ -66,5 +66,3 @@ 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 0377e8c..c08e414 100644 --- a/0001-openssh-7.8p1-role-mls.patch +++ b/0001-openssh-7.8p1-role-mls.patch @@ -1,7 +1,7 @@ -From b6875ceaca4be9e0de0d6d260d8fcff1772f5fb5 Mon Sep 17 00:00:00 2001 +From 95f4e30195382c3df7104c2ad3e5e9953f8ad554 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 01/53] openssh-7.8p1-role-mls +Subject: [PATCH 01/50] openssh-7.8p1-role-mls --- auth-pam.c | 2 +- @@ -26,10 +26,10 @@ Subject: [PATCH 01/53] 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 5591f094e..70bcae83a 100644 +index 13c0a792..b4100ea1 100644 --- a/auth-pam.c +++ b/auth-pam.c -@@ -1261,7 +1261,7 @@ is_pam_session_open(void) +@@ -1238,7 +1238,7 @@ is_pam_session_open(void) * during the ssh authentication process. */ int @@ -39,7 +39,7 @@ index 5591f094e..70bcae83a 100644 int ret = 1; char *compound; diff --git a/auth-pam.h b/auth-pam.h -index 8d801c689..9dd7ae078 100644 +index 8d801c68..9dd7ae07 100644 --- a/auth-pam.h +++ b/auth-pam.h @@ -33,7 +33,7 @@ u_int do_pam_account(void); @@ -52,7 +52,7 @@ index 8d801c689..9dd7ae078 100644 char ** fetch_pam_child_environment(void); void free_pam_environment(char **); diff --git a/auth.h b/auth.h -index 98bb23d4c..83d07ae8b 100644 +index 98bb23d4..83d07ae8 100644 --- a/auth.h +++ b/auth.h @@ -65,6 +65,9 @@ struct Authctxt { @@ -66,7 +66,7 @@ index 98bb23d4c..83d07ae8b 100644 /* Method lists for multiple authentication */ char **auth_methods; /* modified from server config */ diff --git a/auth2-gss.c b/auth2-gss.c -index 75eb4e3a3..f7898ab3e 100644 +index 75eb4e3a..f7898ab3 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -284,6 +284,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) @@ -102,7 +102,7 @@ index 75eb4e3a3..f7898ab3e 100644 authctxt->postponed = 0; diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index 9d8b860eb..976484fc5 100644 +index eb21479a..a3be6e49 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 9d8b860eb..976484fc5 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 15ad3000c..c326a69ba 100644 +index aa24fda0..267a27d2 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c -@@ -204,9 +204,16 @@ userauth_pubkey(struct ssh *ssh, const char *method) +@@ -206,9 +206,16 @@ userauth_pubkey(struct ssh *ssh, const char *method) goto done; } /* reconstruct packet */ @@ -146,7 +146,7 @@ index 15ad3000c..c326a69ba 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 b9bb46f59..1345d3257 100644 +index 82f6e621..5ba45c12 100644 --- a/auth2.c +++ b/auth2.c @@ -271,6 +271,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) @@ -186,10 +186,10 @@ index b9bb46f59..1345d3257 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 ce77ec943..5bed34735 100644 +index dd0bd032..c932f9bb 100644 --- a/misc.c +++ b/misc.c -@@ -822,6 +822,7 @@ char * +@@ -806,6 +806,7 @@ char * colon(char *cp) { int flag = 0; @@ -197,7 +197,7 @@ index ce77ec943..5bed34735 100644 if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -837,6 +838,13 @@ colon(char *cp) +@@ -821,6 +822,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -212,10 +212,10 @@ index ce77ec943..5bed34735 100644 return NULL; } diff --git a/monitor.c b/monitor.c -index a9e854bec..85dc1b1b7 100644 +index 2179553d..02b3eaaa 100644 --- a/monitor.c +++ b/monitor.c -@@ -110,6 +110,9 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); +@@ -120,6 +120,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 a9e854bec..85dc1b1b7 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 *); -@@ -184,6 +187,9 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -194,6 +197,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 a9e854bec..85dc1b1b7 100644 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -919,6 +925,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -912,6 +918,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 a9e854bec..85dc1b1b7 100644 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM -@@ -993,6 +1002,26 @@ key_base_type_match(const char *method, const struct sshkey *key, +@@ -986,6 +995,26 @@ key_base_type_match(const char *method, const struct sshkey *key, return found; } @@ -272,7 +272,7 @@ index a9e854bec..85dc1b1b7 100644 int mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { -@@ -1364,7 +1393,7 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) +@@ -1358,7 +1387,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 a9e854bec..85dc1b1b7 100644 size_t len; u_char type; int hostbound = 0, r, fail = 0; -@@ -1395,6 +1424,8 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen) +@@ -1389,6 +1418,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 a9e854bec..85dc1b1b7 100644 xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1445,7 +1476,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, +@@ -1439,7 +1470,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, { struct sshbuf *b; const u_char *p; @@ -299,7 +299,7 @@ index a9e854bec..85dc1b1b7 100644 size_t len; int r, fail = 0; u_char type; -@@ -1466,6 +1497,8 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen, +@@ -1460,6 +1491,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 a9e854bec..85dc1b1b7 100644 authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); diff --git a/monitor.h b/monitor.h -index 3f8a9bea3..9dcd9c293 100644 +index 3f8a9bea..9dcd9c29 100644 --- a/monitor.h +++ b/monitor.h @@ -56,6 +56,10 @@ enum monitor_reqtype { @@ -324,10 +324,10 @@ index 3f8a9bea3..9dcd9c293 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 33494b73f..347eb6870 100644 +index bd900b2f..ef3ab1b1 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -453,6 +453,27 @@ mm_inform_authserv(char *service, char *style) +@@ -442,6 +442,27 @@ mm_inform_authserv(char *service, char *style) sshbuf_free(m); } @@ -356,10 +356,10 @@ index 33494b73f..347eb6870 100644 int mm_auth_password(struct ssh *ssh, char *password) diff --git a/monitor_wrap.h b/monitor_wrap.h -index c87295388..9b42ddbcb 100644 +index 7134afee..38a280c8 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -50,6 +50,9 @@ int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, +@@ -46,6 +46,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 c87295388..9b42ddbcb 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 53c87db6d..39531ae77 100644 +index 1d549954..78e6fa5b 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in -@@ -102,7 +102,8 @@ PORTS= port-aix.o \ +@@ -100,7 +100,8 @@ PORTS= port-aix.o \ port-prngd.o \ port-solaris.o \ port-net.o \ @@ -385,7 +385,7 @@ index 53c87db6d..39531ae77 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 000000000..b9fbe38b7 +index 00000000..b9fbe38b --- /dev/null +++ b/openbsd-compat/port-linux-sshd.c @@ -0,0 +1,420 @@ @@ -810,7 +810,7 @@ index 000000000..b9fbe38b7 +#endif + diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index c1d54f38d..7426f6f79 100644 +index c1d54f38..7426f6f7 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -109,37 +109,6 @@ ssh_selinux_getctxbyname(char *pwname) @@ -865,7 +865,7 @@ index c1d54f38d..7426f6f79 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 959430de1..055c825e4 100644 +index 959430de..055c825e 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -20,9 +20,10 @@ @@ -881,7 +881,7 @@ index 959430de1..055c825e4 100644 #ifdef LINUX_OOM_ADJUST diff --git a/platform.c b/platform.c -index fd1a7a7c2..bcf1b0491 100644 +index 4c4fe57e..1bfb4bea 100644 --- a/platform.c +++ b/platform.c @@ -140,7 +140,7 @@ platform_setusercontext_post_groups(struct passwd *pw) @@ -894,10 +894,10 @@ index fd1a7a7c2..bcf1b0491 100644 } diff --git a/sshd-session.c b/sshd-session.c -index 8979f743b..cb4b0523d 100644 +index c64eb29f..74d2cbc7 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1306,6 +1306,9 @@ main(int ac, char **av) +@@ -1328,6 +1328,9 @@ main(int ac, char **av) restore_uid(); } #endif @@ -908,5 +908,5 @@ index 8979f743b..cb4b0523d 100644 if (options.use_pam) { do_pam_setcred(); -- -2.52.0 +2.49.0 diff --git a/0002-openssh-6.6p1-privsep-selinux.patch b/0002-openssh-6.6p1-privsep-selinux.patch new file mode 100644 index 0000000..32d3c64 --- /dev/null +++ b/0002-openssh-6.6p1-privsep-selinux.patch @@ -0,0 +1,144 @@ +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/0002-openssh-6.6p1-keycat.patch b/0003-openssh-6.6p1-keycat.patch similarity index 90% rename from 0002-openssh-6.6p1-keycat.patch rename to 0003-openssh-6.6p1-keycat.patch index b196636..b46b378 100644 --- a/0002-openssh-6.6p1-keycat.patch +++ b/0003-openssh-6.6p1-keycat.patch @@ -1,24 +1,24 @@ -From 5f16fff915643a515adbbd2e0cd12717938e3570 Mon Sep 17 00:00:00 2001 +From 5e35e18a419a5a66b6e1cb2b98beaaf4d9db0dc6 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 02/53] openssh-6.6p1-keycat +Subject: [PATCH 03/50] openssh-6.6p1-keycat --- HOWTO.ssh-keycat | 12 ++ Makefile.in | 8 +- configure.ac | 6 + misc.c | 7 + - openbsd-compat/port-linux-sshd.c | 42 +++++- - openbsd-compat/port-linux.h | 1 + + openbsd-compat/port-linux-sshd.c | 44 +++++- + openbsd-compat/port-linux.h | 2 + platform.c | 2 +- ssh-keycat.c | 241 +++++++++++++++++++++++++++++++ - 8 files changed, 312 insertions(+), 7 deletions(-) + 8 files changed, 314 insertions(+), 8 deletions(-) create mode 100644 HOWTO.ssh-keycat create mode 100644 ssh-keycat.c diff --git a/HOWTO.ssh-keycat b/HOWTO.ssh-keycat new file mode 100644 -index 000000000..630ec628c +index 00000000..630ec628 --- /dev/null +++ b/HOWTO.ssh-keycat @@ -0,0 +1,12 @@ @@ -35,7 +35,7 @@ index 000000000..630ec628c + + diff --git a/Makefile.in b/Makefile.in -index ba17a79f0..a3a495c1b 100644 +index 4617cebc..438efc51 100644 --- a/Makefile.in +++ b/Makefile.in @@ -23,6 +23,7 @@ SSH_PROGRAM=@bindir@/ssh @@ -46,7 +46,7 @@ index ba17a79f0..a3a495c1b 100644 SSHD_SESSION=$(libexecdir)/sshd-session SSHD_AUTH=$(libexecdir)/sshd-auth SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper -@@ -58,6 +59,7 @@ CHANNELLIBS=@CHANNELLIBS@ +@@ -57,6 +58,7 @@ CHANNELLIBS=@CHANNELLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ SSHDLIBS=@SSHDLIBS@ @@ -54,16 +54,16 @@ index ba17a79f0..a3a495c1b 100644 LIBEDIT=@LIBEDIT@ LIBFIDO2=@LIBFIDO2@ LIBWTMPDB=@LIBWTMPDB@ -@@ -75,7 +77,7 @@ MKDIR_P=@MKDIR_P@ +@@ -74,7 +76,7 @@ MKDIR_P=@MKDIR_P@ .SUFFIXES: .lo -TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE) +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) $(SK_STANDALONE) - LIBOPENSSH_OBJS=\ - ssh_api.o \ -@@ -252,6 +254,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS) + XMSS_OBJS=\ + ssh-xmss.o \ +@@ -260,6 +262,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS) ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) @@ -73,7 +73,7 @@ index ba17a79f0..a3a495c1b 100644 ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS) -@@ -439,6 +444,7 @@ install-files: +@@ -447,6 +452,7 @@ install-files: $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) @@ -82,10 +82,10 @@ index ba17a79f0..a3a495c1b 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 db5211013..fd632a5a8 100644 +index ee77a048..d546788c 100644 --- a/configure.ac +++ b/configure.ac -@@ -3648,6 +3648,7 @@ AC_ARG_WITH([pam], +@@ -3566,6 +3566,7 @@ AC_ARG_WITH([pam], PAM_MSG="yes" SSHDLIBS="$SSHDLIBS -lpam" @@ -93,7 +93,7 @@ index db5211013..fd632a5a8 100644 AC_DEFINE([USE_PAM], [1], [Define if you want to enable PAM support]) -@@ -3658,6 +3659,7 @@ AC_ARG_WITH([pam], +@@ -3576,6 +3577,7 @@ AC_ARG_WITH([pam], ;; *) SSHDLIBS="$SSHDLIBS -ldl" @@ -101,7 +101,7 @@ index db5211013..fd632a5a8 100644 ;; esac fi -@@ -4883,6 +4885,7 @@ AC_ARG_WITH([selinux], +@@ -4801,6 +4803,7 @@ AC_ARG_WITH([selinux], fi ] ) AC_SUBST([SSHDLIBS]) @@ -109,7 +109,7 @@ index db5211013..fd632a5a8 100644 # Check whether user wants Kerberos 5 support KRB5_MSG="no" -@@ -5894,6 +5897,9 @@ fi +@@ -5812,6 +5815,9 @@ fi if test ! -z "${SSHDLIBS}"; then echo " +for sshd: ${SSHDLIBS}" fi @@ -120,10 +120,10 @@ index db5211013..fd632a5a8 100644 echo "" diff --git a/misc.c b/misc.c -index 5bed34735..7e27a38d1 100644 +index c932f9bb..1e31acc9 100644 --- a/misc.c +++ b/misc.c -@@ -2921,6 +2921,13 @@ subprocess(const char *tag, const char *command, +@@ -2897,6 +2897,13 @@ subprocess(const char *tag, const char *command, error("%s: dup2: %s", tag, strerror(errno)); _exit(1); } @@ -138,7 +138,7 @@ index 5bed34735..7e27a38d1 100644 execve(av[0], av, env); else diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index b9fbe38b7..4d56745f7 100644 +index dfafc622..8c5fc1fe 100644 --- a/openbsd-compat/port-linux-sshd.c +++ b/openbsd-compat/port-linux-sshd.c @@ -52,6 +52,20 @@ extern ServerOptions options; @@ -225,20 +225,32 @@ index b9fbe38b7..4d56745f7 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 055c825e4..c004071d1 100644 +index 498d242a..1b745a76 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h -@@ -24,6 +24,7 @@ void ssh_selinux_change_context(const char *); +@@ -23,8 +23,10 @@ void ssh_selinux_setup_pty(char *, const char *); + void ssh_selinux_change_context(const char *); void ssh_selinux_setfscreatecon(const char *); ++int sshd_selinux_enabled(void); + void sshd_selinux_copy_context(void); void sshd_selinux_setup_exec_context(char *); +int sshd_selinux_setup_env_variables(void); #endif #ifdef LINUX_OOM_ADJUST diff --git a/platform.c b/platform.c -index bcf1b0491..c92a0cba6 100644 +index 1bfb4bea..0d12f311 100644 --- a/platform.c +++ b/platform.c @@ -55,7 +55,7 @@ platform_setusercontext(struct passwd *pw) @@ -252,7 +264,7 @@ index bcf1b0491..c92a0cba6 100644 #ifdef USE_SOLARIS_PROJECTS diff --git a/ssh-keycat.c b/ssh-keycat.c new file mode 100644 -index 000000000..5678be079 +index 00000000..5678be07 --- /dev/null +++ b/ssh-keycat.c @@ -0,0 +1,241 @@ @@ -498,5 +510,5 @@ index 000000000..5678be079 + return ev; +} -- -2.52.0 +2.49.0 diff --git a/0003-openssh-6.6p1-allow-ip-opts.patch b/0004-openssh-6.6p1-allow-ip-opts.patch similarity index 86% rename from 0003-openssh-6.6p1-allow-ip-opts.patch rename to 0004-openssh-6.6p1-allow-ip-opts.patch index ea11b6c..ef15fbf 100644 --- a/0003-openssh-6.6p1-allow-ip-opts.patch +++ b/0004-openssh-6.6p1-allow-ip-opts.patch @@ -1,17 +1,17 @@ -From 7ffeef7e8218c544b6f4a09c5d43e9b748de5a5f Mon Sep 17 00:00:00 2001 +From 28333f1dfe68b0ffc80c2a4799759587b4c32d3e Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 03/53] openssh-6.6p1-allow-ip-opts +Subject: [PATCH 04/50] openssh-6.6p1-allow-ip-opts --- sshd-session.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/sshd-session.c b/sshd-session.c -index cb4b0523d..1c72e664a 100644 +index 4a148db4..a365f26f 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -754,12 +754,32 @@ check_ip_options(struct ssh *ssh) +@@ -778,12 +778,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 cb4b0523d..1c72e664a 100644 #endif /* IP_OPTIONS */ } -- -2.52.0 +2.49.0 diff --git a/0004-openssh-5.9p1-ipv6man.patch b/0005-openssh-5.9p1-ipv6man.patch similarity index 86% rename from 0004-openssh-5.9p1-ipv6man.patch rename to 0005-openssh-5.9p1-ipv6man.patch index 6ec8afc..909b988 100644 --- a/0004-openssh-5.9p1-ipv6man.patch +++ b/0005-openssh-5.9p1-ipv6man.patch @@ -1,7 +1,7 @@ -From f653eed40e15c4c521ce683a604b46ed81cade6a Mon Sep 17 00:00:00 2001 +From 388be633842a9f3e4b0a76fe40cf7035912a913a Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 04/53] openssh-5.9p1-ipv6man +Subject: [PATCH 05/50] openssh-5.9p1-ipv6man --- ssh.1 | 2 ++ @@ -9,7 +9,7 @@ Subject: [PATCH 04/53] openssh-5.9p1-ipv6man 2 files changed, 4 insertions(+) diff --git a/ssh.1 b/ssh.1 -index 697f4e42a..db92ac9af 100644 +index 697f4e42..db92ac9a 100644 --- a/ssh.1 +++ b/ssh.1 @@ -1663,6 +1663,8 @@ manual page for more information. @@ -22,7 +22,7 @@ index 697f4e42a..db92ac9af 100644 .Xr scp 1 , .Xr sftp 1 , diff --git a/sshd.8 b/sshd.8 -index 7fbca776a..0226a8303 100644 +index 08ebf53a..2aa73271 100644 --- a/sshd.8 +++ b/sshd.8 @@ -1018,6 +1018,8 @@ concurrently for different ports, this contains the process ID of the one @@ -35,5 +35,5 @@ index 7fbca776a..0226a8303 100644 .Xr scp 1 , .Xr sftp 1 , -- -2.52.0 +2.49.0 diff --git a/0005-openssh-5.8p2-sigpipe.patch b/0006-openssh-5.8p2-sigpipe.patch similarity index 70% rename from 0005-openssh-5.8p2-sigpipe.patch rename to 0006-openssh-5.8p2-sigpipe.patch index a2a3714..5bf31bc 100644 --- a/0005-openssh-5.8p2-sigpipe.patch +++ b/0006-openssh-5.8p2-sigpipe.patch @@ -1,17 +1,17 @@ -From 6ac14fb92cf0d0676f19282f30b9e427025be31b Mon Sep 17 00:00:00 2001 +From 80359feb76fd8061b5ce18f73451d7b9db0c2477 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 05/53] openssh-5.8p2-sigpipe +Subject: [PATCH 06/50] openssh-5.8p2-sigpipe --- ssh-keyscan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ssh-keyscan.c b/ssh-keyscan.c -index f9788114d..11618ae8a 100644 +index 3436c0b5..9f76ad22 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c -@@ -776,6 +776,9 @@ main(int argc, char **argv) +@@ -798,6 +798,9 @@ main(int argc, char **argv) if (maxfd > fdlim_get(0)) fdlim_set(maxfd); fdcon = xcalloc(maxfd, sizeof(con)); @@ -22,5 +22,5 @@ index f9788114d..11618ae8a 100644 for (j = 0; j < maxfd; j++) read_wait[j].fd = -1; -- -2.52.0 +2.49.0 diff --git a/0006-openssh-7.2p2-x11.patch b/0007-openssh-7.2p2-x11.patch similarity index 84% rename from 0006-openssh-7.2p2-x11.patch rename to 0007-openssh-7.2p2-x11.patch index dceef7b..2f72f9a 100644 --- a/0006-openssh-7.2p2-x11.patch +++ b/0007-openssh-7.2p2-x11.patch @@ -1,17 +1,17 @@ -From d6dc5be6e969ecffe30b9972706b3c92d930d81f Mon Sep 17 00:00:00 2001 +From cf6d48305cf6601448ea7a0d96ae825cbbbf0a2c Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 06/53] openssh-7.2p2-x11 +Subject: [PATCH 07/50] openssh-7.2p2-x11 --- channels.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/channels.c b/channels.c -index 80014ff34..5ce6bd400 100644 +index bfe2e3b2..d46531ce 100644 --- a/channels.c +++ b/channels.c -@@ -5169,11 +5169,13 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +@@ -5098,11 +5098,13 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, } static int @@ -26,7 +26,7 @@ index 80014ff34..5ce6bd400 100644 sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { error("socket: %.100s", strerror(errno)); -@@ -5181,11 +5183,12 @@ connect_local_xsocket_path(const char *pathname) +@@ -5110,11 +5112,12 @@ connect_local_xsocket_path(const char *pathname) } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; @@ -42,7 +42,7 @@ index 80014ff34..5ce6bd400 100644 return -1; } -@@ -5193,8 +5196,18 @@ static int +@@ -5122,8 +5125,18 @@ static int connect_local_xsocket(u_int dnr) { char buf[1024]; @@ -64,5 +64,5 @@ index 80014ff34..5ce6bd400 100644 #ifdef __APPLE__ -- -2.52.0 +2.49.0 diff --git a/0007-openssh-5.1p1-askpass-progress.patch b/0008-openssh-5.1p1-askpass-progress.patch similarity index 94% rename from 0007-openssh-5.1p1-askpass-progress.patch rename to 0008-openssh-5.1p1-askpass-progress.patch index 66b351e..f7ca382 100644 --- a/0007-openssh-5.1p1-askpass-progress.patch +++ b/0008-openssh-5.1p1-askpass-progress.patch @@ -1,14 +1,14 @@ -From c62cd7ce2539c1eac6d0133c07441c617cbc7bc3 Mon Sep 17 00:00:00 2001 +From 6b2a33044583e892badb9ac86cd2c6252b1a532f Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 07/53] openssh-5.1p1-askpass-progress +Subject: [PATCH 08/50] openssh-5.1p1-askpass-progress --- contrib/gnome-ssh-askpass2.c | 39 +++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c -index a62f98152..cb7152dc8 100644 +index a62f9815..cb7152dc 100644 --- a/contrib/gnome-ssh-askpass2.c +++ b/contrib/gnome-ssh-askpass2.c @@ -58,6 +58,7 @@ @@ -92,5 +92,5 @@ index a62f98152..cb7152dc8 100644 /* Grab focus */ -- -2.52.0 +2.49.0 diff --git a/0008-openssh-4.3p2-askpass-grab-info.patch b/0009-openssh-4.3p2-askpass-grab-info.patch similarity index 87% rename from 0008-openssh-4.3p2-askpass-grab-info.patch rename to 0009-openssh-4.3p2-askpass-grab-info.patch index 8108482..8a7cf9e 100644 --- a/0008-openssh-4.3p2-askpass-grab-info.patch +++ b/0009-openssh-4.3p2-askpass-grab-info.patch @@ -1,14 +1,14 @@ -From d124ab0f6eea910dc5f03cdd808f6fa792bf2b7a Mon Sep 17 00:00:00 2001 +From 710ce53fdf1d32a0629fce2e42fb49d407e2b06c Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 08/53] openssh-4.3p2-askpass-grab-info +Subject: [PATCH 09/50] openssh-4.3p2-askpass-grab-info --- contrib/gnome-ssh-askpass2.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c -index cb7152dc8..bbe93d838 100644 +index cb7152dc..bbe93d83 100644 --- a/contrib/gnome-ssh-askpass2.c +++ b/contrib/gnome-ssh-askpass2.c @@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_window, const char *what) @@ -27,5 +27,5 @@ index cb7152dc8..bbe93d838 100644 gtk_dialog_run(GTK_DIALOG(err)); -- -2.52.0 +2.49.0 diff --git a/0009-openssh-8.7p1-redhat.patch b/0010-openssh-8.7p1-redhat.patch similarity index 91% rename from 0009-openssh-8.7p1-redhat.patch rename to 0010-openssh-8.7p1-redhat.patch index 8e75aa5..cb3d140 100644 --- a/0009-openssh-8.7p1-redhat.patch +++ b/0010-openssh-8.7p1-redhat.patch @@ -1,7 +1,7 @@ -From c76607384ff077ba1c45759e749562cccaeaa335 Mon Sep 17 00:00:00 2001 +From 5f21983f6472b26693babea4d6ca6b95a7dc7b05 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 09/53] openssh-8.7p1-redhat +Subject: [PATCH 10/50] openssh-8.7p1-redhat --- ssh_config | 7 +++++++ @@ -17,10 +17,10 @@ Subject: [PATCH 09/53] openssh-8.7p1-redhat create mode 100644 sshd_config_redhat_cp diff --git a/ssh_config b/ssh_config -index 238a0c5e3..d9324c957 100644 +index cc566356..18169187 100644 --- a/ssh_config +++ b/ssh_config -@@ -43,3 +43,10 @@ +@@ -44,3 +44,10 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h # UserKnownHostsFile ~/.ssh/known_hosts.d/%k @@ -33,7 +33,7 @@ index 238a0c5e3..d9324c957 100644 +Include /etc/ssh/ssh_config.d/*.conf diff --git a/ssh_config_redhat b/ssh_config_redhat new file mode 100644 -index 000000000..8b1b59021 +index 00000000..8b1b5902 --- /dev/null +++ b/ssh_config_redhat @@ -0,0 +1,18 @@ @@ -56,7 +56,7 @@ index 000000000..8b1b59021 +# Uncomment this if you want to use .local domain +# Host *.local diff --git a/sshd_config b/sshd_config -index 0f4a3a724..608203e4b 100644 +index 0f4a3a72..608203e4 100644 --- a/sshd_config +++ b/sshd_config @@ -10,6 +10,14 @@ @@ -75,7 +75,7 @@ index 0f4a3a724..608203e4b 100644 #AddressFamily any #ListenAddress 0.0.0.0 diff --git a/sshd_config.0 b/sshd_config.0 -index c63d729a9..8c5217c0b 100644 +index 2f77b4f4..49349bb3 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -1219,9 +1219,9 @@ DESCRIPTION @@ -92,10 +92,10 @@ index c63d729a9..8c5217c0b 100644 TCPKeepAlive Specifies whether the system should send TCP keepalive messages diff --git a/sshd_config.5 b/sshd_config.5 -index 6ae606f1e..aa9f0af76 100644 +index c0771737..035a50c8 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1941,7 +1941,7 @@ By default no subsystems are defined. +@@ -1942,7 +1942,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 6ae606f1e..aa9f0af76 100644 .It Cm TCPKeepAlive diff --git a/sshd_config_redhat b/sshd_config_redhat new file mode 100644 -index 000000000..993a28d52 +index 00000000..993a28d5 --- /dev/null +++ b/sshd_config_redhat @@ -0,0 +1,18 @@ @@ -130,7 +130,7 @@ index 000000000..993a28d52 + diff --git a/sshd_config_redhat_cp b/sshd_config_redhat_cp new file mode 100644 -index 000000000..1d592d13f +index 00000000..1d592d13 --- /dev/null +++ b/sshd_config_redhat_cp @@ -0,0 +1,7 @@ @@ -142,5 +142,5 @@ index 000000000..1d592d13f +Include /etc/crypto-policies/back-ends/opensshserver.config + -- -2.52.0 +2.49.0 diff --git a/0010-openssh-7.8p1-UsePAM-warning.patch b/0011-openssh-7.8p1-UsePAM-warning.patch similarity index 81% rename from 0010-openssh-7.8p1-UsePAM-warning.patch rename to 0011-openssh-7.8p1-UsePAM-warning.patch index 521abe4..76ee115 100644 --- a/0010-openssh-7.8p1-UsePAM-warning.patch +++ b/0011-openssh-7.8p1-UsePAM-warning.patch @@ -1,7 +1,7 @@ -From 5f6dbc98a184ce485aef90321ae9fc1ba45293f8 Mon Sep 17 00:00:00 2001 +From 56b8d082bc9e25a77b5227d576f27088446c6fb9 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 10/53] openssh-7.8p1-UsePAM-warning +Subject: [PATCH 11/50] openssh-7.8p1-UsePAM-warning --- sshd-session.c | 4 ++++ @@ -9,10 +9,10 @@ Subject: [PATCH 10/53] openssh-7.8p1-UsePAM-warning 2 files changed, 6 insertions(+) diff --git a/sshd-session.c b/sshd-session.c -index 1c72e664a..9804dc334 100644 +index a365f26f..a70b36c9 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1103,6 +1103,10 @@ main(int ac, char **av) +@@ -1127,6 +1127,10 @@ main(int ac, char **av) "enabled authentication methods"); } @@ -24,7 +24,7 @@ index 1c72e664a..9804dc334 100644 if (options.moduli_file != NULL) dh_set_moduli_file(options.moduli_file); diff --git a/sshd_config b/sshd_config -index 608203e4b..48af6321b 100644 +index 608203e4..48af6321 100644 --- a/sshd_config +++ b/sshd_config @@ -89,6 +89,8 @@ AuthorizedKeysFile .ssh/authorized_keys @@ -37,5 +37,5 @@ index 608203e4b..48af6321b 100644 #AllowAgentForwarding yes -- -2.52.0 +2.49.0 diff --git a/0011-openssh-9.6p1-gssapi-keyex.patch b/0012-openssh-9.6p1-gssapi-keyex.patch similarity index 94% rename from 0011-openssh-9.6p1-gssapi-keyex.patch rename to 0012-openssh-9.6p1-gssapi-keyex.patch index 2e5b723..95a4325 100644 --- a/0011-openssh-9.6p1-gssapi-keyex.patch +++ b/0012-openssh-9.6p1-gssapi-keyex.patch @@ -1,7 +1,7 @@ -From c992408da3ca7aeae129c731c7753019a16ed226 Mon Sep 17 00:00:00 2001 +From f19e9dcf94b5d38c701626886cb4c71314fd026d Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 11/53] openssh-9.6p1-gssapi-keyex +Subject: [PATCH 12/50] openssh-9.6p1-gssapi-keyex --- Makefile.in | 7 +- @@ -13,10 +13,10 @@ Subject: [PATCH 11/53] openssh-9.6p1-gssapi-keyex canohost.h | 3 + clientloop.c | 12 + configure.ac | 24 ++ - gss-genr.c | 312 ++++++++++++++++++++- + gss-genr.c | 302 ++++++++++++++++++++- gss-serv-krb5.c | 97 ++++++- gss-serv.c | 200 ++++++++++++-- - kex-names.c | 60 +++- + kex-names.c | 62 ++++- kex.c | 35 ++- kex.h | 34 +++ kexdh.c | 10 + @@ -29,7 +29,7 @@ Subject: [PATCH 11/53] openssh-9.6p1-gssapi-keyex monitor_wrap.h | 4 +- readconf.c | 70 +++++ readconf.h | 6 + - servconf.c | 46 ++++ + servconf.c | 47 ++++ servconf.h | 3 + session.c | 10 +- ssh-gss.h | 64 ++++- @@ -45,23 +45,23 @@ Subject: [PATCH 11/53] openssh-9.6p1-gssapi-keyex sshd_config.5 | 31 +++ sshkey.c | 72 ++++- sshkey.h | 1 + - 41 files changed, 2993 insertions(+), 76 deletions(-) + 41 files changed, 2985 insertions(+), 77 deletions(-) create mode 100644 kexgssc.c create mode 100644 kexgsss.c diff --git a/Makefile.in b/Makefile.in -index a3a495c1b..a36eb82ed 100644 +index 438efc51..78f65948 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -108,6 +108,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -117,6 +117,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o misc-agent.o + sshbuf-io.o -@@ -131,7 +132,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ +@@ -138,7 +139,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ auth2-chall.o groupaccess.o \ auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ @@ -70,7 +70,7 @@ index a3a495c1b..a36eb82ed 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 \ -@@ -143,7 +144,7 @@ SSHD_AUTH_OBJS=sshd-auth.o \ +@@ -150,7 +151,7 @@ SSHD_AUTH_OBJS=sshd-auth.o \ serverloop.o auth.o auth2.o auth-options.o session.o auth2-chall.o \ groupaccess.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ @@ -79,20 +79,20 @@ index a3a495c1b..a36eb82ed 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 \ -@@ -554,7 +555,7 @@ regress-prep: +@@ -563,7 +564,7 @@ regress-prep: ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile REGRESSLIBS=libssh.a $(LIBCOMPAT) --TESTLIBS=$(LIBS) $(CHANNELLIBS) @TESTLIBS@ -+TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) @TESTLIBS@ +-TESTLIBS=$(LIBS) $(CHANNELLIBS) ++TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ diff --git a/auth.c b/auth.c -index 8d9404743..d25653ee4 100644 +index 9a6e5a31..e4578169 100644 --- a/auth.c +++ b/auth.c -@@ -354,7 +354,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) +@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -103,7 +103,7 @@ index 8d9404743..d25653ee4 100644 break; case PERMIT_FORCED_ONLY: diff --git a/auth2-gss.c b/auth2-gss.c -index f7898ab3e..5b1b9cde3 100644 +index f7898ab3..5b1b9cde 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -51,6 +51,7 @@ @@ -194,7 +194,7 @@ index f7898ab3e..5b1b9cde3 100644 &methodcfg_gssapi, userauth_gssapi, diff --git a/auth2-methods.c b/auth2-methods.c -index 99637a89b..a05908cf3 100644 +index 99637a89..a05908cf 100644 --- a/auth2-methods.c +++ b/auth2-methods.c @@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = { @@ -218,7 +218,7 @@ index 99637a89b..a05908cf3 100644 #endif &methodcfg_passwd, diff --git a/auth2.c b/auth2.c -index 1345d3257..5a4b932a9 100644 +index 5ba45c12..8ec41de2 100644 --- a/auth2.c +++ b/auth2.c @@ -71,6 +71,7 @@ extern Authmethod method_passwd; @@ -238,7 +238,7 @@ index 1345d3257..5a4b932a9 100644 #endif &method_passwd, diff --git a/canohost.c b/canohost.c -index 28f086e5a..875805c99 100644 +index 28f086e5..875805c9 100644 --- a/canohost.c +++ b/canohost.c @@ -35,6 +35,99 @@ @@ -342,7 +342,7 @@ index 28f086e5a..875805c99 100644 ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) { diff --git a/canohost.h b/canohost.h -index 26d62855a..0cadc9f18 100644 +index 26d62855..0cadc9f1 100644 --- a/canohost.h +++ b/canohost.h @@ -15,6 +15,9 @@ @@ -356,10 +356,10 @@ index 26d62855a..0cadc9f18 100644 int get_peer_port(int); char *get_local_ipaddr(int); diff --git a/clientloop.c b/clientloop.c -index 49d048d85..33adf31dc 100644 +index 916fc077..4655f91f 100644 --- a/clientloop.c +++ b/clientloop.c -@@ -107,6 +107,10 @@ +@@ -115,6 +115,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -370,7 +370,7 @@ index 49d048d85..33adf31dc 100644 /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -@@ -1604,6 +1608,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, +@@ -1591,6 +1595,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 49d048d85..33adf31dc 100644 if (conn_in_ready) client_process_net_input(ssh); diff --git a/configure.ac b/configure.ac -index fd632a5a8..adccaebd4 100644 +index d546788c..13c70a98 100644 --- a/configure.ac +++ b/configure.ac -@@ -813,6 +813,30 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +@@ -786,6 +786,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 fd632a5a8..adccaebd4 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 8f1f54afb..f2d6f59e5 100644 +index aa34b71c..3034370c 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -42,9 +42,33 @@ @@ -458,7 +458,7 @@ index 8f1f54afb..f2d6f59e5 100644 /* sshbuf_get for gss_buffer_desc */ int 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) +@@ -60,6 +84,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) return 0; } @@ -527,29 +527,19 @@ index 8f1f54afb..f2d6f59e5 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 ((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); ++ ++ 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) + fatal_fr(r, "digest failed"); -+ } -+ EVP_MD_free(md5); md5 = NULL; -+ EVP_MD_CTX_free(ctx); ctx = NULL; ++ ssh_digest_free(md); ++ md = NULL; + + encoded = xmalloc(ssh_digest_bytes(SSH_DIGEST_MD5) + * 2); @@ -628,7 +618,7 @@ index 8f1f54afb..f2d6f59e5 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 +355,7 @@ ssh_gssapi_build_ctx(Gssctxt **ctx) +@@ -168,6 +345,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; @@ -636,7 +626,7 @@ index 8f1f54afb..f2d6f59e5 100644 } /* Delete our context, providing it has been built correctly */ -@@ -193,6 +381,12 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx) +@@ -193,6 +371,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); @@ -649,7 +639,7 @@ index 8f1f54afb..f2d6f59e5 100644 free(*ctx); *ctx = NULL; -@@ -216,7 +410,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, +@@ -216,7 +400,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, } ctx->major = gss_init_sec_context(&ctx->minor, @@ -658,7 +648,7 @@ index 8f1f54afb..f2d6f59e5 100644 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -245,9 +439,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) +@@ -245,9 +429,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) return (ctx->major); } @@ -702,7 +692,7 @@ index 8f1f54afb..f2d6f59e5 100644 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -255,6 +483,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) +@@ -255,6 +473,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) return (ctx->major); } @@ -722,7 +712,7 @@ index 8f1f54afb..f2d6f59e5 100644 void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context, const struct sshbuf *session_id) -@@ -271,11 +512,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, +@@ -271,11 +502,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, } int @@ -740,7 +730,7 @@ index 8f1f54afb..f2d6f59e5 100644 /* RFC 4462 says we MUST NOT do SPNEGO */ if (oid->length == spnego_oid.length && -@@ -285,6 +531,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -285,6 +521,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); @@ -751,7 +741,7 @@ index 8f1f54afb..f2d6f59e5 100644 if (!GSS_ERROR(major)) { major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -294,10 +544,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) +@@ -294,10 +534,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) GSS_C_NO_BUFFER); } @@ -820,7 +810,7 @@ index 8f1f54afb..f2d6f59e5 100644 + #endif /* GSSAPI */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index a151bc1e4..8d2b677f7 100644 +index a151bc1e..8d2b677f 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -1,7 +1,7 @@ @@ -960,11 +950,11 @@ index a151bc1e4..8d2b677f7 100644 #endif /* KRB5 */ diff --git a/gss-serv.c b/gss-serv.c -index b0e9c3b49..6bac42931 100644 +index 025a118f..a5cca797 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ - /* $OpenBSD: gss-serv.c,v 1.33 2025/09/29 21:30:15 dtucker Exp $ */ + /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1255,7 +1245,7 @@ index b0e9c3b49..6bac42931 100644 /* Privileged */ diff --git a/kex-names.c b/kex-names.c -index a20ce602a..31e395aa2 100644 +index ec840c1f..6c0b7c2b 100644 --- a/kex-names.c +++ b/kex-names.c @@ -45,6 +45,10 @@ @@ -1269,22 +1259,22 @@ index a20ce602a..31e395aa2 100644 struct kexalg { char *name; u_int type; -@@ -90,9 +94,22 @@ static const struct kexalg kexalgs[] = { +@@ -89,15 +93,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, 0, -1, -1, 0 }, + { NULL, 0, -1, -1}, }; +static const struct kexalg gss_kexalgs[] = { +#ifdef GSSAPI -+ { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1, KEX_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_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, ++ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, + { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, -+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256, KEX_NOT_PQ }, -+ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, ++ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, ++ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, +#endif -+ { NULL, 0, -1, -1, 0}, ++ { NULL, 0, -1, -1}, +}; -char * @@ -1292,9 +1282,16 @@ index a20ce602a..31e395aa2 100644 +static char * +kex_alg_list_internal(char sep, const struct kexalg *algs) { - char *ret = NULL; + char *ret = NULL, *tmp; + size_t nlen, rlen = 0; const struct kexalg *k; -@@ -104,6 +121,18 @@ kex_alg_list(char sep) + +- for (k = kexalgs; k->name != NULL; k++) { ++ for (k = algs; k->name != NULL; k++) { + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(k->name); +@@ -112,6 +129,18 @@ kex_alg_list(char sep) return ret; } @@ -1313,7 +1310,7 @@ index a20ce602a..31e395aa2 100644 static const struct kexalg * kex_alg_by_name(const char *name) { -@@ -113,6 +142,10 @@ kex_alg_by_name(const char *name) +@@ -121,6 +150,10 @@ kex_alg_by_name(const char *name) if (strcmp(k->name, name) == 0) return k; } @@ -1324,7 +1321,7 @@ index a20ce602a..31e395aa2 100644 return NULL; } -@@ -336,3 +369,26 @@ kex_assemble_names(char **listp, const char *def, const char *all) +@@ -334,3 +367,26 @@ kex_assemble_names(char **listp, const char *def, const char *all) free(ret); return r; } @@ -1352,10 +1349,10 @@ index a20ce602a..31e395aa2 100644 + return 1; +} diff --git a/kex.c b/kex.c -index 814fad947..9a2ce6d88 100644 +index 6b957e5e..19a56e8e 100644 --- a/kex.c +++ b/kex.c -@@ -295,17 +295,37 @@ static int +@@ -297,17 +297,37 @@ static int kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m) { int r; @@ -1399,7 +1396,7 @@ index 814fad947..9a2ce6d88 100644 (r = sshbuf_put_cstring(m, "0")) != 0) { error_fr(r, "compose"); return r; -@@ -735,6 +755,9 @@ kex_free(struct kex *kex) +@@ -737,6 +757,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); sshbuf_free(kex->session_id); @@ -1410,7 +1407,7 @@ index 814fad947..9a2ce6d88 100644 sshkey_free(kex->initial_hostkey); free(kex->failed_choice); diff --git a/kex.h b/kex.h -index 55baa6a1e..206ce60ed 100644 +index d08988b3..0e080ea3 100644 --- a/kex.h +++ b/kex.h @@ -29,6 +29,10 @@ @@ -1440,7 +1437,7 @@ index 55baa6a1e..206ce60ed 100644 KEX_MAX }; -@@ -169,6 +182,13 @@ struct kex { +@@ -165,6 +178,13 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1454,8 +1451,8 @@ index 55baa6a1e..206ce60ed 100644 char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -196,8 +216,10 @@ int kex_nid_from_name(const char *); - int kex_is_pq_from_name(const char *); +@@ -191,8 +211,10 @@ int kex_hash_from_name(const char *); + int kex_nid_from_name(const char *); int kex_names_valid(const char *); char *kex_alg_list(char); +char *kex_gss_alg_list(char); @@ -1465,7 +1462,7 @@ index 55baa6a1e..206ce60ed 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 *); -@@ -231,6 +253,12 @@ int kexgex_client(struct ssh *); +@@ -226,6 +248,12 @@ int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kex_gen_client(struct ssh *); int kex_gen_server(struct ssh *); @@ -1478,7 +1475,7 @@ index 55baa6a1e..206ce60ed 100644 int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -269,6 +297,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, +@@ -264,6 +292,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, const BIGNUM *, const u_char *, size_t, u_char *, size_t *); @@ -1492,10 +1489,10 @@ index 55baa6a1e..206ce60ed 100644 __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); diff --git a/kexdh.c b/kexdh.c -index 191bdced0..6d5a7813d 100644 +index c1084f21..0faab21b 100644 --- a/kexdh.c +++ b/kexdh.c -@@ -50,13 +50,23 @@ kex_dh_keygen(struct kex *kex) +@@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: @@ -1520,7 +1517,7 @@ index 191bdced0..6d5a7813d 100644 break; case KEX_DH_GRP18_SHA512: diff --git a/kexgen.c b/kexgen.c -index 494d4b233..58edc79ad 100644 +index 40d688d6..15df591c 100644 --- a/kexgen.c +++ b/kexgen.c @@ -44,7 +44,7 @@ @@ -1534,7 +1531,7 @@ index 494d4b233..58edc79ad 100644 const struct sshbuf *client_version, diff --git a/kexgssc.c b/kexgssc.c new file mode 100644 -index 000000000..96f7b6f58 +index 00000000..96f7b6f5 --- /dev/null +++ b/kexgssc.c @@ -0,0 +1,706 @@ @@ -2246,7 +2243,7 @@ index 000000000..96f7b6f58 +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/kexgsss.c b/kexgsss.c new file mode 100644 -index 000000000..8362081ea +index 00000000..8362081e --- /dev/null +++ b/kexgsss.c @@ -0,0 +1,601 @@ @@ -2852,10 +2849,10 @@ index 000000000..8362081ea + +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/monitor.c b/monitor.c -index 85dc1b1b7..d463d6a9c 100644 +index 02b3eaaa..2ef16cc8 100644 --- a/monitor.c +++ b/monitor.c -@@ -137,6 +137,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); +@@ -147,6 +147,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 *); @@ -2864,7 +2861,7 @@ index 85dc1b1b7..d463d6a9c 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -214,11 +216,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -224,11 +226,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}, @@ -2883,7 +2880,7 @@ index 85dc1b1b7..d463d6a9c 100644 {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, -@@ -289,6 +298,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -299,6 +308,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); @@ -2894,7 +2891,7 @@ index 85dc1b1b7..d463d6a9c 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -341,8 +354,15 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -351,8 +364,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); @@ -2911,7 +2908,7 @@ index 85dc1b1b7..d463d6a9c 100644 if (authenticated || partial) { auth2_update_session_info(authctxt, auth_method, auth_submethod); -@@ -429,6 +449,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -421,6 +441,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); @@ -2922,7 +2919,7 @@ index 85dc1b1b7..d463d6a9c 100644 if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1896,6 +1920,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1890,6 +1914,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2940,7 +2937,7 @@ index 85dc1b1b7..d463d6a9c 100644 #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -@@ -1987,8 +2022,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1981,8 +2016,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; @@ -2951,7 +2948,7 @@ index 85dc1b1b7..d463d6a9c 100644 if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal_fr(r, "parse"); -@@ -2020,8 +2055,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2014,8 +2049,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2962,7 +2959,7 @@ index 85dc1b1b7..d463d6a9c 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal_fr(r, "ssh_gssapi_get_buffer_desc"); -@@ -2041,6 +2076,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2035,6 +2070,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); @@ -2970,7 +2967,7 @@ index 85dc1b1b7..d463d6a9c 100644 } return (0); } -@@ -2052,8 +2088,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2046,8 +2082,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 ret; int r; @@ -2981,7 +2978,7 @@ index 85dc1b1b7..d463d6a9c 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -2079,13 +2115,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2073,13 +2109,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) { @@ -3003,7 +3000,7 @@ index 85dc1b1b7..d463d6a9c 100644 sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -2094,7 +2134,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2088,7 +2128,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); @@ -3016,7 +3013,7 @@ index 85dc1b1b7..d463d6a9c 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -2102,5 +2146,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2096,5 +2140,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -3102,7 +3099,7 @@ index 85dc1b1b7..d463d6a9c 100644 #endif /* GSSAPI */ diff --git a/monitor.h b/monitor.h -index 9dcd9c293..dbc7e0037 100644 +index 9dcd9c29..dbc7e003 100644 --- a/monitor.h +++ b/monitor.h @@ -68,6 +68,8 @@ enum monitor_reqtype { @@ -3115,10 +3112,10 @@ index 9dcd9c293..dbc7e0037 100644 struct ssh; diff --git a/monitor_wrap.c b/monitor_wrap.c -index 347eb6870..08dc29e12 100644 +index ef3ab1b1..b6e3b3f3 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -1142,13 +1142,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +@@ -1131,13 +1131,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int @@ -3135,7 +3132,7 @@ index 347eb6870..08dc29e12 100644 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, -@@ -1161,6 +1163,59 @@ mm_ssh_gssapi_userok(char *user) +@@ -1150,6 +1152,59 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -3196,10 +3193,10 @@ index 347eb6870..08dc29e12 100644 /* diff --git a/monitor_wrap.h b/monitor_wrap.h -index 9b42ddbcb..12c489c33 100644 +index 38a280c8..672dce52 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -71,8 +71,10 @@ void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); +@@ -67,8 +67,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 *); @@ -3212,10 +3209,10 @@ index 9b42ddbcb..12c489c33 100644 #ifdef USE_PAM diff --git a/readconf.c b/readconf.c -index d99205944..eab734aaf 100644 +index 7cbe7d2c..6c04ed43 100644 --- a/readconf.c +++ b/readconf.c -@@ -65,6 +65,7 @@ +@@ -71,6 +71,7 @@ #include "myproposal.h" #include "digest.h" #include "version.h" @@ -3223,7 +3220,7 @@ index d99205944..eab734aaf 100644 /* Format of the configuration file: -@@ -159,6 +160,8 @@ typedef enum { +@@ -165,6 +166,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -3232,7 +3229,7 @@ index d99205944..eab734aaf 100644 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -206,10 +209,22 @@ static struct { +@@ -212,10 +215,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -3255,7 +3252,7 @@ index d99205944..eab734aaf 100644 #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1326,10 +1341,42 @@ parse_time: +@@ -1320,10 +1335,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -3298,7 +3295,7 @@ index d99205944..eab734aaf 100644 case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -2698,7 +2745,13 @@ initialize_options(Options * options) +@@ -2662,7 +2709,13 @@ initialize_options(Options * options) options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; options->gss_authentication = -1; @@ -3312,7 +3309,7 @@ index d99205944..eab734aaf 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2863,8 +2916,18 @@ fill_default_options(Options * options) +@@ -2826,8 +2879,18 @@ fill_default_options(Options * options) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3331,7 +3328,7 @@ index d99205944..eab734aaf 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -3692,7 +3755,14 @@ dump_client_config(Options *o, const char *host) +@@ -3656,7 +3719,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); @@ -3347,7 +3344,7 @@ index d99205944..eab734aaf 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 942149f9a..b96e3279e 100644 +index cd49139b..368523dd 100644 --- a/readconf.h +++ b/readconf.h @@ -39,7 +39,13 @@ typedef struct { @@ -3365,10 +3362,10 @@ index 942149f9a..b96e3279e 100644 * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --git a/servconf.c b/servconf.c -index 48ec8c4ec..3b93ca829 100644 +index f7bc9237..d4f7fd66 100644 --- a/servconf.c +++ b/servconf.c -@@ -67,6 +67,7 @@ +@@ -69,6 +69,7 @@ #include "myproposal.h" #include "digest.h" #include "version.h" @@ -3376,7 +3373,7 @@ index 48ec8c4ec..3b93ca829 100644 #if !defined(SSHD_PAM_SERVICE) # define SSHD_PAM_SERVICE "sshd" -@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions *options) +@@ -138,8 +139,11 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3388,7 +3385,7 @@ index 48ec8c4ec..3b93ca829 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -374,10 +378,18 @@ fill_default_server_options(ServerOptions *options) +@@ -380,10 +384,18 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3407,7 +3404,7 @@ index 48ec8c4ec..3b93ca829 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -562,6 +574,7 @@ typedef enum { +@@ -568,6 +580,7 @@ typedef enum { sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -3415,7 +3412,7 @@ index 48ec8c4ec..3b93ca829 100644 sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -647,12 +660,22 @@ static struct { +@@ -653,12 +666,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3438,7 +3435,7 @@ index 48ec8c4ec..3b93ca829 100644 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ -@@ -1643,6 +1666,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1649,6 +1672,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; @@ -3449,7 +3446,7 @@ index 48ec8c4ec..3b93ca829 100644 case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1651,6 +1678,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1657,6 +1684,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3472,19 +3469,19 @@ index 48ec8c4ec..3b93ca829 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3256,7 +3299,10 @@ dump_config(ServerOptions *o) +@@ -3254,6 +3297,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 9beb90fae..c3f501400 100644 +index 9beb90fa..c3f50140 100644 --- a/servconf.h +++ b/servconf.h @@ -150,8 +150,11 @@ typedef struct { @@ -3500,10 +3497,10 @@ index 9beb90fae..c3f501400 100644 * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/session.c b/session.c -index f265fdc3e..b8f0c1a58 100644 +index e4657cef..cbfbcee8 100644 --- a/session.c +++ b/session.c -@@ -2630,13 +2630,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2670,13 +2670,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3526,7 +3523,7 @@ index f265fdc3e..b8f0c1a58 100644 /* remove agent socket */ diff --git a/ssh-gss.h b/ssh-gss.h -index 7b14e74a8..8ec451926 100644 +index 7b14e74a..8ec45192 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -61,10 +61,36 @@ @@ -3654,7 +3651,7 @@ index 7b14e74a8..8ec451926 100644 #endif /* _SSH_GSS_H */ diff --git a/ssh.1 b/ssh.1 -index db92ac9af..6a9fbdc5b 100644 +index db92ac9a..6a9fbdc5 100644 --- a/ssh.1 +++ b/ssh.1 @@ -539,9 +539,15 @@ For full details of the options listed below, and their possible values, see @@ -3683,10 +3680,10 @@ index db92ac9af..6a9fbdc5b 100644 (key types), .Ar key-ca-sign diff --git a/ssh.c b/ssh.c -index 3b03108db..8d27f6379 100644 +index dc4886d0..c23d3b9e 100644 --- a/ssh.c +++ b/ssh.c -@@ -847,6 +847,8 @@ main(int ac, char **av) +@@ -835,6 +835,8 @@ main(int ac, char **av) else if (strcmp(optarg, "kex") == 0 || strcasecmp(optarg, "KexAlgorithms") == 0) cp = kex_alg_list('\n'); @@ -3695,7 +3692,7 @@ index 3b03108db..8d27f6379 100644 else if (strcmp(optarg, "key") == 0) cp = sshkey_alg_list(0, 0, 0, '\n'); else if (strcmp(optarg, "key-cert") == 0) -@@ -877,8 +879,8 @@ main(int ac, char **av) +@@ -865,8 +867,8 @@ main(int ac, char **av) } else if (strcmp(optarg, "help") == 0) { cp = xstrdup( "cipher\ncipher-auth\ncompression\nkex\n" @@ -3707,7 +3704,7 @@ index 3b03108db..8d27f6379 100644 if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); diff --git a/ssh_config b/ssh_config -index d9324c957..ca7c5853b 100644 +index 18169187..209248d6 100644 --- a/ssh_config +++ b/ssh_config @@ -24,6 +24,8 @@ @@ -3720,7 +3717,7 @@ index d9324c957..ca7c5853b 100644 # CheckHostIP no # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 -index f7066cbaa..8a4b469cf 100644 +index 894d7383..3a8e246c 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -976,10 +976,68 @@ The default is @@ -3793,7 +3790,7 @@ index f7066cbaa..8a4b469cf 100644 Indicates that .Xr ssh 1 diff --git a/sshconnect2.c b/sshconnect2.c -index b3679c9d7..b253f991b 100644 +index 1ee6000a..0af15bcc 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, @@ -4026,10 +4023,10 @@ index b3679c9d7..b253f991b 100644 static int diff --git a/sshd-auth.c b/sshd-auth.c -index 9c31515de..5a4ee733c 100644 +index f957dc22..e6f14dd0 100644 --- a/sshd-auth.c +++ b/sshd-auth.c -@@ -696,7 +696,7 @@ main(int ac, char **av) +@@ -722,7 +722,7 @@ main(int ac, char **av) break; } } @@ -4038,7 +4035,7 @@ index 9c31515de..5a4ee733c 100644 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) +@@ -844,6 +844,48 @@ do_ssh2_kex(struct ssh *ssh) free(hkalgs); @@ -4087,7 +4084,7 @@ index 9c31515de..5a4ee733c 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) fatal_r(r, "kex_setup"); -@@ -836,6 +878,17 @@ do_ssh2_kex(struct ssh *ssh) +@@ -861,6 +903,17 @@ do_ssh2_kex(struct ssh *ssh) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif /* OPENSSL_HAS_ECC */ @@ -4106,10 +4103,10 @@ index 9c31515de..5a4ee733c 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 9804dc334..6e28020e9 100644 +index a70b36c9..f8c8a797 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -592,8 +592,8 @@ notify_hostkeys(struct ssh *ssh) +@@ -616,8 +616,8 @@ notify_hostkeys(struct ssh *ssh) } debug3_f("sent %u hostkeys", nkeys); if (nkeys == 0) @@ -4120,7 +4117,7 @@ index 9804dc334..6e28020e9 100644 sshpkt_fatal(ssh, r, "%s: send", __func__); sshbuf_free(buf); } -@@ -1135,8 +1135,9 @@ main(int ac, char **av) +@@ -1159,8 +1159,9 @@ main(int ac, char **av) break; } } @@ -4133,7 +4130,7 @@ index 9804dc334..6e28020e9 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 3c76b60b0..3ab81e268 100644 +index 4a93e29e..c9ea8e38 100644 --- a/sshd.c +++ b/sshd.c @@ -1676,7 +1676,8 @@ main(int ac, char **av) @@ -4147,7 +4144,7 @@ index 3c76b60b0..3ab81e268 100644 exit(1); } diff --git a/sshd_config b/sshd_config -index 48af6321b..8db9f0fb1 100644 +index 48af6321..8db9f0fb 100644 --- a/sshd_config +++ b/sshd_config @@ -79,6 +79,8 @@ AuthorizedKeysFile .ssh/authorized_keys @@ -4160,7 +4157,7 @@ index 48af6321b..8db9f0fb1 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 aa9f0af76..b90068bf3 100644 +index 035a50c8..8bc6586e 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -739,6 +739,11 @@ Specifies whether to automatically destroy the user's credentials cache @@ -4209,12 +4206,12 @@ index aa9f0af76..b90068bf3 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 afd7822c4..148fee2b7 100644 +index ab80752b..4e41a78c 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -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 */ +@@ -129,6 +129,75 @@ extern const struct sshkey_impl sshkey_xmss_impl; + extern const struct sshkey_impl sshkey_xmss_cert_impl; + #endif +static int ssh_gss_equal(const struct sshkey *, const struct sshkey *) +{ @@ -4288,15 +4285,15 @@ index afd7822c4..148fee2b7 100644 const struct sshkey_impl * const keyimpls[] = { &sshkey_ed25519_impl, &sshkey_ed25519_cert_impl, -@@ -144,6 +213,7 @@ const struct sshkey_impl * const keyimpls[] = { - &sshkey_rsa_sha512_impl, - &sshkey_rsa_sha512_cert_impl, - #endif /* WITH_OPENSSL */ +@@ -167,6 +236,7 @@ const struct sshkey_impl * const keyimpls[] = { + &sshkey_xmss_impl, + &sshkey_xmss_cert_impl, + #endif + &sshkey_gss_kex_impl, NULL }; -@@ -314,7 +384,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -336,7 +406,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]; @@ -4306,10 +4303,10 @@ index afd7822c4..148fee2b7 100644 if (!include_sigonly && impl->sigonly) continue; diff --git a/sshkey.h b/sshkey.h -index c3262b896..931d1f79b 100644 +index 19bbbac7..4a318d05 100644 --- a/sshkey.h +++ b/sshkey.h -@@ -67,6 +67,7 @@ enum sshkey_types { +@@ -75,6 +75,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, KEY_ED25519_SK_CERT, @@ -4318,5 +4315,5 @@ index c3262b896..931d1f79b 100644 }; -- -2.52.0 +2.49.0 diff --git a/0012-openssh-6.6p1-force_krb.patch b/0013-openssh-6.6p1-force_krb.patch similarity index 96% rename from 0012-openssh-6.6p1-force_krb.patch rename to 0013-openssh-6.6p1-force_krb.patch index 70f75fb..74643b5 100644 --- a/0012-openssh-6.6p1-force_krb.patch +++ b/0013-openssh-6.6p1-force_krb.patch @@ -1,7 +1,7 @@ -From 577b0fea53270292bd0b4979eb5369619b2f5adb Mon Sep 17 00:00:00 2001 +From f5e5ee321def2a3674600714ad98fd1ca9b2cff1 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 12/53] openssh-6.6p1-force_krb +Subject: [PATCH 13/50] openssh-6.6p1-force_krb --- gss-serv-krb5.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++- @@ -11,7 +11,7 @@ Subject: [PATCH 12/53] 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 8d2b677f7..14502c5a6 100644 +index 8d2b677f..14502c5a 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -32,7 +32,9 @@ @@ -217,10 +217,10 @@ index 8d2b677f7..14502c5a6 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 b8f0c1a58..3eae5bdf3 100644 +index cbfbcee8..89b3a9cf 100644 --- a/session.c +++ b/session.c -@@ -642,6 +642,29 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -680,6 +680,29 @@ do_exec(struct ssh *ssh, Session *s, const char *command) command = auth_opts->force_command; forced = "(key-option)"; } @@ -251,7 +251,7 @@ index b8f0c1a58..3eae5bdf3 100644 if (forced != NULL) { s->forced = 1; diff --git a/ssh-gss.h b/ssh-gss.h -index 8ec451926..db34d77f4 100644 +index 8ec45192..db34d77f 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -49,6 +49,10 @@ @@ -266,7 +266,7 @@ index 8ec451926..db34d77f4 100644 /* draft-ietf-secsh-gsskeyex-06 */ diff --git a/sshd.8 b/sshd.8 -index 0226a8303..e2d8ff003 100644 +index 2aa73271..049d0a94 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 0226a8303..e2d8ff003 100644 This directory is the default location for all user-specific configuration and authentication information. -- -2.52.0 +2.49.0 diff --git a/0013-openssh-7.7p1-gssapi-new-unique.patch b/0014-openssh-7.7p1-gssapi-new-unique.patch similarity index 94% rename from 0013-openssh-7.7p1-gssapi-new-unique.patch rename to 0014-openssh-7.7p1-gssapi-new-unique.patch index 89fb40d..1d21839 100644 --- a/0013-openssh-7.7p1-gssapi-new-unique.patch +++ b/0014-openssh-7.7p1-gssapi-new-unique.patch @@ -1,7 +1,7 @@ -From 1a5b32dbf550467a4ae19351667bcfdf9c52e44d Mon Sep 17 00:00:00 2001 +From 5fca5946aa97dce23c6824c52b070a92532752a9 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 13/53] openssh-7.7p1-gssapi-new-unique +Subject: [PATCH 14/50] openssh-7.7p1-gssapi-new-unique --- auth-krb5.c | 262 ++++++++++++++++++++++++++++++++++++++++++------ @@ -17,7 +17,7 @@ Subject: [PATCH 13/53] openssh-7.7p1-gssapi-new-unique 10 files changed, 279 insertions(+), 71 deletions(-) diff --git a/auth-krb5.c b/auth-krb5.c -index 9d2f1f0ea..035032221 100644 +index c99e4e43..77714e3d 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -51,6 +51,7 @@ @@ -339,7 +339,7 @@ index 9d2f1f0ea..035032221 100644 #endif /* !HEIMDAL */ #endif /* KRB5 */ diff --git a/auth.h b/auth.h -index 83d07ae8b..10e88e11f 100644 +index 83d07ae8..10e88e11 100644 --- a/auth.h +++ b/auth.h @@ -85,6 +85,7 @@ struct Authctxt { @@ -360,7 +360,7 @@ index 83d07ae8b..10e88e11f 100644 #endif /* AUTH_H */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 14502c5a6..df55512d3 100644 +index 14502c5a..df55512d 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, @@ -475,7 +475,7 @@ index 14502c5a6..df55512d3 100644 int diff --git a/gss-serv.c b/gss-serv.c -index 6bac42931..d2bc03486 100644 +index a5cca797..9d5435ed 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void) @@ -508,10 +508,10 @@ index 6bac42931..d2bc03486 100644 ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); diff --git a/servconf.c b/servconf.c -index 3b93ca829..7bf1507df 100644 +index d4f7fd66..55aa5bf0 100644 --- a/servconf.c +++ b/servconf.c -@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions *options) +@@ -138,6 +138,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 3b93ca829..7bf1507df 100644 options->gss_authentication=-1; options->gss_keyex = -1; options->gss_cleanup_creds = -1; -@@ -376,6 +377,8 @@ fill_default_server_options(ServerOptions *options) +@@ -382,6 +383,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 3b93ca829..7bf1507df 100644 if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) -@@ -558,7 +561,7 @@ typedef enum { +@@ -564,7 +567,7 @@ typedef enum { sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -537,7 +537,7 @@ index 3b93ca829..7bf1507df 100644 sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, -@@ -649,11 +652,13 @@ static struct { +@@ -655,11 +658,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -551,7 +551,7 @@ index 3b93ca829..7bf1507df 100644 #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1662,6 +1667,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1668,6 +1673,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->kerberos_get_afs_token; goto parse_flag; @@ -562,7 +562,7 @@ index 3b93ca829..7bf1507df 100644 case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; -@@ -3295,6 +3304,7 @@ dump_config(ServerOptions *o) +@@ -3293,6 +3302,7 @@ dump_config(ServerOptions *o) # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif @@ -571,7 +571,7 @@ index 3b93ca829..7bf1507df 100644 #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff --git a/servconf.h b/servconf.h -index c3f501400..a4a38d6d7 100644 +index c3f50140..a4a38d6d 100644 --- a/servconf.h +++ b/servconf.h @@ -149,6 +149,8 @@ typedef struct { @@ -584,10 +584,10 @@ index c3f501400..a4a38d6d7 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 3eae5bdf3..b8a2dae92 100644 +index 89b3a9cf..2620dd11 100644 --- a/session.c +++ b/session.c -@@ -987,7 +987,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +@@ -1025,7 +1025,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 3eae5bdf3..b8a2dae92 100644 #endif /* Set basic environment. */ -@@ -1063,7 +1064,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +@@ -1101,7 +1102,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) } #endif #ifdef KRB5 @@ -607,7 +607,7 @@ index 3eae5bdf3..b8a2dae92 100644 s->authctxt->krb5_ccname); #endif diff --git a/ssh-gss.h b/ssh-gss.h -index db34d77f4..a894e23c9 100644 +index db34d77f..a894e23c 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -116,7 +116,7 @@ typedef struct ssh_gssapi_mech_struct { @@ -629,10 +629,10 @@ index db34d77f4..a894e23c9 100644 char *ssh_gssapi_server_mechanisms(void); diff --git a/sshd-session.c b/sshd-session.c -index 6e28020e9..028d5850e 100644 +index f8c8a797..478381db 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1327,7 +1327,7 @@ main(int ac, char **av) +@@ -1349,7 +1349,7 @@ main(int ac, char **av) #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(authctxt->pw); @@ -642,10 +642,10 @@ index 6e28020e9..028d5850e 100644 } #endif diff --git a/sshd_config.5 b/sshd_config.5 -index b90068bf3..cae0fd0b4 100644 +index 8bc6586e..1251d4d5 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1032,6 +1032,14 @@ Specifies whether to automatically destroy the user's ticket cache +@@ -1033,6 +1033,14 @@ Specifies whether to automatically destroy the user's ticket cache file on logout. The default is .Cm yes . @@ -661,5 +661,5 @@ index b90068bf3..cae0fd0b4 100644 Specifies the permitted KEX (Key Exchange) algorithms that the server will offer to clients. -- -2.52.0 +2.49.0 diff --git a/0014-openssh-7.2p2-k5login_directory.patch b/0015-openssh-7.2p2-k5login_directory.patch similarity index 91% rename from 0014-openssh-7.2p2-k5login_directory.patch rename to 0015-openssh-7.2p2-k5login_directory.patch index fa07e55..5e980c8 100644 --- a/0014-openssh-7.2p2-k5login_directory.patch +++ b/0015-openssh-7.2p2-k5login_directory.patch @@ -1,7 +1,7 @@ -From 0b19c3dabb1e23837238e90238f1ab5fa3c99df8 Mon Sep 17 00:00:00 2001 +From 25540939422660b024b8832f67eab82267aa8df6 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 14/53] openssh-7.2p2-k5login_directory +Subject: [PATCH 15/50] openssh-7.2p2-k5login_directory --- auth-krb5.c | 16 ++++++++++++++++ @@ -11,7 +11,7 @@ Subject: [PATCH 14/53] openssh-7.2p2-k5login_directory 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/auth-krb5.c b/auth-krb5.c -index 035032221..4910aa38a 100644 +index 77714e3d..74f56d47 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 035032221..4910aa38a 100644 #endif /* !HEIMDAL */ #endif /* KRB5 */ diff --git a/auth.h b/auth.h -index 10e88e11f..391630350 100644 +index 10e88e11..39163035 100644 --- a/auth.h +++ b/auth.h @@ -247,6 +247,8 @@ int sys_auth_passwd(struct ssh *, const char *); @@ -50,7 +50,7 @@ index 10e88e11f..391630350 100644 #endif /* AUTH_H */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index df55512d3..820f794cf 100644 +index df55512d..820f794c 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -144,8 +144,27 @@ ssh_gssapi_k5login_exists() @@ -83,7 +83,7 @@ index df55512d3..820f794cf 100644 } diff --git a/sshd.8 b/sshd.8 -index e2d8ff003..fa33f5232 100644 +index 049d0a94..6784286d 100644 --- a/sshd.8 +++ b/sshd.8 @@ -880,6 +880,10 @@ rlogin/rsh. @@ -98,5 +98,5 @@ index e2d8ff003..fa33f5232 100644 .It Pa ~/.ssh/ This directory is the default location for all user-specific configuration -- -2.52.0 +2.49.0 diff --git a/0015-openssh-6.6p1-kuserok.patch b/0016-openssh-6.6p1-kuserok.patch similarity index 94% rename from 0015-openssh-6.6p1-kuserok.patch rename to 0016-openssh-6.6p1-kuserok.patch index a403c7c..3724b8d 100644 --- a/0015-openssh-6.6p1-kuserok.patch +++ b/0016-openssh-6.6p1-kuserok.patch @@ -1,7 +1,7 @@ -From d0c2e8ddde548c79144547152b523346ae9f0358 Mon Sep 17 00:00:00 2001 +From bac7a9d1a654c8c2e0c71f979195e300b25d6232 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 15/53] openssh-6.6p1-kuserok +Subject: [PATCH 16/50] openssh-6.6p1-kuserok --- auth-krb5.c | 20 ++++++++- @@ -13,7 +13,7 @@ Subject: [PATCH 15/53] openssh-6.6p1-kuserok 6 files changed, 139 insertions(+), 7 deletions(-) diff --git a/auth-krb5.c b/auth-krb5.c -index 4910aa38a..b9c261a24 100644 +index 74f56d47..bae153c9 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -55,6 +55,21 @@ @@ -51,7 +51,7 @@ index 4910aa38a..b9c261a24 100644 goto out; } diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 820f794cf..187faf929 100644 +index 820f794c..187faf92 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -66,6 +66,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, @@ -189,10 +189,10 @@ index 820f794cf..187faf929 100644 if ((fp = fopen(file, "r")) == NULL) { int saved_errno = errno; diff --git a/servconf.c b/servconf.c -index 7bf1507df..8f4b2b43e 100644 +index 55aa5bf0..5dd5ca21 100644 --- a/servconf.c +++ b/servconf.c -@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions *options) +@@ -145,6 +145,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 7bf1507df..8f4b2b43e 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -393,6 +394,8 @@ fill_default_server_options(ServerOptions *options) +@@ -399,6 +400,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 7bf1507df..8f4b2b43e 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -561,7 +564,7 @@ typedef enum { +@@ -567,7 +570,7 @@ typedef enum { sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -218,7 +218,7 @@ index 7bf1507df..8f4b2b43e 100644 sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, -@@ -653,12 +656,14 @@ static struct { +@@ -659,12 +662,14 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif { "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL }, @@ -233,7 +233,7 @@ index 7bf1507df..8f4b2b43e 100644 #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -2431,6 +2436,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -2441,6 +2446,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, } break; @@ -244,7 +244,7 @@ index 7bf1507df..8f4b2b43e 100644 case sMatch: if (cmdline) fatal("Match directive not supported as a command-line " -@@ -2997,6 +3006,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +@@ -2995,6 +3004,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 7bf1507df..8f4b2b43e 100644 M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); -@@ -3305,6 +3315,7 @@ dump_config(ServerOptions *o) +@@ -3303,6 +3313,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 7bf1507df..8f4b2b43e 100644 #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff --git a/servconf.h b/servconf.h -index a4a38d6d7..11de36a23 100644 +index a4a38d6d..11de36a2 100644 --- a/servconf.h +++ b/servconf.h @@ -151,6 +151,7 @@ typedef struct { @@ -273,7 +273,7 @@ index a4a38d6d7..11de36a23 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 8db9f0fb1..ea5a878e6 100644 +index 8db9f0fb..ea5a878e 100644 --- a/sshd_config +++ b/sshd_config @@ -75,6 +75,7 @@ AuthorizedKeysFile .ssh/authorized_keys @@ -285,10 +285,10 @@ index 8db9f0fb1..ea5a878e6 100644 # GSSAPI options #GSSAPIAuthentication no diff --git a/sshd_config.5 b/sshd_config.5 -index cae0fd0b4..c360fcfff 100644 +index 1251d4d5..0fcb409a 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1040,6 +1040,10 @@ The default value +@@ -1041,6 +1041,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 cae0fd0b4..c360fcfff 100644 .It Cm KexAlgorithms Specifies the permitted KEX (Key Exchange) algorithms that the server will offer to clients. -@@ -1354,6 +1358,7 @@ Available keywords are +@@ -1355,6 +1359,7 @@ Available keywords are .Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , @@ -308,5 +308,5 @@ index cae0fd0b4..c360fcfff 100644 .Cm MaxAuthTries , .Cm MaxSessions , -- -2.52.0 +2.49.0 diff --git a/0016-openssh-6.4p1-fromto-remote.patch b/0017-openssh-6.4p1-fromto-remote.patch similarity index 73% rename from 0016-openssh-6.4p1-fromto-remote.patch rename to 0017-openssh-6.4p1-fromto-remote.patch index 2a2575e..5e8309d 100644 --- a/0016-openssh-6.4p1-fromto-remote.patch +++ b/0017-openssh-6.4p1-fromto-remote.patch @@ -1,17 +1,17 @@ -From d755d647c33f96cd4ec7d5499d11ecd443bdb098 Mon Sep 17 00:00:00 2001 +From 20aabb2c445e29d211266ce7434bb0273edf88b9 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 16/53] openssh-6.4p1-fromto-remote +Subject: [PATCH 17/50] openssh-6.4p1-fromto-remote --- scp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scp.c b/scp.c -index c5f573cc1..d97a54cc4 100644 +index 57c242ff..716ae386 100644 --- a/scp.c +++ b/scp.c -@@ -1148,7 +1148,10 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) +@@ -1162,7 +1162,10 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) addargs(&alist, "%s", ssh_program); addargs(&alist, "-x"); addargs(&alist, "-oClearAllForwardings=yes"); @@ -24,5 +24,5 @@ index c5f573cc1..d97a54cc4 100644 addargs(&alist, "%s", remote_remote_args.list[j]); -- -2.52.0 +2.49.0 diff --git a/0018-openssh-6.6.1p1-selinux-contexts.patch b/0018-openssh-6.6.1p1-selinux-contexts.patch new file mode 100644 index 0000000..49f2119 --- /dev/null +++ b/0018-openssh-6.6.1p1-selinux-contexts.patch @@ -0,0 +1,147 @@ +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/0017-openssh-6.6.1p1-log-in-chroot.patch b/0019-openssh-6.6.1p1-log-in-chroot.patch similarity index 83% rename from 0017-openssh-6.6.1p1-log-in-chroot.patch rename to 0019-openssh-6.6.1p1-log-in-chroot.patch index 6704616..3b30f98 100644 --- a/0017-openssh-6.6.1p1-log-in-chroot.patch +++ b/0019-openssh-6.6.1p1-log-in-chroot.patch @@ -1,7 +1,7 @@ -From 674851677d1e38cf6992948f8f452e46107a2014 Mon Sep 17 00:00:00 2001 +From 825018f5f2d892655f3d63167a0d1f3391cec678 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 17/53] openssh-6.6.1p1-log-in-chroot +Subject: [PATCH 19/50] openssh-6.6.1p1-log-in-chroot --- log.c | 11 +++++++++-- @@ -16,7 +16,7 @@ Subject: [PATCH 17/53] openssh-6.6.1p1-log-in-chroot 9 files changed, 52 insertions(+), 22 deletions(-) diff --git a/log.c b/log.c -index 5969c4a16..49b0c8a68 100644 +index 6617f267..9782cfb0 100644 --- a/log.c +++ b/log.c @@ -196,6 +196,11 @@ void @@ -45,7 +45,7 @@ index 5969c4a16..49b0c8a68 100644 log_on_stderr = on_stderr; if (on_stderr) diff --git a/log.h b/log.h -index 8e8dfc23f..70048a8af 100644 +index 8e8dfc23..70048a8a 100644 --- a/log.h +++ b/log.h @@ -52,6 +52,7 @@ typedef enum { @@ -57,10 +57,10 @@ index 8e8dfc23f..70048a8af 100644 int log_change_level(LogLevel); int log_is_on_stderr(void); diff --git a/monitor.c b/monitor.c -index d463d6a9c..453469665 100644 +index 2ef16cc8..43c10a4e 100644 --- a/monitor.c +++ b/monitor.c -@@ -2007,9 +2007,22 @@ monitor_init(void) +@@ -2001,9 +2001,22 @@ monitor_init(void) } void @@ -86,7 +86,7 @@ index d463d6a9c..453469665 100644 #ifdef GSSAPI diff --git a/monitor.h b/monitor.h -index dbc7e0037..d4d631ddc 100644 +index dbc7e003..d4d631dd 100644 --- a/monitor.h +++ b/monitor.h @@ -85,7 +85,7 @@ struct monitor { @@ -99,10 +99,10 @@ index dbc7e0037..d4d631ddc 100644 struct Authctxt; void monitor_child_preauth(struct ssh *, struct monitor *); diff --git a/session.c b/session.c -index b8a2dae92..d034f5c65 100644 +index 2620dd11..54da09d5 100644 --- a/session.c +++ b/session.c -@@ -162,6 +162,7 @@ login_cap_t *lc; +@@ -169,6 +169,7 @@ login_cap_t *lc; static int is_child = 0; static int in_chroot = 0; @@ -110,7 +110,7 @@ index b8a2dae92..d034f5c65 100644 /* File containing userauth info, if ExposeAuthInfo set */ static char *auth_info_file = NULL; -@@ -632,6 +633,7 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -670,6 +671,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 b8a2dae92..d034f5c65 100644 if (options.adm_forced_command) { original_command = command; -@@ -691,6 +693,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -729,6 +731,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command) tty += 5; } @@ -129,7 +129,7 @@ index b8a2dae92..d034f5c65 100644 verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", -@@ -1469,14 +1475,6 @@ child_close_fds(struct ssh *ssh) +@@ -1512,14 +1518,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 b8a2dae92..d034f5c65 100644 } /* -@@ -1609,8 +1607,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1652,8 +1650,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) exit(1); } @@ -153,10 +153,10 @@ index b8a2dae92..d034f5c65 100644 do_rc_files(ssh, s, shell); /* restore SIGPIPE for child */ -@@ -1638,9 +1634,17 @@ do_child(struct ssh *ssh, Session *s, const char *command) - #ifdef WITH_SELINUX - ssh_selinux_change_context("sftpd_t"); - #endif +@@ -1678,9 +1674,17 @@ do_child(struct ssh *ssh, Session *s, const char *command) + argv[i] = NULL; + optind = optreset = 1; + __progname = argv[0]; - exit(sftp_server_main(i, argv, s->pw)); + exit(sftp_server_main(i, argv, s->pw, have_dev_log)); } @@ -173,7 +173,7 @@ index b8a2dae92..d034f5c65 100644 /* Get the last component of the shell name. */ diff --git a/sftp-server-main.c b/sftp-server-main.c -index 2c70f89bc..bbb79f278 100644 +index 2c70f89b..bbb79f27 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 2c70f89bc..bbb79f278 100644 + return (sftp_server_main(argc, argv, user_pw, 0)); } diff --git a/sftp-server.c b/sftp-server.c -index 777821acd..185ad1459 100644 +index a4abb9f7..4985da38 100644 --- a/sftp-server.c +++ b/sftp-server.c -@@ -1897,7 +1897,7 @@ sftp_server_usage(void) +@@ -1901,7 +1901,7 @@ sftp_server_usage(void) } int @@ -196,7 +196,7 @@ index 777821acd..185ad1459 100644 { int i, r, in, out, ch, skipargs = 0, log_stderr = 0; ssize_t len, olen; -@@ -1909,7 +1909,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) +@@ -1913,7 +1913,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 777821acd..185ad1459 100644 pw = pwcopy(user_pw); -@@ -1982,7 +1982,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) +@@ -1986,7 +1986,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) } } @@ -215,7 +215,7 @@ index 777821acd..185ad1459 100644 /* * On platforms where we can, avoid making /proc/self/{mem,maps} diff --git a/sftp.h b/sftp.h -index 2bde8bb7f..ddf1a3968 100644 +index 2bde8bb7..ddf1a396 100644 --- a/sftp.h +++ b/sftp.h @@ -97,5 +97,5 @@ @@ -226,10 +226,10 @@ index 2bde8bb7f..ddf1a3968 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 028d5850e..4a5eaa1ff 100644 +index 478381db..9342e416 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -415,7 +415,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -437,7 +437,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) #endif /* New socket pair */ @@ -238,7 +238,7 @@ index 028d5850e..4a5eaa1ff 100644 pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) -@@ -434,6 +434,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -456,6 +456,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; @@ -251,5 +251,5 @@ index 028d5850e..4a5eaa1ff 100644 /* Demote the private keys to public keys. */ demote_sensitive_data(); -- -2.52.0 +2.49.0 diff --git a/0018-openssh-6.6.1p1-scp-non-existing-directory.patch b/0020-openssh-6.6.1p1-scp-non-existing-directory.patch similarity index 65% rename from 0018-openssh-6.6.1p1-scp-non-existing-directory.patch rename to 0020-openssh-6.6.1p1-scp-non-existing-directory.patch index e50e1c2..94c43ef 100644 --- a/0018-openssh-6.6.1p1-scp-non-existing-directory.patch +++ b/0020-openssh-6.6.1p1-scp-non-existing-directory.patch @@ -1,17 +1,17 @@ -From 931f22f77ab2b9cebd96e113f1e3ab179dd1b6cb Mon Sep 17 00:00:00 2001 +From 007ee98fa9100f7241985ac2a7eed71e17d89a9f Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 18/53] openssh-6.6.1p1-scp-non-existing-directory +Subject: [PATCH 20/50] openssh-6.6.1p1-scp-non-existing-directory --- scp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scp.c b/scp.c -index d97a54cc4..e1992622f 100644 +index 716ae386..9554b188 100644 --- a/scp.c +++ b/scp.c -@@ -1866,6 +1866,10 @@ sink(int argc, char **argv, const char *src) +@@ -1876,6 +1876,10 @@ sink(int argc, char **argv, const char *src) free(vect[0]); continue; } @@ -23,5 +23,5 @@ index d97a54cc4..e1992622f 100644 mode |= S_IWUSR; if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { -- -2.52.0 +2.49.0 diff --git a/0019-openssh-6.6p1-GSSAPIEnablek5users.patch b/0021-openssh-6.6p1-GSSAPIEnablek5users.patch similarity index 87% rename from 0019-openssh-6.6p1-GSSAPIEnablek5users.patch rename to 0021-openssh-6.6p1-GSSAPIEnablek5users.patch index 4c0a60b..eeff02a 100644 --- a/0019-openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/0021-openssh-6.6p1-GSSAPIEnablek5users.patch @@ -1,7 +1,7 @@ -From ef91c84a26a282adaf95e165ebcdd44a410c4328 Mon Sep 17 00:00:00 2001 +From 9c75c175e3555377328fc5fc9b06e94f129b7cd7 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 19/53] openssh-6.6p1-GSSAPIEnablek5users +Subject: [PATCH 21/50] openssh-6.6p1-GSSAPIEnablek5users --- gss-serv-krb5.c | 3 +-- @@ -12,7 +12,7 @@ Subject: [PATCH 19/53] openssh-6.6p1-GSSAPIEnablek5users 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index 187faf929..03188d9b3 100644 +index 187faf92..03188d9b 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -278,7 +278,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, @@ -33,10 +33,10 @@ index 187faf929..03188d9b3 100644 k5login_exists); } diff --git a/servconf.c b/servconf.c -index 8f4b2b43e..5e40f1b00 100644 +index 5dd5ca21..c0de7110 100644 --- a/servconf.c +++ b/servconf.c -@@ -144,6 +144,7 @@ initialize_server_options(ServerOptions *options) +@@ -146,6 +146,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 8f4b2b43e..5e40f1b00 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -396,6 +397,8 @@ fill_default_server_options(ServerOptions *options) +@@ -402,6 +403,8 @@ fill_default_server_options(ServerOptions *options) #endif if (options->use_kuserok == -1) options->use_kuserok = 1; @@ -53,7 +53,7 @@ index 8f4b2b43e..5e40f1b00 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -579,7 +582,7 @@ typedef enum { +@@ -585,7 +588,7 @@ typedef enum { sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -62,7 +62,7 @@ index 8f4b2b43e..5e40f1b00 100644 sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, -@@ -675,6 +678,7 @@ static struct { +@@ -681,6 +684,7 @@ static struct { { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, @@ -70,7 +70,7 @@ index 8f4b2b43e..5e40f1b00 100644 #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -683,6 +687,7 @@ static struct { +@@ -689,6 +693,7 @@ static struct { { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, @@ -78,7 +78,7 @@ index 8f4b2b43e..5e40f1b00 100644 #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -2440,6 +2445,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -2450,6 +2455,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->use_kuserok; goto parse_flag; @@ -89,7 +89,7 @@ index 8f4b2b43e..5e40f1b00 100644 case sMatch: if (cmdline) fatal("Match directive not supported as a command-line " -@@ -3007,6 +3016,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +@@ -3005,6 +3014,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 8f4b2b43e..5e40f1b00 100644 M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); -@@ -3316,6 +3326,7 @@ dump_config(ServerOptions *o) +@@ -3314,6 +3324,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 8f4b2b43e..5e40f1b00 100644 #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff --git a/servconf.h b/servconf.h -index 11de36a23..c08cf6a7a 100644 +index 11de36a2..c08cf6a7 100644 --- a/servconf.h +++ b/servconf.h @@ -152,6 +152,7 @@ typedef struct { @@ -118,7 +118,7 @@ index 11de36a23..c08cf6a7a 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 ea5a878e6..33713c886 100644 +index ea5a878e..33713c88 100644 --- a/sshd_config +++ b/sshd_config @@ -82,6 +82,7 @@ AuthorizedKeysFile .ssh/authorized_keys @@ -130,7 +130,7 @@ index ea5a878e6..33713c886 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 c360fcfff..a0fc6064f 100644 +index 0fcb409a..fe246fc2 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -739,6 +739,12 @@ Specifies whether to automatically destroy the user's credentials cache @@ -147,5 +147,5 @@ index c360fcfff..a0fc6064f 100644 Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange doesn't rely on ssh keys to verify host identity. -- -2.52.0 +2.49.0 diff --git a/0020-openssh-6.8p1-sshdT-output.patch b/0022-openssh-6.8p1-sshdT-output.patch similarity index 75% rename from 0020-openssh-6.8p1-sshdT-output.patch rename to 0022-openssh-6.8p1-sshdT-output.patch index ed2379e..4e4766e 100644 --- a/0020-openssh-6.8p1-sshdT-output.patch +++ b/0022-openssh-6.8p1-sshdT-output.patch @@ -1,17 +1,17 @@ -From cce18d636f4137a4e5401170538868b8b80651c1 Mon Sep 17 00:00:00 2001 +From 05b09904f431333e19cd24528ef66d1fd15e9efe Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 20/53] openssh-6.8p1-sshdT-output +Subject: [PATCH 22/50] openssh-6.8p1-sshdT-output --- servconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servconf.c b/servconf.c -index 5e40f1b00..b63a7f0b0 100644 +index c0de7110..105e301d 100644 --- a/servconf.c +++ b/servconf.c -@@ -3368,7 +3368,7 @@ dump_config(ServerOptions *o) +@@ -3366,7 +3366,7 @@ dump_config(ServerOptions *o) dump_cfg_string(sXAuthLocation, o->xauth_location); dump_cfg_string(sCiphers, o->ciphers); dump_cfg_string(sMacs, o->macs); @@ -21,5 +21,5 @@ index 5e40f1b00..b63a7f0b0 100644 dump_cfg_string(sChrootDirectory, o->chroot_directory); dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); -- -2.52.0 +2.49.0 diff --git a/0021-openssh-6.7p1-sftp-force-permission.patch b/0023-openssh-6.7p1-sftp-force-permission.patch similarity index 85% rename from 0021-openssh-6.7p1-sftp-force-permission.patch rename to 0023-openssh-6.7p1-sftp-force-permission.patch index 737430d..1cdc0df 100644 --- a/0021-openssh-6.7p1-sftp-force-permission.patch +++ b/0023-openssh-6.7p1-sftp-force-permission.patch @@ -1,7 +1,7 @@ -From 57ae33c2f43425725345c910d90ef6fed75d3b85 Mon Sep 17 00:00:00 2001 +From 34b196198018059bed294fa7a08e70606b4cbc36 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 21/53] openssh-6.7p1-sftp-force-permission +Subject: [PATCH 23/50] openssh-6.7p1-sftp-force-permission --- sftp-server.8 | 7 +++++++ @@ -9,7 +9,7 @@ Subject: [PATCH 21/53] openssh-6.7p1-sftp-force-permission 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/sftp-server.8 b/sftp-server.8 -index 5311bf929..5e6e3aa44 100644 +index 5311bf92..5e6e3aa4 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -38,6 +38,7 @@ @@ -34,10 +34,10 @@ index 5311bf929..5e6e3aa44 100644 .Pp On some systems, diff --git a/sftp-server.c b/sftp-server.c -index 185ad1459..e04fc63b3 100644 +index 4985da38..6ed1c27f 100644 --- a/sftp-server.c +++ b/sftp-server.c -@@ -72,6 +72,10 @@ struct sshbuf *oqueue; +@@ -76,6 +76,10 @@ struct sshbuf *oqueue; /* Version of client */ static u_int version; @@ -48,7 +48,7 @@ index 185ad1459..e04fc63b3 100644 /* SSH2_FXP_INIT received */ static int init_done; -@@ -741,6 +745,7 @@ process_open(u_int32_t id) +@@ -745,6 +749,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 185ad1459..e04fc63b3 100644 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ -@@ -750,6 +755,10 @@ process_open(u_int32_t id) +@@ -754,6 +759,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 185ad1459..e04fc63b3 100644 logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && -@@ -771,6 +780,8 @@ process_open(u_int32_t id) +@@ -775,6 +784,8 @@ process_open(u_int32_t id) } } } @@ -76,7 +76,7 @@ index 185ad1459..e04fc63b3 100644 if (status != SSH2_FX_OK) send_status(id, status); free(name); -@@ -1890,7 +1901,7 @@ sftp_server_usage(void) +@@ -1894,7 +1905,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 185ad1459..e04fc63b3 100644 " %s -Q protocol_feature\n", __progname, __progname); exit(1); -@@ -1914,7 +1925,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle +@@ -1918,7 +1929,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 185ad1459..e04fc63b3 100644 switch (ch) { case 'Q': if (strcasecmp(optarg, "requests") != 0) { -@@ -1976,6 +1987,15 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle +@@ -1980,6 +1991,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 185ad1459..e04fc63b3 100644 default: sftp_server_usage(); -- -2.52.0 +2.49.0 diff --git a/0022-openssh-7.2p2-s390-closefrom.patch b/0024-openssh-7.2p2-s390-closefrom.patch similarity index 89% rename from 0022-openssh-7.2p2-s390-closefrom.patch rename to 0024-openssh-7.2p2-s390-closefrom.patch index fa59fd6..0214781 100644 --- a/0022-openssh-7.2p2-s390-closefrom.patch +++ b/0024-openssh-7.2p2-s390-closefrom.patch @@ -1,14 +1,14 @@ -From 25b593f41fa85bcaf1bbdc9c368325c4af033208 Mon Sep 17 00:00:00 2001 +From 9bb31b63142adaaf949e20c2d86c97f9b787217b Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 22/53] openssh-7.2p2-s390-closefrom +Subject: [PATCH 24/50] 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 49a4f35ff..f61124585 100644 +index 49a4f35f..f6112458 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 49a4f35ff..f61124585 100644 (void) closedir(dirp); return; -- -2.52.0 +2.49.0 diff --git a/0051-openssh-7.3p1-x11-max-displays.patch b/0025-openssh-7.3p1-x11-max-displays.patch similarity index 82% rename from 0051-openssh-7.3p1-x11-max-displays.patch rename to 0025-openssh-7.3p1-x11-max-displays.patch index 422107c..68d679c 100644 --- a/0051-openssh-7.3p1-x11-max-displays.patch +++ b/0025-openssh-7.3p1-x11-max-displays.patch @@ -1,7 +1,7 @@ -From 763c65f6f349a7bab344a58991246891700e4fa0 Mon Sep 17 00:00:00 2001 +From 36e3430d1f81397d5f40600e075272a81f7effce Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy -Date: Fri, 12 Dec 2025 15:35:14 +0100 -Subject: [PATCH 51/53] openssh-7.3p1-x11-max-displays +Date: Thu, 15 May 2025 13:43:28 +0200 +Subject: [PATCH 25/50] openssh-7.3p1-x11-max-displays --- channels.c | 9 ++++++--- @@ -13,10 +13,10 @@ Subject: [PATCH 51/53] openssh-7.3p1-x11-max-displays 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/channels.c b/channels.c -index 26ed9945f..c26380e25 100644 +index d46531ce..7438c1a5 100644 --- a/channels.c +++ b/channels.c -@@ -5067,7 +5067,7 @@ rdynamic_connect_finish(struct ssh *ssh, Channel *c) +@@ -4996,7 +4996,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 26ed9945f..c26380e25 100644 u_int *display_numberp, int **chanids) { Channel *nc = NULL; -@@ -5080,8 +5080,11 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +@@ -5009,8 +5009,11 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS) return -1; @@ -33,25 +33,25 @@ index 26ed9945f..c26380e25 100644 + x11_max_displays = x11_max_displays + x11_display_offset; + for (display_number = x11_display_offset; -- display_number < x11_display_offset + MAX_DISPLAYS; +- display_number < MAX_DISPLAYS; + display_number < x11_max_displays; display_number++) { port = X11_BASE_PORT + display_number; memset(&hints, 0, sizeof(hints)); -@@ -5146,7 +5149,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +@@ -5065,7 +5068,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, if (num_socks > 0) break; } -- if (display_number >= x11_display_offset + MAX_DISPLAYS) { +- if (display_number >= 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 7456541f8..754bd98ee 100644 +index 134528d5..8a09a820 100644 --- a/channels.h +++ b/channels.h -@@ -389,7 +389,7 @@ int permitopen_port(const char *); +@@ -379,7 +379,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 7456541f8..754bd98ee 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 fb1d150cd..956205f6d 100644 +index 105e301d..15c99b30 100644 --- a/servconf.c +++ b/servconf.c -@@ -118,6 +118,7 @@ initialize_server_options(ServerOptions *options) +@@ -117,6 +117,7 @@ initialize_server_options(ServerOptions *options) options->print_lastlog = -1; options->x11_forwarding = -1; options->x11_display_offset = -1; @@ -72,7 +72,7 @@ index fb1d150cd..956205f6d 100644 options->x11_use_localhost = -1; options->permit_tty = -1; options->permit_user_rc = -1; -@@ -357,6 +358,8 @@ fill_default_server_options(ServerOptions *options) +@@ -353,6 +354,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 fb1d150cd..956205f6d 100644 if (options->x11_use_localhost == -1) options->x11_use_localhost = 1; if (options->xauth_location == NULL) -@@ -582,7 +585,7 @@ typedef enum { +@@ -576,7 +579,7 @@ typedef enum { sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -90,7 +90,7 @@ index fb1d150cd..956205f6d 100644 sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, sPermitUserEnvironment, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, -@@ -725,6 +728,7 @@ static struct { +@@ -714,6 +717,7 @@ static struct { { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, @@ -98,7 +98,7 @@ index fb1d150cd..956205f6d 100644 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, -@@ -1775,6 +1779,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1750,6 +1754,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, *intptr = value; break; @@ -109,7 +109,7 @@ index fb1d150cd..956205f6d 100644 case sX11UseLocalhost: intptr = &options->x11_use_localhost; goto parse_flag; -@@ -3037,6 +3045,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +@@ -3004,6 +3012,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 fb1d150cd..956205f6d 100644 M_CP_INTOPT(x11_use_localhost); M_CP_INTOPT(permit_tty); M_CP_INTOPT(permit_user_rc); -@@ -3332,6 +3341,7 @@ dump_config(ServerOptions *o) +@@ -3299,6 +3308,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 fb1d150cd..956205f6d 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 9b1a73b8d..6bfdf6305 100644 +index c08cf6a7..7c7e5d43 100644 --- a/servconf.h +++ b/servconf.h @@ -38,6 +38,7 @@ @@ -146,10 +146,10 @@ index 9b1a73b8d..6bfdf6305 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 80282dfd8..e53d044a0 100644 +index 54da09d5..28bbb8a7 100644 --- a/session.c +++ b/session.c -@@ -2681,8 +2681,9 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) +@@ -2611,8 +2611,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 80282dfd8..e53d044a0 100644 return 0; } diff --git a/sshd_config.5 b/sshd_config.5 -index 4ae4bebee..3dbce55fc 100644 +index fe246fc2..26fcdc84 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1403,6 +1403,7 @@ Available keywords are +@@ -1391,6 +1391,7 @@ Available keywords are .Cm TrustedUserCAKeys , .Cm UnusedConnectionTimeout , .Cm X11DisplayOffset , @@ -173,7 +173,7 @@ index 4ae4bebee..3dbce55fc 100644 .Cm X11Forwarding and .Cm X11UseLocalhost . -@@ -2112,6 +2113,12 @@ Specifies the first display number available for +@@ -2111,6 +2112,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 4ae4bebee..3dbce55fc 100644 Specifies whether X11 forwarding is permitted. The argument must be -- -2.52.0 +2.49.0 diff --git a/0023-openssh-7.6p1-cleanup-selinux.patch b/0026-openssh-7.6p1-cleanup-selinux.patch similarity index 81% rename from 0023-openssh-7.6p1-cleanup-selinux.patch rename to 0026-openssh-7.6p1-cleanup-selinux.patch index d018772..c4f2d15 100644 --- a/0023-openssh-7.6p1-cleanup-selinux.patch +++ b/0026-openssh-7.6p1-cleanup-selinux.patch @@ -1,25 +1,25 @@ -From 4cacb1bda51a2d91cf4cc1c8058b989dfc0c58c8 Mon Sep 17 00:00:00 2001 +From 43320351b6f150167190aacc84f2f87030fef3d2 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 23/53] openssh-7.6p1-cleanup-selinux +Subject: [PATCH 26/50] openssh-7.6p1-cleanup-selinux --- auth2-pubkey.c | 8 ++++-- misc.c | 5 ++-- misc.h | 2 +- openbsd-compat/port-linux-sshd.c | 42 +++++++++++++++++--------------- - openbsd-compat/port-linux.h | 5 ++-- + openbsd-compat/port-linux.h | 4 +-- platform.c | 6 ++++- sshconnect.c | 2 +- sshd-auth.c | 2 +- sshd-session.c | 6 +++-- - 9 files changed, 46 insertions(+), 32 deletions(-) + 9 files changed, 45 insertions(+), 32 deletions(-) diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index c326a69ba..b7300ca9e 100644 +index 267a27d2..0d5ae0df 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c -@@ -75,6 +75,8 @@ +@@ -77,6 +77,8 @@ /* import */ extern ServerOptions options; @@ -28,7 +28,7 @@ index c326a69ba..b7300ca9e 100644 extern struct authmethod_cfg methodcfg_pubkey; static char * -@@ -483,7 +485,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key, +@@ -485,7 +487,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 c326a69ba..b7300ca9e 100644 goto out; uid_swapped = 1; -@@ -759,7 +762,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key, +@@ -755,7 +758,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 c326a69ba..b7300ca9e 100644 uid_swapped = 1; diff --git a/misc.c b/misc.c -index 7e27a38d1..2fd14159d 100644 +index 1e31acc9..09722962 100644 --- a/misc.c +++ b/misc.c -@@ -2788,7 +2788,8 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) +@@ -2764,7 +2764,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 7e27a38d1..2fd14159d 100644 { FILE *f = NULL; struct stat st; -@@ -2922,7 +2923,7 @@ subprocess(const char *tag, const char *command, +@@ -2898,7 +2899,7 @@ subprocess(const char *tag, const char *command, _exit(1); } #ifdef WITH_SELINUX @@ -72,10 +72,10 @@ index 7e27a38d1..2fd14159d 100644 strerror(errno)); _exit(127); diff --git a/misc.h b/misc.h -index f3c5a18c6..8cdfd7cec 100644 +index efecdf1a..9efa9cf4 100644 --- a/misc.h +++ b/misc.h -@@ -124,7 +124,7 @@ typedef void privrestore_fn(void); +@@ -122,7 +122,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 f3c5a18c6..8cdfd7cec 100644 typedef struct arglist arglist; struct arglist { diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c -index 4d56745f7..ab083a637 100644 +index 646f0887..291b569a 100644 --- a/openbsd-compat/port-linux-sshd.c +++ b/openbsd-compat/port-linux-sshd.c -@@ -48,10 +48,6 @@ +@@ -49,10 +49,6 @@ #include #endif @@ -99,7 +99,7 @@ index 4d56745f7..ab083a637 100644 /* Wrapper around is_selinux_enabled() to log its return value once only */ int sshd_selinux_enabled(void) -@@ -221,7 +217,8 @@ get_user_context(const char *sename, const char *role, const char *lvl, +@@ -222,7 +218,8 @@ get_user_context(const char *sename, const char *role, const char *lvl, } static void @@ -109,7 +109,7 @@ index 4d56745f7..ab083a637 100644 { *role = NULL; *level = NULL; -@@ -239,8 +236,8 @@ ssh_selinux_get_role_level(char **role, const char **level) +@@ -240,8 +237,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 4d56745f7..ab083a637 100644 { char *sename, *lvl; char *role; -@@ -248,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -249,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname, int r = 0; context_t con = NULL; @@ -129,7 +129,7 @@ index 4d56745f7..ab083a637 100644 #ifdef HAVE_GETSEUSERBYNAME if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { -@@ -270,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -271,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname, if (r == 0) { /* If launched from xinetd, we must use current level */ @@ -138,7 +138,7 @@ index 4d56745f7..ab083a637 100644 security_context_t sshdsc=NULL; if (getcon_raw(&sshdsc) < 0) -@@ -331,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname, +@@ -332,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int @@ -148,7 +148,7 @@ index 4d56745f7..ab083a637 100644 { const char *reqlvl; char *role; -@@ -340,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) +@@ -341,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) debug3_f("setting execution context"); @@ -162,7 +162,7 @@ index 4d56745f7..ab083a637 100644 use_current = "1"; } else { use_current = ""; -@@ -360,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) +@@ -361,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) } static int @@ -175,7 +175,7 @@ index 4d56745f7..ab083a637 100644 } static int -@@ -372,25 +371,28 @@ do_setenv(char *name, const char *value) +@@ -373,25 +372,28 @@ do_setenv(char *name, const char *value) } int @@ -209,7 +209,7 @@ index 4d56745f7..ab083a637 100644 switch (security_getenforce()) { case -1: fatal_f("security_getenforce() failed"); -@@ -406,7 +408,7 @@ sshd_selinux_setup_exec_context(char *pwname) +@@ -407,7 +409,7 @@ sshd_selinux_setup_exec_context(char *pwname) debug3_f("setting execution context"); @@ -219,23 +219,22 @@ index 4d56745f7..ab083a637 100644 r = setexeccon(user_ctx); if (r < 0) { diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index c004071d1..26c5f773b 100644 +index 7f8ba200..3cd7da6a 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h -@@ -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 *); +@@ -25,8 +25,8 @@ void ssh_selinux_setfscreatecon(const char *); + int sshd_selinux_enabled(void); + void sshd_selinux_copy_context(void); -void sshd_selinux_setup_exec_context(char *); -int sshd_selinux_setup_env_variables(void); -+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 c92a0cba6..66d0c2a6b 100644 +index 0d12f311..f0800b1f 100644 --- a/platform.c +++ b/platform.c @@ -33,6 +33,8 @@ @@ -259,10 +258,10 @@ index c92a0cba6..66d0c2a6b 100644 } diff --git a/sshconnect.c b/sshconnect.c -index 912a520c5..babe4a982 100644 +index c86182d1..04084810 100644 --- a/sshconnect.c +++ b/sshconnect.c -@@ -917,7 +917,7 @@ load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template, +@@ -925,7 +925,7 @@ load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template, if ((pid = subprocess(tag, command, ac, av, &f, SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH| @@ -272,10 +271,10 @@ index 912a520c5..babe4a982 100644 load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1); diff --git a/sshd-auth.c b/sshd-auth.c -index 5a4ee733c..f3c38a7d1 100644 +index e4a8edfd..897db9b4 100644 --- a/sshd-auth.c +++ b/sshd-auth.c -@@ -120,7 +120,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; +@@ -122,7 +122,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; int debug_flag = 0; /* Flag indicating that the daemon is being started from inetd. */ @@ -285,10 +284,10 @@ index 5a4ee733c..f3c38a7d1 100644 /* Saved arguments to main(). */ static char **saved_argv; diff --git a/sshd-session.c b/sshd-session.c -index 4a5eaa1ff..d6bece941 100644 +index 9342e416..81d30152 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -130,7 +130,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; +@@ -136,7 +136,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; int debug_flag = 0; /* Flag indicating that the daemon is being started from inetd. */ @@ -297,7 +296,7 @@ index 4a5eaa1ff..d6bece941 100644 /* debug goes to stderr unless inetd_flag is set */ static int log_stderr = 0; -@@ -1337,7 +1337,9 @@ main(int ac, char **av) +@@ -1359,7 +1359,9 @@ main(int ac, char **av) } #endif #ifdef WITH_SELINUX @@ -309,5 +308,5 @@ index 4a5eaa1ff..d6bece941 100644 #ifdef USE_PAM if (options.use_pam) { -- -2.52.0 +2.49.0 diff --git a/0024-openssh-7.5p1-sandbox.patch b/0027-openssh-7.5p1-sandbox.patch similarity index 76% rename from 0024-openssh-7.5p1-sandbox.patch rename to 0027-openssh-7.5p1-sandbox.patch index 32b56db..435d029 100644 --- a/0024-openssh-7.5p1-sandbox.patch +++ b/0027-openssh-7.5p1-sandbox.patch @@ -1,17 +1,17 @@ -From 503297ec6f6eef3bb4906271d170fab848e27298 Mon Sep 17 00:00:00 2001 +From 35205319dd71d8e61c1596b8f9479df91aff7756 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 24/53] openssh-7.5p1-sandbox +Subject: [PATCH 27/50] openssh-7.5p1-sandbox --- sandbox-seccomp-filter.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index a0692dd2f..e0f2d4289 100644 +index b31062c2..1fabf99d 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c -@@ -305,6 +305,9 @@ static const struct sock_filter preauth_insns[] = { +@@ -277,6 +277,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_exit_group SC_ALLOW(__NR_exit_group), #endif @@ -21,7 +21,7 @@ index a0692dd2f..e0f2d4289 100644 #ifdef __NR_futex SC_FUTEX(__NR_futex), #endif -@@ -323,6 +326,21 @@ static const struct sock_filter preauth_insns[] = { +@@ -295,6 +298,21 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_getpid SC_ALLOW(__NR_getpid), #endif @@ -43,7 +43,7 @@ index a0692dd2f..e0f2d4289 100644 #ifdef __NR_getrandom SC_ALLOW(__NR_getrandom), #endif -@@ -332,6 +350,9 @@ static const struct sock_filter preauth_insns[] = { +@@ -304,6 +322,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_gettimeofday SC_ALLOW(__NR_gettimeofday), #endif @@ -54,5 +54,5 @@ index a0692dd2f..e0f2d4289 100644 SC_ALLOW(__NR_getuid), #endif -- -2.52.0 +2.49.0 diff --git a/0052-openssh-10.2p1-pkcs11-uri.patch b/0028-openssh-8.0p1-pkcs11-uri.patch similarity index 86% rename from 0052-openssh-10.2p1-pkcs11-uri.patch rename to 0028-openssh-8.0p1-pkcs11-uri.patch index b486fee..73e890b 100644 --- a/0052-openssh-10.2p1-pkcs11-uri.patch +++ b/0028-openssh-8.0p1-pkcs11-uri.patch @@ -1,59 +1,45 @@ -From f32f2a8a37e8585c1259fea2a970319d229e2cc7 Mon Sep 17 00:00:00 2001 +From 5d6ec35c1a0e06452a2c087decb0baf6e8063e21 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy -Date: Mon, 15 Dec 2025 14:24:07 +0100 -Subject: [PATCH 52/53] openssh-10.2p1-pkcs11-uri +Date: Thu, 15 May 2025 13:43:28 +0200 +Subject: [PATCH 28/50] openssh-8.0p1-pkcs11-uri --- - Makefile.in | 24 +- + Makefile.in | 20 +- configure.ac | 37 ++ - regress/Makefile | 4 +- - regress/pkcs11.sh | 349 ++++++++++++++ + regress/Makefile | 8 +- + regress/pkcs11.sh | 349 +++++++++++++++ regress/unittests/Makefile | 2 +- - regress/unittests/pkcs11/tests.c | 353 ++++++++++++++ + regress/unittests/pkcs11/tests.c | 346 ++++++++++++++ ssh-add.c | 48 +- - ssh-agent.c | 104 ++++- + ssh-agent.c | 103 ++++- ssh-keygen.c | 7 +- - ssh-pkcs11-client.c | 17 + + ssh-pkcs11-client.c | 3 + ssh-pkcs11-uri.c | 437 ++++++++++++++++++ ssh-pkcs11-uri.h | 43 ++ - ssh-pkcs11.c | 760 ++++++++++++++++++++++--------- + ssh-pkcs11.c | 745 +++++++++++++++++++++++-------- ssh-pkcs11.h | 4 + ssh.c | 104 ++++- ssh_config.5 | 15 + - 16 files changed, 2039 insertions(+), 269 deletions(-) + 16 files changed, 2024 insertions(+), 247 deletions(-) create mode 100644 regress/pkcs11.sh create mode 100644 regress/unittests/pkcs11/tests.c create mode 100644 ssh-pkcs11-uri.c create mode 100644 ssh-pkcs11-uri.h diff --git a/Makefile.in b/Makefile.in -index 20d134c02..f8cbd545d 100644 +index 78f65948..6c417ef7 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -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 +@@ -110,7 +110,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ + ssh-ed25519-sk.o ssh-rsa.o dh.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o \ + hmac.o ed25519.o hash.o \ +@@ -339,6 +339,8 @@ clean: regressclean rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8$(EXEEXT) @@ -62,7 +48,7 @@ index 20d134c02..f8cbd545d 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) -@@ -369,6 +371,8 @@ distclean: regressclean +@@ -377,6 +379,8 @@ distclean: regressclean rm -f regress/unittests/sshsig/test_sshsig rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 @@ -71,7 +57,7 @@ index 20d134c02..f8cbd545d 100644 rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -549,6 +553,7 @@ regress-prep: +@@ -558,6 +562,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshkey $(MKDIR_P) `pwd`/regress/unittests/sshsig $(MKDIR_P) `pwd`/regress/unittests/utf8 @@ -79,7 +65,7 @@ index 20d134c02..f8cbd545d 100644 $(MKDIR_P) `pwd`/regress/misc/sk-dummy $(MKDIR_P) `pwd`/regress/misc/ssh-verify-attestation [ -f `pwd`/regress/Makefile ] || \ -@@ -724,6 +729,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ +@@ -731,6 +736,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) @@ -87,16 +73,16 @@ index 20d134c02..f8cbd545d 100644 + regress/unittests/pkcs11/tests.o + +regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} ssh-pkcs11-uri.o \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ + regress/unittests/test_helper/libtest_helper.a libssh.a + $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ + regress/unittests/test_helper/libtest_helper.a \ -+ ssh-pkcs11-uri.o -lssh -lopenbsd-compat -lcrypto $(LIBS) -lm ++ -lssh -lopenbsd-compat -lcrypto $(LIBS) + # These all need to be compiled -fPIC, so they are treated differently. SK_DUMMY_OBJS=\ regress/misc/sk-dummy/sk-dummy.lo \ -@@ -769,7 +784,8 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ +@@ -776,7 +791,8 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ regress/unittests/sshkey/test_sshkey$(EXEEXT) \ regress/unittests/sshsig/test_sshsig$(EXEEXT) \ @@ -107,10 +93,10 @@ index 20d134c02..f8cbd545d 100644 tests: file-tests t-exec interop-tests extra-tests unit echo all tests passed diff --git a/configure.ac b/configure.ac -index 9d3b19925..e33462027 100644 +index 13c70a98..d9bd2f51 100644 --- a/configure.ac +++ b/configure.ac -@@ -2246,12 +2246,14 @@ AC_LINK_IFELSE( +@@ -2172,12 +2172,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -125,7 +111,7 @@ index 9d3b19925..e33462027 100644 fi ] ) -@@ -2281,6 +2283,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2207,6 +2209,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -166,7 +152,7 @@ index 9d3b19925..e33462027 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5904,6 +5940,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" +@@ -5820,6 +5856,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" @@ -175,10 +161,10 @@ index 9d3b19925..e33462027 100644 echo "" diff --git a/regress/Makefile b/regress/Makefile -index ece093a2b..a851549f6 100644 +index 7e7f95b5..f36de51e 100644 --- a/regress/Makefile +++ b/regress/Makefile -@@ -139,7 +139,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ +@@ -137,7 +137,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 \ @@ -188,17 +174,21 @@ index ece093a2b..a851549f6 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 \ -@@ -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}; \ +@@ -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 ; \ diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh new file mode 100644 -index 000000000..a91aee94f +index 00000000..a91aee94 --- /dev/null +++ b/regress/pkcs11.sh @@ -0,0 +1,349 @@ @@ -552,7 +542,7 @@ index 000000000..a91aee94f + ${SSHAGENT} -k > /dev/null +fi diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index e370900e4..d6c89c129 100644 +index e370900e..d6c89c12 100644 --- a/regress/unittests/Makefile +++ b/regress/unittests/Makefile @@ -1,6 +1,6 @@ @@ -565,10 +555,10 @@ index e370900e4..d6c89c129 100644 .include diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c new file mode 100644 -index 000000000..89ba45c4e +index 00000000..7d4fa499 --- /dev/null +++ b/regress/unittests/pkcs11/tests.c -@@ -0,0 +1,353 @@ +@@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -915,27 +905,20 @@ index 000000000..89ba45c4e + test_parse_invalid(); + test_generate_valid(); +} -+ -+void -+benchmarks(void) -+{ -+ printf("no benchmarks\n"); -+} -+ diff --git a/ssh-add.c b/ssh-add.c -index 2d5bec89c..aae82a794 100644 +index 0035cb84..b0f47f4d 100644 --- a/ssh-add.c +++ b/ssh-add.c -@@ -70,6 +70,7 @@ +@@ -69,6 +69,7 @@ #include "ssh-sk.h" #include "sk-api.h" #include "hostfile.h" +#include "ssh-pkcs11-uri.h" - #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); + /* argv0 */ + extern char *__progname; +@@ -242,6 +243,38 @@ delete_all(int agent_fd, int qflag) + return ret; } +#ifdef ENABLE_PKCS11 @@ -972,8 +955,8 @@ index 2d5bec89c..aae82a794 100644 + static int add_file(int agent_fd, const char *filename, int key_only, int cert_only, - int qflag, int Nflag, const char *skprovider, -@@ -447,15 +480,14 @@ static int + int qflag, const char *skprovider, +@@ -462,15 +495,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, @@ -991,8 +974,8 @@ index 2d5bec89c..aae82a794 100644 if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -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, +@@ -658,6 +690,14 @@ do_file(int agent_fd, int deleting, int key_only, int cert_only, + char *file, int qflag, const char *skprovider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { +#ifdef ENABLE_PKCS11 @@ -1006,20 +989,20 @@ index 2d5bec89c..aae82a794 100644 if (deleting) { if (delete_file(agent_fd, file, key_only, cert_only, qflag) == -1) -@@ -1009,7 +1049,7 @@ main(int argc, char **argv) +@@ -1001,7 +1041,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; - for (n = 0; n < ncerts; n++) - sshkey_free(certs[n]); + goto done; + } diff --git a/ssh-agent.c b/ssh-agent.c -index dc246066d..c3e94e2b1 100644 +index c27c5a95..798bf9b6 100644 --- a/ssh-agent.c +++ b/ssh-agent.c -@@ -1540,10 +1540,75 @@ add_p11_identity(struct sshkey *key, char *comment, const char *provider, +@@ -1569,10 +1569,74 @@ add_p11_identity(struct sshkey *key, char *comment, const char *provider, idtab->nentries++; } @@ -1047,7 +1030,6 @@ index dc246066d..c3e94e2b1 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 */ @@ -1096,7 +1078,7 @@ index dc246066d..c3e94e2b1 100644 char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; -@@ -1572,25 +1637,18 @@ process_add_smartcard_key(SocketEntry *e) +@@ -1601,25 +1665,18 @@ process_add_smartcard_key(SocketEntry *e) "providers is disabled", provider); goto send; } @@ -1127,7 +1109,7 @@ index dc246066d..c3e94e2b1 100644 } for (j = 0; j < ncerts; j++) { if (!sshkey_is_cert(certs[j])) -@@ -1600,13 +1658,13 @@ process_add_smartcard_key(SocketEntry *e) +@@ -1629,13 +1686,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]), @@ -1143,7 +1125,7 @@ index dc246066d..c3e94e2b1 100644 dest_constraints, ndest_constraints); keys[i] = NULL; /* transferred */ comments[i] = NULL; /* transferred */ -@@ -1619,6 +1677,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -1648,6 +1705,7 @@ process_add_smartcard_key(SocketEntry *e) send: free(pin); free(provider); @@ -1151,7 +1133,7 @@ index dc246066d..c3e94e2b1 100644 free(keys); free(comments); free_dest_constraints(dest_constraints, ndest_constraints); -@@ -1631,7 +1690,7 @@ send: +@@ -1660,7 +1718,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1160,7 +1142,7 @@ index dc246066d..c3e94e2b1 100644 int r, success = 0; Identity *id, *nxt; -@@ -1643,30 +1702,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -1672,30 +1730,29 @@ process_remove_smartcard_key(SocketEntry *e) } free(pin); @@ -1198,10 +1180,10 @@ index dc246066d..c3e94e2b1 100644 } #endif /* ENABLE_PKCS11 */ diff --git a/ssh-keygen.c b/ssh-keygen.c -index afa279097..7af08fcdf 100644 +index 89c3ed28..16cff947 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c -@@ -831,8 +831,11 @@ do_download(struct passwd *pw) +@@ -906,8 +906,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1216,30 +1198,10 @@ index afa279097..7af08fcdf 100644 free(comments[i]); sshkey_free(keys[i]); diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c -index 85afb62ac..7b7eaf533 100644 +index b8d1700f..64df695e 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c -@@ -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, +@@ -635,6 +635,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, struct sshbuf *msg; struct helper *helper; @@ -1248,17 +1210,17 @@ index 85afb62ac..7b7eaf533 100644 if ((helper = helper_by_provider(name)) == NULL && (helper = pkcs11_start_helper(name)) == NULL) return -1; -@@ -413,6 +429,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +@@ -655,6 +657,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 = sshkey_froms(msg, &k)) != 0 || + if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c new file mode 100644 -index 000000000..8bd97e9e2 +index 00000000..8bd97e9e --- /dev/null +++ b/ssh-pkcs11-uri.c @@ -0,0 +1,437 @@ @@ -1701,7 +1663,7 @@ index 000000000..8bd97e9e2 +#endif /* ENABLE_PKCS11 */ diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h new file mode 100644 -index 000000000..29e9f7327 +index 00000000..29e9f732 --- /dev/null +++ b/ssh-pkcs11-uri.h @@ -0,0 +1,43 @@ @@ -1749,26 +1711,18 @@ index 000000000..29e9f7327 +char *pkcs11_uri_get(struct pkcs11_uri *uri); + diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index c88179473..1a443824d 100644 +index 31b9360f..b96f5b89 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c -@@ -39,6 +39,7 @@ +@@ -38,6 +38,7 @@ #include #include #include +#include - #endif #define CRYPTOKI_COMPAT -@@ -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 { + #include "pkcs11.h" +@@ -55,8 +56,8 @@ struct pkcs11_slotinfo { int logged_in; }; @@ -1779,7 +1733,7 @@ index c88179473..1a443824d 100644 void *handle; CK_FUNCTION_LIST *function_list; CK_INFO info; -@@ -71,6 +73,13 @@ struct pkcs11_provider { +@@ -65,6 +66,13 @@ struct pkcs11_provider { struct pkcs11_slotinfo *slotinfo; int valid; int refcount; @@ -1793,15 +1747,15 @@ index c88179473..1a443824d 100644 TAILQ_ENTRY(pkcs11_provider) next; }; -@@ -82,6 +91,7 @@ struct pkcs11_key { +@@ -75,6 +83,7 @@ struct pkcs11_key { CK_ULONG slotidx; char *keyid; int keyid_len; + char *label; - TAILQ_ENTRY(pkcs11_key) next; }; -@@ -108,26 +118,61 @@ ossl_error(const char *msg) + int pkcs11_interactive = 0; +@@ -106,26 +115,61 @@ pkcs11_init(int interactive) * this is called when a provider gets unregistered. */ static void @@ -1874,7 +1828,7 @@ index c88179473..1a443824d 100644 } /* -@@ -139,15 +184,27 @@ pkcs11_provider_unref(struct pkcs11_provider *p) +@@ -137,11 +181,9 @@ pkcs11_provider_unref(struct pkcs11_provider *p) { debug_f("provider \"%s\" refcount %d", p->name, p->refcount); if (--p->refcount <= 0) { @@ -1888,6 +1842,9 @@ index c88179473..1a443824d 100644 free(p); } } +@@ -159,6 +201,20 @@ pkcs11_terminate(void) + } + } +/* lookup provider by module path */ +static struct pkcs11_module * @@ -1906,7 +1863,7 @@ index c88179473..1a443824d 100644 /* lookup provider by name */ static struct pkcs11_provider * pkcs11_provider_lookup(char *provider_id) -@@ -162,19 +219,55 @@ pkcs11_provider_lookup(char *provider_id) +@@ -173,19 +229,55 @@ pkcs11_provider_lookup(char *provider_id) return (NULL); } @@ -1964,113 +1921,10 @@ index c88179473..1a443824d 100644 + return rv; } - /* 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; - } + static RSA_METHOD *rsa_method; +@@ -195,6 +287,60 @@ static EC_KEY_METHOD *ec_key_method; + static int ec_key_idx = 0; + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ +/* + * This can't be in the ssh-pkcs11-uri, becase we can not depend on @@ -2081,8 +1935,26 @@ index c88179473..1a443824d 100644 +{ + char *p = NULL; + struct pkcs11_uri uri; -+ struct pkcs11_key *k11 = pkcs11_lookup_key(key); ++ struct pkcs11_key *k11; + ++ /* sanity - is it a RSA key with associated app_data? */ ++ switch (key->type) { ++ case KEY_RSA: { ++ const RSA *rsa = EVP_PKEY_get0_RSA(key->pkey); ++ k11 = RSA_get_ex_data(rsa, rsa_idx); ++ break; ++ } ++#ifdef HAVE_EC_KEY_METHOD_NEW ++ case KEY_ECDSA: { ++ const EC_KEY * ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); ++ k11 = EC_KEY_get_ex_data(ecdsa, ec_key_idx); ++ break; ++ } ++#endif ++ default: ++ error("Unknown key type %d", key->type); ++ return -1; ++ } + if (k11 == NULL) { + error("Failed to get ex_data for key type %d", key->type); + return (-1); @@ -2108,11 +1980,72 @@ index c88179473..1a443824d 100644 + return 0; +} + - #ifdef WITH_OPENSSL - /* - * See: -@@ -571,8 +710,8 @@ pkcs11_sign_rsa(struct sshkey *key, - return SSH_ERR_AGENT_FAILURE; + /* release a wrapped object */ + static void + pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, +@@ -208,6 +354,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ free(k11->label); + free(k11); + } + +@@ -222,8 +369,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, + CK_RV rv; + int ret = -1; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { + error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); + return (-1); +@@ -260,14 +407,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) + verbose("Deferring PIN entry to reader keypad."); + else { +- snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", ++ snprintf(prompt, sizeof(prompt), "Enter PIN for '%.32s': ", + si->token.label); +- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { ++ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { + debug_f("no pin specified"); + return (-1); /* bail out */ + } + } +- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, ++ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, + (pin != NULL) ? strlen(pin) : 0); + if (pin != NULL) + freezero(pin, strlen(pin)); +@@ -297,13 +444,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + static int + pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) + { +- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { ++ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || ++ k11->provider->module == NULL || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + + return pkcs11_login_slot(k11->provider, +- &k11->provider->slotinfo[k11->slotidx], type); ++ &k11->provider->module->slotinfo[k11->slotidx], type); + } + + +@@ -319,13 +467,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, + + *val = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); } - f = k11->provider->function_list; @@ -2120,33 +2053,95 @@ index c88179473..1a443824d 100644 + 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); + 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]; - /* 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); + 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]; - xdata = xmalloc(datalen); - memcpy(xdata, data, datalen); -@@ -775,7 +914,8 @@ pkcs11_sign_ed25519(struct sshkey *key, - return ret; + 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 @@ -2154,7 +2149,7 @@ index c88179473..1a443824d 100644 static char * rmspace(u_char *buf, size_t len) { -@@ -807,8 +947,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, +@@ -658,8 +821,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, CK_SESSION_HANDLE session; int login_required, ret; @@ -2165,7 +2160,7 @@ index c88179473..1a443824d 100644 login_required = si->token.flags & CKF_LOGIN_REQUIRED; -@@ -818,9 +958,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, +@@ -669,9 +832,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -2177,7 +2172,7 @@ index c88179473..1a443824d 100644 return (-1); } if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -857,7 +997,8 @@ static struct sshkey * +@@ -707,7 +870,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2187,7 +2182,7 @@ index c88179473..1a443824d 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -870,14 +1011,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -721,14 +885,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2208,7 +2203,7 @@ index c88179473..1a443824d 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -888,19 +1030,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -739,19 +904,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -2232,7 +2227,7 @@ index c88179473..1a443824d 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -912,8 +1054,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -763,8 +928,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2243,7 +2238,7 @@ index c88179473..1a443824d 100644 if (group == NULL) { ossl_error("d2i_ECPKParameters failed"); goto fail; -@@ -924,13 +1066,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -775,13 +940,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2260,7 +2255,25 @@ index c88179473..1a443824d 100644 if (octet == NULL) { ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; -@@ -992,7 +1134,8 @@ static struct sshkey * +@@ -798,7 +963,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto fail; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -817,7 +982,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + key->flags |= SSHKEY_FLAG_EXT; + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + if (ec) + EC_KEY_free(ec); +@@ -834,7 +999,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2270,7 +2283,7 @@ index c88179473..1a443824d 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1003,14 +1146,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -845,14 +1011,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2291,7 +2304,7 @@ index c88179473..1a443824d 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -1021,19 +1165,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -863,19 +1030,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -2315,7 +2328,7 @@ index c88179473..1a443824d 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -1045,8 +1189,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -887,8 +1054,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2326,112 +2339,25 @@ index c88179473..1a443824d 100644 if (rsa_n == NULL || rsa_e == NULL) { error("BN_bin2bn failed"); goto fail; -@@ -1078,7 +1222,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - /* success */ - success = 0; +@@ -897,7 +1064,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + fatal_f("set key"); + rsa_n = rsa_e = NULL; /* transferred */ + +- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -915,7 +1082,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + key->flags |= SSHKEY_FLAG_EXT; + fail: - for (i = 0; i < 3; i++) + for (i = 0; i < nattr; i++) free(key_attr[i].pValue); RSA_free(rsa); - 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, - 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 +@@ -926,7 +1093,8 @@ static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) { @@ -2441,7 +2367,7 @@ index c88179473..1a443824d 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1229,14 +1376,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -950,14 +1118,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -2462,7 +2388,7 @@ index c88179473..1a443824d 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return -1; -@@ -1248,18 +1396,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -969,18 +1138,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2485,7 +2411,7 @@ index c88179473..1a443824d 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto out; -@@ -1273,8 +1422,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -994,8 +1164,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, subject = xstrdup("invalid subject"); X509_NAME_free(x509_name); @@ -2496,7 +2422,25 @@ index c88179473..1a443824d 100644 error("d2i_x509 failed"); goto out; } -@@ -1384,7 +1533,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1015,7 +1185,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; + } + +- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1048,7 +1218,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + goto out; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1071,7 +1241,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto out; } out: @@ -2505,7 +2449,7 @@ index c88179473..1a443824d 100644 free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1427,11 +1576,12 @@ note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, +@@ -1122,11 +1292,12 @@ note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, */ static int pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2520,7 +2464,7 @@ index c88179473..1a443824d 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1448,10 +1598,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1143,10 +1314,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2538,16 +2482,16 @@ index c88179473..1a443824d 100644 + key_attr[nattr].ulValueLen = strlen(uri->object); + nattr++; + } - -- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ + session = p->module->slotinfo[slotidx].session; + f = p->module->function_list; -+ + +- rv = f->C_FindObjectsInit(session, key_attr, 1); + rv = f->C_FindObjectsInit(session, key_attr, nattr); if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1533,11 +1696,12 @@ fail: +@@ -1227,11 +1411,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2562,7 +2506,7 @@ index c88179473..1a443824d 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1553,10 +1717,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1247,10 +1432,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2589,7 +2533,7 @@ index c88179473..1a443824d 100644 if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1844,16 +2021,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1532,16 +1730,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, } #endif /* WITH_PKCS11_KEYGEN */ @@ -2608,7 +2552,7 @@ index c88179473..1a443824d 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1862,128 +2033,126 @@ pkcs11_register_provider(char *provider_id, char *pin, +@@ -1550,162 +1742,309 @@ pkcs11_register_provider(char *provider_id, char *pin, CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2699,6 +2643,13 @@ index c88179473..1a443824d 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" @@ -2711,13 +2662,6 @@ index c88179473..1a443824d 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", @@ -2770,6 +2714,7 @@ index c88179473..1a443824d 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> " @@ -2780,77 +2725,39 @@ index c88179473..1a443824d 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; -@@ -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); ++ ++ /* now owned by caller */ ++ *providerp = p; ++ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ + return 0; - fail: - if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) - error("C_Finalize for provider %s failed: %lu", -- provider_id, rv); ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", + provider_module, rv); + free(provider_module); + if (m) { + free(m->slotlist); + free(m); + } - if (p) { - free(p->name); -- free(p->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 ++ if (p) { ++ free(p->name); ++ free(p); ++ } ++ if (handle) ++ dlclose(handle); ++ return (ret); ++} ++ ++/* + * register a new provider, fails if provider already exists. if + * keyp is provided, fetch keys. - */ ++ */ +static int +pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, + struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, @@ -2912,28 +2819,37 @@ index c88179473..1a443824d 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; + keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +- if (nkeys == 0 && !p->slotinfo[i].logged_in && + pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); + pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + if (nkeys == 0 && !p->module->slotinfo[i].logged_in && -+ pkcs11_interactive) { -+ /* -+ * Some tokens require login before they will -+ * expose keys. -+ */ + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], + debug3_f("Trying to login as there were no keys found"); + if (pkcs11_login_slot(p, &p->module->slotinfo[i], -+ CKU_USER) < 0) { -+ error("login failed"); -+ continue; -+ } + CKU_USER) < 0) { + error("login failed"); + continue; + } +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); + pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); + pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + } @@ -2946,25 +2862,41 @@ index c88179473..1a443824d 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; -+ + + /* now owned by caller */ + *providerp = p; + +- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); +- p->refcount++; /* add to provider list */ +- + free(provider_uri); -+ return (nkeys); -+ fail: -+ if (p) { + return (nkeys); + fail: +- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->name); +- free(p->slotlist); +- free(p->slotinfo); +- free(p); + TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); -+ } -+ if (ret > 0) -+ ret = -1; -+ return (ret); -+} -+ ++ pkcs11_provider_unref(p); + } +- if (handle) +- dlclose(handle); + if (ret > 0) + ret = -1; + return (ret); + } + +-/* +- * register a new provider and get number of keys hold by the token, +- * fails if provider already exists +- */ +static int +pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, + char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) @@ -3010,17 +2942,21 @@ index c88179473..1a443824d 100644 /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -2061,11 +2374,38 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, +@@ -1714,7 +2053,37 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, pkcs11_provider_unref(p); } if (nkeys == 0) - debug_f("provider %s returned no keys", provider_id); + debug_f("provider %s returned no keys", provider_uri); - ++ + free(provider_uri); - return (nkeys); - } - ++ return nkeys; ++} ++ ++/* ++ * register a new provider and get number of keys hold by the token, ++ * fails if provider already exists ++ */ +int +pkcs11_add_provider(char *provider_id, char *pin, + struct sshkey ***keyp, char ***labelsp) @@ -3042,40 +2978,33 @@ index c88179473..1a443824d 100644 + + nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); + pkcs11_uri_cleanup(uri); -+ -+ return (nkeys); -+} -+ -+ - int - pkcs11_sign(struct sshkey *key, - u_char **sigp, size_t *lenp, + + return (nkeys); + } diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h -index d86c506c1..32f2d0ccf 100644 +index 52602231..9ce20c1f 100644 --- a/ssh-pkcs11.h +++ b/ssh-pkcs11.h -@@ -22,12 +22,16 @@ +@@ -22,10 +22,14 @@ #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 *); - int pkcs11_sign(struct sshkey *, u_char **, size_t *, - const u_char *, size_t, const char *, const char *, - const char *, u_int); + #ifdef WITH_PKCS11_KEYGEN + struct sshkey * + pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, diff --git a/ssh.c b/ssh.c -index 320ac6834..14965a4f1 100644 +index c23d3b9e..98b103c9 100644 --- a/ssh.c +++ b/ssh.c -@@ -904,6 +904,14 @@ main(int ac, char **av) +@@ -890,6 +890,14 @@ main(int ac, char **av) options.gss_deleg_creds = 1; break; case 'i': @@ -3090,15 +3019,15 @@ index 320ac6834..14965a4f1 100644 p = tilde_expand_filename(optarg, getuid()); if (stat(p, &st) == -1) fprintf(stderr, "Warning: Identity file %s " -@@ -1872,6 +1880,7 @@ main(int ac, char **av) +@@ -1847,6 +1855,7 @@ main(int ac, char **av) #ifdef ENABLE_PKCS11 (void)pkcs11_del_provider(options.pkcs11_provider); #endif + pkcs11_terminate(); skip_connect: - if (addrs != NULL) -@@ -2387,6 +2396,45 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) + exit_status = ssh_session2(ssh, cinfo); +@@ -2370,6 +2379,45 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -3144,7 +3073,7 @@ index 320ac6834..14965a4f1 100644 /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2401,11 +2449,6 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2384,11 +2432,6 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; @@ -3156,7 +3085,7 @@ index 320ac6834..14965a4f1 100644 n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2418,33 +2461,46 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2401,33 +2444,46 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -3223,10 +3152,10 @@ index 320ac6834..14965a4f1 100644 free(cp); check_load(sshkey_load_public(filename, &public, NULL), diff --git a/ssh_config.5 b/ssh_config.5 -index a06fbfa11..717b0938a 100644 +index 3a8e246c..8d5d0722 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -1260,6 +1260,21 @@ may also be used in conjunction with +@@ -1263,6 +1263,21 @@ may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. @@ -3249,5 +3178,5 @@ index a06fbfa11..717b0938a 100644 Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. -- -2.52.0 +2.49.0 diff --git a/0025-openssh-7.8p1-scp-ipv6.patch b/0029-openssh-7.8p1-scp-ipv6.patch similarity index 74% rename from 0025-openssh-7.8p1-scp-ipv6.patch rename to 0029-openssh-7.8p1-scp-ipv6.patch index d1eb51a..dbd69aa 100644 --- a/0025-openssh-7.8p1-scp-ipv6.patch +++ b/0029-openssh-7.8p1-scp-ipv6.patch @@ -1,17 +1,17 @@ -From e1d86d265d9543c77fa90a33acc70246e68bf3bf Mon Sep 17 00:00:00 2001 +From 507e6f245557ae7261806f7ecbd40697cb0dd389 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 25/53] openssh-7.8p1-scp-ipv6 +Subject: [PATCH 29/50] openssh-7.8p1-scp-ipv6 --- scp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scp.c b/scp.c -index e1992622f..621131ffc 100644 +index 9554b188..7f9795a5 100644 --- a/scp.c +++ b/scp.c -@@ -1169,7 +1169,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) +@@ -1183,7 +1183,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 e1992622f..621131ffc 100644 thost, targ); if (do_local_cmd(&alist) != 0) -- -2.52.0 +2.49.0 diff --git a/0026-openssh-8.0p1-crypto-policies.patch b/0030-openssh-8.0p1-crypto-policies.patch similarity index 96% rename from 0026-openssh-8.0p1-crypto-policies.patch rename to 0030-openssh-8.0p1-crypto-policies.patch index 5162ffa..498e3f5 100644 --- a/0026-openssh-8.0p1-crypto-policies.patch +++ b/0030-openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,7 @@ -From 6d9e08f061451f6cd464af5ec598fa99d15acadb Mon Sep 17 00:00:00 2001 +From b436140fe3abd9f97f01f9af9f5da5cf6c5d7725 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 26/53] openssh-8.0p1-crypto-policies +Subject: [PATCH 30/50] openssh-8.0p1-crypto-policies --- ssh_config.5 | 164 ++++++++++++++++++++------------------------- @@ -9,7 +9,7 @@ Subject: [PATCH 26/53] openssh-8.0p1-crypto-policies 2 files changed, 140 insertions(+), 203 deletions(-) diff --git a/ssh_config.5 b/ssh_config.5 -index 8a4b469cf..8ac5e1633 100644 +index 8d5d0722..a43b2a27 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -438,17 +438,13 @@ A single argument of @@ -166,7 +166,7 @@ index 8a4b469cf..8ac5e1633 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 -@@ -1360,6 +1357,11 @@ it may be zero or more of: +@@ -1376,6 +1373,11 @@ it may be zero or more of: and .Cm pam . .It Cm KexAlgorithms @@ -178,7 +178,7 @@ index 8a4b469cf..8ac5e1633 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 -@@ -1368,29 +1370,17 @@ Multiple algorithms must be comma-separated. +@@ -1384,29 +1386,17 @@ Multiple algorithms must be comma-separated. .Pp If the specified list begins with a .Sq + @@ -212,7 +212,7 @@ index 8a4b469cf..8ac5e1633 100644 The list of supported key exchange algorithms may also be obtained using .Qq ssh -Q kex . .It Cm KnownHostsCommand -@@ -1506,37 +1496,33 @@ function, and all code in the +@@ -1522,37 +1512,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 8a4b469cf..8ac5e1633 100644 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1725,39 +1711,31 @@ instead of continuing to execute and pass data. +@@ -1741,39 +1727,31 @@ instead of continuing to execute and pass data. The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -311,7 +311,7 @@ index 8a4b469cf..8ac5e1633 100644 .It Cm PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be -@@ -2504,7 +2482,9 @@ for those users who do not have a configuration file. +@@ -2497,7 +2475,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 8a4b469cf..8ac5e1633 100644 .An -nosplit OpenSSH is a derivative of the original and free diff --git a/sshd_config.5 b/sshd_config.5 -index a0fc6064f..c172d5aab 100644 +index 26fcdc84..583a01cd 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -379,17 +379,13 @@ If the argument is @@ -497,7 +497,7 @@ index a0fc6064f..c172d5aab 100644 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -1051,6 +1024,11 @@ Specifies whether to look at .k5login file for user's aliases. +@@ -1052,6 +1025,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 a0fc6064f..c172d5aab 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 -@@ -1059,16 +1037,16 @@ Multiple algorithms must be comma-separated. +@@ -1060,16 +1038,16 @@ Multiple algorithms must be comma-separated. .Pp If the specified list begins with a .Sq + @@ -530,7 +530,7 @@ index a0fc6064f..c172d5aab 100644 .Pp The supported algorithms are: .Pp -@@ -1105,14 +1083,6 @@ sntrup761x25519-sha512 +@@ -1106,14 +1084,6 @@ sntrup761x25519-sha512 sntrup761x25519-sha512@openssh.com .El .Pp @@ -545,7 +545,7 @@ index a0fc6064f..c172d5aab 100644 The list of supported key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress -@@ -1199,21 +1169,26 @@ function, and all code in the +@@ -1200,21 +1170,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 a0fc6064f..c172d5aab 100644 .Pp The algorithms that contain .Qq -etm -@@ -1256,15 +1231,6 @@ umac-64-etm@openssh.com +@@ -1257,15 +1232,6 @@ umac-64-etm@openssh.com umac-128-etm@openssh.com .El .Pp @@ -592,7 +592,7 @@ index a0fc6064f..c172d5aab 100644 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1751,36 +1717,25 @@ or equivalent.) +@@ -1753,36 +1719,25 @@ or equivalent.) The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms @@ -638,7 +638,7 @@ index a0fc6064f..c172d5aab 100644 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -@@ -2281,7 +2236,9 @@ This file should be writable by root only, but it is recommended +@@ -2289,7 +2244,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 a0fc6064f..c172d5aab 100644 .An -nosplit OpenSSH is a derivative of the original and free -- -2.52.0 +2.49.0 diff --git a/0027-openssh-8.0p1-openssl-kdf.patch b/0031-openssh-8.0p1-openssl-kdf.patch similarity index 89% rename from 0027-openssh-8.0p1-openssl-kdf.patch rename to 0031-openssh-8.0p1-openssl-kdf.patch index 6f7f49b..529940f 100644 --- a/0027-openssh-8.0p1-openssl-kdf.patch +++ b/0031-openssh-8.0p1-openssl-kdf.patch @@ -1,7 +1,7 @@ -From d73633dd9770bea0c3802075842398faf3e55e30 Mon Sep 17 00:00:00 2001 +From 430bd33963725beb8ec01a1e581529ae6bf6bec0 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 27/53] openssh-8.0p1-openssl-kdf +Subject: [PATCH 31/50] openssh-8.0p1-openssl-kdf --- configure.ac | 1 + @@ -9,10 +9,10 @@ Subject: [PATCH 27/53] openssh-8.0p1-openssl-kdf 2 files changed, 108 insertions(+) diff --git a/configure.ac b/configure.ac -index adccaebd4..805be4b5e 100644 +index d9bd2f51..d92a8580 100644 --- a/configure.ac +++ b/configure.ac -@@ -3182,6 +3182,7 @@ if test "x$openssl" = "xyes" ; then +@@ -3137,6 +3137,7 @@ if test "x$openssl" = "xyes" ; then HMAC_CTX_init \ RSA_generate_key_ex \ RSA_get_default_method \ @@ -21,10 +21,10 @@ index adccaebd4..805be4b5e 100644 # OpenSSL_add_all_algorithms may be a macro. diff --git a/kex.c b/kex.c -index 9a2ce6d88..5f9530908 100644 +index 19a56e8e..8b200ff4 100644 --- a/kex.c +++ b/kex.c -@@ -38,6 +38,11 @@ +@@ -40,6 +40,11 @@ #ifdef WITH_OPENSSL #include #include @@ -36,7 +36,7 @@ index 9a2ce6d88..5f9530908 100644 #endif #include "ssh.h" -@@ -1077,6 +1082,107 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -1078,6 +1083,107 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) return r; } @@ -144,7 +144,7 @@ index 9a2ce6d88..5f9530908 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) -@@ -1140,6 +1246,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, +@@ -1141,6 +1247,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 9a2ce6d88..5f9530908 100644 #define NKEYS 6 int -- -2.52.0 +2.49.0 diff --git a/0028-openssh-8.2p1-visibility.patch b/0032-openssh-8.2p1-visibility.patch similarity index 75% rename from 0028-openssh-8.2p1-visibility.patch rename to 0032-openssh-8.2p1-visibility.patch index 7c5eabf..c67373c 100644 --- a/0028-openssh-8.2p1-visibility.patch +++ b/0032-openssh-8.2p1-visibility.patch @@ -1,17 +1,17 @@ -From ed5e5df9ec7ac96ac2a68c5711db00ed29d4d1cd Mon Sep 17 00:00:00 2001 +From 6aa231d9acfeca870ee87e3bf9c4a1239518706d Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 28/53] openssh-8.2p1-visibility +Subject: [PATCH 32/50] openssh-8.2p1-visibility --- regress/misc/sk-dummy/sk-dummy.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c -index 4c96e8827..4af5209db 100644 +index 347b2122..344f8a8a 100644 --- a/regress/misc/sk-dummy/sk-dummy.c +++ b/regress/misc/sk-dummy/sk-dummy.c -@@ -80,7 +80,7 @@ skdebug(const char *func, const char *fmt, ...) +@@ -81,7 +81,7 @@ skdebug(const char *func, const char *fmt, ...) #endif } @@ -20,7 +20,7 @@ index 4c96e8827..4af5209db 100644 sk_api_version(void) { return SSH_SK_VERSION_MAJOR; -@@ -229,7 +229,7 @@ check_options(struct sk_option **options) +@@ -230,7 +230,7 @@ check_options(struct sk_option **options) return 0; } @@ -29,7 +29,7 @@ index 4c96e8827..4af5209db 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) -@@ -477,7 +477,7 @@ sig_ed25519(const uint8_t *message, size_t message_len, +@@ -478,7 +478,7 @@ sig_ed25519(const uint8_t *message, size_t message_len, return ret; } @@ -38,7 +38,7 @@ index 4c96e8827..4af5209db 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, -@@ -534,7 +534,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, +@@ -535,7 +535,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, return ret; } @@ -48,5 +48,5 @@ index 4c96e8827..4af5209db 100644 struct sk_resident_key ***rks, size_t *nrks) { -- -2.52.0 +2.49.0 diff --git a/0029-openssh-8.2p1-x11-without-ipv6.patch b/0033-openssh-8.2p1-x11-without-ipv6.patch similarity index 75% rename from 0029-openssh-8.2p1-x11-without-ipv6.patch rename to 0033-openssh-8.2p1-x11-without-ipv6.patch index 7063d7f..32a9056 100644 --- a/0029-openssh-8.2p1-x11-without-ipv6.patch +++ b/0033-openssh-8.2p1-x11-without-ipv6.patch @@ -1,17 +1,17 @@ -From c8dce0615eac6d2a724cdb3f288d7aaa1362f65b Mon Sep 17 00:00:00 2001 +From cfe5a99d335eb57b8c08b4eb6b4535dd042d96e3 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:28 +0200 -Subject: [PATCH 29/53] openssh-8.2p1-x11-without-ipv6 +Subject: [PATCH 33/50] openssh-8.2p1-x11-without-ipv6 --- channels.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/channels.c b/channels.c -index 5ce6bd400..26ed9945f 100644 +index 7438c1a5..95836d50 100644 --- a/channels.c +++ b/channels.c -@@ -5123,6 +5123,16 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +@@ -5055,6 +5055,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 5ce6bd400..26ed9945f 100644 close(socks[n]); num_socks = 0; -- -2.52.0 +2.49.0 diff --git a/0030-openssh-8.0p1-preserve-pam-errors.patch b/0034-openssh-8.0p1-preserve-pam-errors.patch similarity index 79% rename from 0030-openssh-8.0p1-preserve-pam-errors.patch rename to 0034-openssh-8.0p1-preserve-pam-errors.patch index 4aa2ffb..15e59c2 100644 --- a/0030-openssh-8.0p1-preserve-pam-errors.patch +++ b/0034-openssh-8.0p1-preserve-pam-errors.patch @@ -1,17 +1,17 @@ -From a3b6182e1d6b69a37a6c841baa43b818251036b1 Mon Sep 17 00:00:00 2001 +From 8de0391e3b3eb75e23ee9f173f04a9c78f2b96c9 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 30/53] openssh-8.0p1-preserve-pam-errors +Subject: [PATCH 34/50] openssh-8.0p1-preserve-pam-errors --- auth-pam.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/auth-pam.c b/auth-pam.c -index 70bcae83a..70b2b8580 100644 +index b4100ea1..a042c3c8 100644 --- a/auth-pam.c +++ b/auth-pam.c -@@ -551,7 +551,11 @@ sshpam_thread(void *ctxtp) +@@ -523,7 +523,11 @@ sshpam_thread(void *ctxtp) goto auth_fail; if (!do_pam_account()) { @@ -24,9 +24,9 @@ index 70bcae83a..70b2b8580 100644 goto auth_fail; } if (sshpam_authctxt->force_pwchange) { -@@ -608,8 +612,10 @@ sshpam_thread(void *ctxtp) +@@ -580,8 +584,10 @@ sshpam_thread(void *ctxtp) pam_strerror(sshpam_handle, sshpam_err))) != 0) - fatal_fr(r, "buffer error"); + fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* 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 70bcae83a..70b2b8580 100644 else if (sshpam_maxtries_reached) ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer); else -@@ -913,9 +919,11 @@ sshpam_query(void *ctx, char **name, char **info, +@@ -890,9 +896,11 @@ sshpam_query(void *ctx, char **name, char **info, free(msg); break; case PAM_ACCT_EXPIRED: @@ -52,5 +52,5 @@ index 70bcae83a..70b2b8580 100644 sshpam_set_maxtries_reached(1); /* FALLTHROUGH */ -- -2.52.0 +2.49.0 diff --git a/0031-openssh-8.7p1-scp-kill-switch.patch b/0035-openssh-8.7p1-scp-kill-switch.patch similarity index 75% rename from 0031-openssh-8.7p1-scp-kill-switch.patch rename to 0035-openssh-8.7p1-scp-kill-switch.patch index 5c3594f..58a5036 100644 --- a/0031-openssh-8.7p1-scp-kill-switch.patch +++ b/0035-openssh-8.7p1-scp-kill-switch.patch @@ -1,7 +1,7 @@ -From ca8b4de1019b859e2c68288a554d1905a6cf029f Mon Sep 17 00:00:00 2001 +From a68f3741fdc01bf6823a69d2442caba7de9835f9 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 31/53] openssh-8.7p1-scp-kill-switch +Subject: [PATCH 35/50] openssh-8.7p1-scp-kill-switch --- pathnames.h | 1 + @@ -10,11 +10,11 @@ Subject: [PATCH 31/53] openssh-8.7p1-scp-kill-switch 3 files changed, 16 insertions(+) diff --git a/pathnames.h b/pathnames.h -index 0dcc49552..78bba2314 100644 +index 1158bec9..43f0c570 100644 --- a/pathnames.h +++ b/pathnames.h -@@ -40,6 +40,7 @@ - #define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key" +@@ -42,6 +42,7 @@ + #define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" #define _PATH_DH_MODULI SSHDIR "/moduli" +#define _PATH_SCP_KILL_SWITCH SSHDIR "/disable_scp" @@ -22,10 +22,10 @@ index 0dcc49552..78bba2314 100644 #ifndef _PATH_SSH_PROGRAM #define _PATH_SSH_PROGRAM "/usr/bin/ssh" diff --git a/scp.1 b/scp.1 -index 7bce0fe6f..2bb838c7d 100644 +index aa2e2d8b..373d7237 100644 --- a/scp.1 +++ b/scp.1 -@@ -334,6 +334,13 @@ during download or upload. +@@ -331,6 +331,13 @@ during download or upload. By default a 32KB buffer is used. .El .El @@ -40,10 +40,10 @@ index 7bce0fe6f..2bb838c7d 100644 .Ex -std scp .Sh SEE ALSO diff --git a/scp.c b/scp.c -index 621131ffc..3c213f83d 100644 +index 7f9795a5..7ed1a54c 100644 --- a/scp.c +++ b/scp.c -@@ -633,6 +633,14 @@ main(int argc, char **argv) +@@ -649,6 +649,14 @@ main(int argc, char **argv) if (iamremote) mode = MODE_SCP; @@ -59,5 +59,5 @@ index 621131ffc..3c213f83d 100644 fatal("unknown user %u", (u_int) userid); -- -2.52.0 +2.49.0 diff --git a/0032-openssh-8.7p1-recursive-scp.patch b/0036-openssh-8.7p1-recursive-scp.patch similarity index 86% rename from 0032-openssh-8.7p1-recursive-scp.patch rename to 0036-openssh-8.7p1-recursive-scp.patch index adb5e3d..929b408 100644 --- a/0032-openssh-8.7p1-recursive-scp.patch +++ b/0036-openssh-8.7p1-recursive-scp.patch @@ -1,7 +1,7 @@ -From e6478b233cd2298c9e6e6128867421892ff8f0e4 Mon Sep 17 00:00:00 2001 +From 99e1e3af524376788e591ca73387f1ca37e6f5ef Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 32/53] openssh-8.7p1-recursive-scp +Subject: [PATCH 36/50] openssh-8.7p1-recursive-scp --- scp.c | 2 +- @@ -11,10 +11,10 @@ Subject: [PATCH 32/53] openssh-8.7p1-recursive-scp 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/scp.c b/scp.c -index 3c213f83d..78c79a755 100644 +index 7ed1a54c..0c87dd0e 100644 --- a/scp.c +++ b/scp.c -@@ -1378,7 +1378,7 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) +@@ -1388,7 +1388,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 3c213f83d..78c79a755 100644 errs = 1; } diff --git a/sftp-client.c b/sftp-client.c -index 840170ab6..9bf9cc047 100644 +index 9f8ab4af..873dec04 100644 --- a/sftp-client.c +++ b/sftp-client.c -@@ -1001,7 +1001,7 @@ sftp_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, +@@ -1003,7 +1003,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 840170ab6..9bf9cc047 100644 { struct sshbuf *msg; u_int expected_id, count, id; -@@ -1047,11 +1047,43 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) +@@ -1049,11 +1049,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 840170ab6..9bf9cc047 100644 } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); -@@ -1076,9 +1108,9 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) +@@ -1078,9 +1110,9 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) } char * @@ -97,7 +97,7 @@ index 840170ab6..9bf9cc047 100644 } int -@@ -1092,9 +1124,9 @@ sftp_expand_path(struct sftp_conn *conn, const char *path) +@@ -1094,9 +1126,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 840170ab6..9bf9cc047 100644 } int -@@ -2014,7 +2046,7 @@ sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst, +@@ -2016,7 +2048,7 @@ sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst, char *src_canon; int ret; @@ -143,10 +143,10 @@ index 840170ab6..9bf9cc047 100644 from_path); return -1; diff --git a/sftp-client.h b/sftp-client.h -index 873ad3849..fe58651c1 100644 +index 74cdae7d..00ed6630 100644 --- a/sftp-client.h +++ b/sftp-client.h -@@ -112,7 +112,7 @@ int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *); +@@ -111,7 +111,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 873ad3849..fe58651c1 100644 /* Canonicalisation with tilde expansion (requires server extension) */ char *sftp_expand_path(struct sftp_conn *, const char *); -@@ -164,7 +164,7 @@ int sftp_upload(struct sftp_conn *, const char *, const char *, +@@ -163,7 +163,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 873ad3849..fe58651c1 100644 /* * Download a 'from_path' from the 'from' connection and upload it to diff --git a/sftp.c b/sftp.c -index 3b505eea2..2a99698a8 100644 +index bdedd141..322e6d1f 100644 --- a/sftp.c +++ b/sftp.c -@@ -801,7 +801,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst, +@@ -809,7 +809,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 3b505eea2..2a99698a8 100644 err = -1; } else { if (sftp_upload(conn, g.gl_pathv[i], abs_dst, -@@ -1636,7 +1636,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, +@@ -1644,7 +1644,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 3b505eea2..2a99698a8 100644 err = 1; break; } -@@ -2241,7 +2241,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) +@@ -2249,7 +2249,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) } #endif /* USE_LIBEDIT */ @@ -196,5 +196,5 @@ index 3b505eea2..2a99698a8 100644 startdir = xstrdup(remote_path); -- -2.52.0 +2.49.0 diff --git a/0033-openssh-8.7p1-minrsabits.patch b/0037-openssh-8.7p1-minrsabits.patch similarity index 80% rename from 0033-openssh-8.7p1-minrsabits.patch rename to 0037-openssh-8.7p1-minrsabits.patch index fcd994b..59e530b 100644 --- a/0033-openssh-8.7p1-minrsabits.patch +++ b/0037-openssh-8.7p1-minrsabits.patch @@ -1,7 +1,7 @@ -From 14f25e21b4e2c5e625f266fcc9af42c2f89845de Mon Sep 17 00:00:00 2001 +From 286bc4a302b5130f732c857095ae665f7bea01dd Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 33/53] openssh-8.7p1-minrsabits +Subject: [PATCH 37/50] openssh-8.7p1-minrsabits --- readconf.c | 1 + @@ -9,10 +9,10 @@ Subject: [PATCH 33/53] openssh-8.7p1-minrsabits 2 files changed, 2 insertions(+) diff --git a/readconf.c b/readconf.c -index eab734aaf..3f67f4de4 100644 +index 6c04ed43..f340bf50 100644 --- a/readconf.c +++ b/readconf.c -@@ -337,6 +337,7 @@ static struct { +@@ -343,6 +343,7 @@ static struct { { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, { "requiredrsasize", oRequiredRSASize }, @@ -21,10 +21,10 @@ index eab734aaf..3f67f4de4 100644 { "obscurekeystroketiming", oObscureKeystrokeTiming }, { "channeltimeout", oChannelTimeout }, diff --git a/servconf.c b/servconf.c -index b63a7f0b0..ac84b74d9 100644 +index 15c99b30..84891544 100644 --- a/servconf.c +++ b/servconf.c -@@ -778,6 +778,7 @@ static struct { +@@ -788,6 +788,7 @@ static struct { { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, @@ -33,5 +33,5 @@ index b63a7f0b0..ac84b74d9 100644 { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, -- -2.52.0 +2.49.0 diff --git a/0034-openssh-8.7p1-ibmca.patch b/0038-openssh-8.7p1-ibmca.patch similarity index 79% rename from 0034-openssh-8.7p1-ibmca.patch rename to 0038-openssh-8.7p1-ibmca.patch index 803c899..74dd5b5 100644 --- a/0034-openssh-8.7p1-ibmca.patch +++ b/0038-openssh-8.7p1-ibmca.patch @@ -1,14 +1,14 @@ -From e2c0fb233119584b04d61d243cd58433072559c2 Mon Sep 17 00:00:00 2001 +From 26af04432f6404eb03780265a5cce948ecfec8dc Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 34/53] openssh-8.7p1-ibmca +Subject: [PATCH 38/50] openssh-8.7p1-ibmca --- openbsd-compat/bsd-closefrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c -index f61124585..417c20484 100644 +index f6112458..417c2048 100644 --- a/openbsd-compat/bsd-closefrom.c +++ b/openbsd-compat/bsd-closefrom.c @@ -16,7 +16,7 @@ @@ -21,5 +21,5 @@ index f61124585..417c20484 100644 #include #include -- -2.52.0 +2.49.0 diff --git a/0035-openssh-7.6p1-audit.patch b/0039-openssh-7.6p1-audit.patch similarity index 91% rename from 0035-openssh-7.6p1-audit.patch rename to 0039-openssh-7.6p1-audit.patch index 1635f9f..e4f89c7 100644 --- a/0035-openssh-7.6p1-audit.patch +++ b/0039-openssh-7.6p1-audit.patch @@ -1,7 +1,7 @@ -From c64eb340d925f3f7e29bb1c45b7d7b537ffa6197 Mon Sep 17 00:00:00 2001 +From b0505837bfa2dcdf07800634fa80c5cdb78799dc Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 35/53] openssh-7.6p1-audit +Subject: [PATCH 39/50] openssh-7.6p1-audit --- Makefile.in | 2 +- @@ -21,34 +21,34 @@ Subject: [PATCH 35/53] openssh-7.6p1-audit kex.h | 2 + mac.c | 14 +++ mac.h | 1 + - monitor.c | 193 +++++++++++++++++++++++++++-- + monitor.c | 194 +++++++++++++++++++++++++++-- monitor.h | 8 +- monitor_wrap.c | 130 +++++++++++++++++++- monitor_wrap.h | 11 +- packet.c | 98 +++++++++++++-- packet.h | 1 + - session.c | 82 ++++++++++++- + session.c | 83 ++++++++++++- session.h | 10 +- - sshd-session.c | 98 +++++++++++++-- + sshd-session.c | 104 ++++++++++++++-- sshd.c | 10 ++ - 27 files changed, 1251 insertions(+), 103 deletions(-) + 27 files changed, 1258 insertions(+), 104 deletions(-) create mode 100644 auditstub.c diff --git a/Makefile.in b/Makefile.in -index a36eb82ed..20d134c02 100644 +index 6c417ef7..a2942392 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -110,7 +110,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -119,7 +119,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ -- sshbuf-io.o misc-agent.o -+ sshbuf-io.o misc-agent.o auditstub.o +- sshbuf-io.o ++ sshbuf-io.o auditstub.o - P11OBJS= ssh-pkcs11-client.o + SKOBJS= ssh-sk-client.o diff --git a/audit-bsm.c b/audit-bsm.c -index 4bce22c37..a6292cb8f 100644 +index ccfcf6f7..a49abb92 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 4bce22c37..a6292cb8f 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_f("unhandled event %d", event); + debug("%s: unhandled event %d", __func__, event); } } + @@ -121,10 +121,10 @@ index 4bce22c37..a6292cb8f 100644 +} #endif /* BSM */ diff --git a/audit-linux.c b/audit-linux.c -index 954eabe27..4d3e9d41e 100644 +index 3fcbe5c5..d484b82b 100644 --- a/audit-linux.c +++ b/audit-linux.c -@@ -33,29 +33,42 @@ +@@ -33,27 +33,40 @@ #include "log.h" #include "audit.h" @@ -164,8 +164,6 @@ index 954eabe27..4d3e9d41e 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)", @@ -174,7 +172,7 @@ index 954eabe27..4d3e9d41e 100644 saved_errno = errno; close(audit_fd); -@@ -67,9 +80,96 @@ linux_audit_record_event(int uid, const char *username, const char *hostname, +@@ -65,9 +78,96 @@ linux_audit_record_event(int uid, const char *username, const char *hostname, rc = 0; errno = saved_errno; @@ -272,7 +270,7 @@ index 954eabe27..4d3e9d41e 100644 /* Below is the sshd audit API code */ void -@@ -78,49 +178,211 @@ audit_connection_from(const char *host, int port) +@@ -76,49 +176,211 @@ audit_connection_from(const char *host, int port) /* not implemented */ } @@ -381,7 +379,7 @@ index 954eabe27..4d3e9d41e 100644 + ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; default: - debug_f("unhandled event %d", event); + debug("%s: unhandled event %d", __func__, event); break; } } @@ -497,7 +495,7 @@ index 954eabe27..4d3e9d41e 100644 +} #endif /* USE_LINUX_AUDIT */ diff --git a/audit.c b/audit.c -index dd2f03558..d0433c3a0 100644 +index dd2f0355..d0433c3a 100644 --- a/audit.c +++ b/audit.c @@ -34,6 +34,12 @@ @@ -678,7 +676,7 @@ index dd2f03558..d0433c3a0 100644 # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ diff --git a/audit.h b/audit.h -index 38cb5ad31..45d66ccff 100644 +index 38cb5ad3..45d66ccf 100644 --- a/audit.h +++ b/audit.h @@ -26,6 +26,7 @@ @@ -725,7 +723,7 @@ index 38cb5ad31..45d66ccff 100644 #endif /* _SSH_AUDIT_H */ diff --git a/auditstub.c b/auditstub.c new file mode 100644 -index 000000000..639a798df +index 00000000..639a798d --- /dev/null +++ b/auditstub.c @@ -0,0 +1,52 @@ @@ -782,10 +780,10 @@ index 000000000..639a798df +{ +} diff --git a/auth.c b/auth.c -index d25653ee4..38c34298e 100644 +index e4578169..e10e804f 100644 --- a/auth.c +++ b/auth.c -@@ -499,9 +499,6 @@ getpwnamallow(struct ssh *ssh, const char *user) +@@ -501,9 +501,6 @@ getpwnamallow(struct ssh *ssh, const char *user) record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif @@ -796,7 +794,7 @@ index d25653ee4..38c34298e 100644 } if (!allowed_user(ssh, pw)) diff --git a/auth.h b/auth.h -index 391630350..6be52d70b 100644 +index 39163035..6be52d70 100644 --- a/auth.h +++ b/auth.h @@ -215,6 +215,8 @@ struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *); @@ -818,7 +816,7 @@ index 391630350..6be52d70b 100644 FILE *auth_openprincipals(const char *, struct passwd *, int); diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index 976484fc5..e9421a868 100644 +index a3be6e49..8cebaffd 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -157,7 +157,7 @@ userauth_hostbased(struct ssh *ssh, const char *method) @@ -852,10 +850,10 @@ index 976484fc5..e9421a868 100644 int hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index b7300ca9e..9f3371c07 100644 +index 0d5ae0df..99cb810f 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c -@@ -233,7 +233,7 @@ userauth_pubkey(struct ssh *ssh, const char *method) +@@ -235,7 +235,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) && @@ -864,7 +862,7 @@ index b7300ca9e..9f3371c07 100644 sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, ssh->compat, &sig_details) == 0) { -@@ -326,6 +326,20 @@ done: +@@ -328,6 +328,20 @@ done: return authenticated; } @@ -886,7 +884,7 @@ index b7300ca9e..9f3371c07 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 5a4b932a9..da24f7bcb 100644 +index 8ec41de2..4a8515ea 100644 --- a/auth2.c +++ b/auth2.c @@ -310,9 +310,6 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) @@ -900,7 +898,7 @@ index 5a4b932a9..da24f7bcb 100644 #ifdef USE_PAM if (options.use_pam) diff --git a/cipher.c b/cipher.c -index 5e096cebf..9b42ffb9a 100644 +index 8a18da2d..57d55325 100644 --- a/cipher.c +++ b/cipher.c @@ -64,25 +64,6 @@ struct sshcipher_ctx { @@ -929,7 +927,7 @@ index 5e096cebf..9b42ffb9a 100644 static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES -@@ -411,7 +392,7 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, +@@ -420,7 +401,7 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, void cipher_free(struct sshcipher_ctx *cc) { @@ -939,7 +937,7 @@ index 5e096cebf..9b42ffb9a 100644 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_free(cc->cp_ctx); diff --git a/cipher.h b/cipher.h -index 6533ff2bb..2e05a0210 100644 +index 6533ff2b..2e05a021 100644 --- a/cipher.h +++ b/cipher.h @@ -47,7 +47,25 @@ @@ -970,10 +968,10 @@ index 6533ff2bb..2e05a0210 100644 const struct sshcipher *cipher_by_name(const char *); diff --git a/kex.c b/kex.c -index 5f9530908..44f350ce8 100644 +index 8b200ff4..62f607d6 100644 --- a/kex.c +++ b/kex.c -@@ -66,6 +66,7 @@ +@@ -68,6 +68,7 @@ #include "sshbuf.h" #include "digest.h" #include "xmalloc.h" @@ -981,7 +979,7 @@ index 5f9530908..44f350ce8 100644 /* prototype */ static int kex_choose_conf(struct ssh *, uint32_t seq); -@@ -820,12 +821,16 @@ kex_start_rekex(struct ssh *ssh) +@@ -821,12 +822,16 @@ kex_start_rekex(struct ssh *ssh) } static int @@ -1000,7 +998,7 @@ index 5f9530908..44f350ce8 100644 if ((enc->cipher = cipher_by_name(name)) == NULL) { error_f("unsupported cipher %s", name); free(name); -@@ -846,8 +851,12 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) +@@ -847,8 +852,12 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); @@ -1014,7 +1012,7 @@ index 5f9530908..44f350ce8 100644 if (mac_setup(mac, name) < 0) { error_f("unsupported MAC %s", name); free(name); -@@ -860,12 +869,16 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) +@@ -861,12 +870,16 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) } static int @@ -1033,7 +1031,7 @@ index 5f9530908..44f350ce8 100644 #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; -@@ -1029,7 +1042,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -1030,7 +1043,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; @@ -1042,7 +1040,7 @@ index 5f9530908..44f350ce8 100644 sprop[nenc])) != 0) { kex->failed_choice = peer[nenc]; peer[nenc] = NULL; -@@ -1044,7 +1057,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -1045,7 +1058,7 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) peer[nmac] = NULL; goto out; } @@ -1051,7 +1049,7 @@ index 5f9530908..44f350ce8 100644 sprop[ncomp])) != 0) { kex->failed_choice = peer[ncomp]; peer[ncomp] = NULL; -@@ -1067,6 +1080,10 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) +@@ -1068,6 +1081,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); @@ -1062,7 +1060,7 @@ index 5f9530908..44f350ce8 100644 } /* XXX need runden? */ kex->we_need = need; -@@ -1336,6 +1353,36 @@ dump_digest(const char *msg, const u_char *digest, int len) +@@ -1337,6 +1354,36 @@ dump_digest(const char *msg, const u_char *digest, int len) } #endif @@ -1100,10 +1098,10 @@ index 5f9530908..44f350ce8 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 206ce60ed..cb06e85a3 100644 +index 0e080ea3..6a55aadf 100644 --- a/kex.h +++ b/kex.h -@@ -260,6 +260,8 @@ int kexgss_client(struct ssh *); +@@ -255,6 +255,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1113,10 +1111,10 @@ index 206ce60ed..cb06e85a3 100644 int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **); diff --git a/mac.c b/mac.c -index c95f5ea06..354cfb408 100644 +index f3dda669..bf051baa 100644 --- a/mac.c +++ b/mac.c -@@ -230,6 +230,20 @@ mac_clear(struct sshmac *mac) +@@ -239,6 +239,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1138,7 +1136,7 @@ index c95f5ea06..354cfb408 100644 #define MAC_SEP "," int diff --git a/mac.h b/mac.h -index 0b119d7a1..5fb593b9e 100644 +index 0b119d7a..5fb593b9 100644 --- a/mac.h +++ b/mac.h @@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, @@ -1149,10 +1147,10 @@ index 0b119d7a1..5fb593b9e 100644 #endif /* SSHMAC_H */ diff --git a/monitor.c b/monitor.c -index 453469665..b2f501790 100644 +index 43c10a4e..fbc35782 100644 --- a/monitor.c +++ b/monitor.c -@@ -83,6 +83,7 @@ +@@ -93,6 +93,7 @@ #include "compat.h" #include "ssh2.h" #include "authfd.h" @@ -1160,7 +1158,7 @@ index 453469665..b2f501790 100644 #include "match.h" #include "ssherr.h" #include "sk-api.h" -@@ -100,6 +101,8 @@ extern struct sshbuf *loginmsg; +@@ -110,6 +111,8 @@ extern struct sshbuf *loginmsg; extern struct include_list includes; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ @@ -1169,7 +1167,7 @@ index 453469665..b2f501790 100644 /* State exported from the child */ static struct sshbuf *child_state; -@@ -144,6 +147,11 @@ int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); +@@ -154,6 +157,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 *); @@ -1181,7 +1179,7 @@ index 453469665..b2f501790 100644 #endif static Authctxt *authctxt; -@@ -204,6 +212,10 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -214,6 +222,10 @@ struct mon_table mon_dispatch_proto20[] = { #endif #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, @@ -1192,7 +1190,7 @@ index 453469665..b2f501790 100644 #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -239,6 +251,11 @@ struct mon_table mon_dispatch_postauth20[] = { +@@ -249,6 +261,11 @@ struct mon_table mon_dispatch_postauth20[] = { #ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, @@ -1204,7 +1202,7 @@ index 453469665..b2f501790 100644 #endif {0, 0, NULL} }; -@@ -1575,8 +1592,10 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1569,8 +1586,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; @@ -1216,7 +1214,7 @@ index 453469665..b2f501790 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) -@@ -1585,6 +1604,8 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1579,6 +1598,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"); @@ -1225,7 +1223,7 @@ index 453469665..b2f501790 100644 /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1600,14 +1621,19 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1594,14 +1615,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"; @@ -1245,7 +1243,7 @@ index 453469665..b2f501790 100644 break; } if (!valid_data) -@@ -1619,8 +1645,6 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1613,8 +1639,6 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) SSH_FP_DEFAULT)) == NULL) fatal_f("sshkey_fingerprint failed"); @@ -1254,7 +1252,7 @@ index 453469665..b2f501790 100644 debug3_f("%s %s signature using %s %s%s%s", auth_method, sshkey_type(key), sigalg == NULL ? "default" : sigalg, (ret == 0) ? "verified" : "unverified", -@@ -1708,13 +1732,19 @@ mm_record_login(struct ssh *ssh, Session *s, struct passwd *pw) +@@ -1702,13 +1726,19 @@ mm_record_login(struct ssh *ssh, Session *s, struct passwd *pw) } static void @@ -1275,7 +1273,7 @@ index 453469665..b2f501790 100644 session_unused(s->self); } -@@ -1781,7 +1811,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1775,7 +1805,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) error: if (s != NULL) @@ -1284,7 +1282,7 @@ index 453469665..b2f501790 100644 if ((r = sshbuf_put_u32(m, 0)) != 0) fatal_fr(r, "assemble 0"); mm_request_send(sock, MONITOR_ANS_PTY, m); -@@ -1800,7 +1830,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1794,7 +1824,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) @@ -1293,7 +1291,7 @@ index 453469665..b2f501790 100644 sshbuf_reset(m); free(tty); return (0); -@@ -1822,6 +1852,8 @@ mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req) +@@ -1816,6 +1846,8 @@ mm_answer_term(struct ssh *ssh, int sock, struct sshbuf *req) sshpam_cleanup(); #endif @@ -1302,15 +1300,16 @@ index 453469665..b2f501790 100644 while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1868,12 +1900,46 @@ mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) +@@ -1862,12 +1894,47 @@ mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) { char *cmd; int r; + Session *s; - debug3_f("entering"); + debug3("%s entering", __func__); if ((r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) - fatal_fr(r, "buffer error"); + fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ /* sanity check command, if so how? */ - audit_run_command(cmd); + s = session_new(); @@ -1350,7 +1349,7 @@ index 453469665..b2f501790 100644 free(cmd); return (0); } -@@ -1946,6 +2012,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1940,6 +2007,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) void mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { @@ -1358,7 +1357,7 @@ index 453469665..b2f501790 100644 debug3_f("Waiting for new keys"); if ((child_state = sshbuf_new()) == NULL) -@@ -1953,6 +2020,19 @@ mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1947,6 +2015,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"); @@ -1378,7 +1377,7 @@ index 453469665..b2f501790 100644 } -@@ -2240,3 +2320,102 @@ mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { +@@ -2234,3 +2315,102 @@ mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { #endif /* GSSAPI */ @@ -1482,7 +1481,7 @@ index 453469665..b2f501790 100644 +} +#endif /* SSH_AUDIT_EVENTS */ diff --git a/monitor.h b/monitor.h -index d4d631ddc..2c64f07dc 100644 +index d4d631dd..2c64f07d 100644 --- a/monitor.h +++ b/monitor.h @@ -66,7 +66,13 @@ enum monitor_reqtype { @@ -1501,10 +1500,10 @@ index d4d631ddc..2c64f07dc 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 08dc29e12..fb44ae733 100644 +index b6e3b3f3..1a079c15 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -578,7 +578,7 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, +@@ -567,7 +567,7 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, */ int @@ -1513,7 +1512,7 @@ index 08dc29e12..fb44ae733 100644 const u_char *data, size_t datalen, const char *sigalg, u_int compat, struct sshkey_sig_details **sig_detailsp) { -@@ -594,7 +594,8 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, +@@ -583,7 +583,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"); @@ -1523,7 +1522,7 @@ index 08dc29e12..fb44ae733 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) -@@ -627,6 +628,22 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, +@@ -616,6 +617,22 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, return 0; } @@ -1546,7 +1545,7 @@ index 08dc29e12..fb44ae733 100644 void mm_send_keystate(struct ssh *ssh, struct monitor *monitor) { -@@ -1043,11 +1060,12 @@ mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) +@@ -1032,11 +1049,12 @@ mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) sshbuf_free(m); } @@ -1559,10 +1558,10 @@ index 08dc29e12..fb44ae733 100644 int r; + int handle; - debug3_f("entering command %s", command); + debug3("%s entering command %s", __func__, command); -@@ -1057,6 +1075,30 @@ mm_audit_run_command(const char *command) - fatal_fr(r, "buffer error"); +@@ -1046,6 +1064,30 @@ mm_audit_run_command(const char *command) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, m); @@ -1592,7 +1591,7 @@ index 08dc29e12..fb44ae733 100644 sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1305,3 +1347,83 @@ server_get_connection_info(struct ssh *ssh, int populate, int use_dns) +@@ -1294,3 +1336,83 @@ server_get_connection_info(struct ssh *ssh, int populate, int use_dns) return &ci; } @@ -1677,10 +1676,10 @@ index 08dc29e12..fb44ae733 100644 +} +#endif /* SSH_AUDIT_EVENTS */ diff --git a/monitor_wrap.h b/monitor_wrap.h -index 12c489c33..1bcbfd305 100644 +index 672dce52..661ed63b 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -62,7 +62,9 @@ int mm_user_key_allowed(struct ssh *ssh, struct passwd *, struct sshkey *, int, +@@ -58,7 +58,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 *); @@ -1691,7 +1690,7 @@ index 12c489c33..1bcbfd305 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); -@@ -89,7 +91,12 @@ void mm_sshpam_free_ctx(void *); +@@ -85,7 +87,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(struct ssh *, ssh_audit_event_t); @@ -1706,10 +1705,10 @@ index 12c489c33..1bcbfd305 100644 struct Session; diff --git a/packet.c b/packet.c -index 5dd8269c2..bc22b8625 100644 +index 9dea2cfc..344b5f54 100644 --- a/packet.c +++ b/packet.c -@@ -77,6 +77,7 @@ +@@ -81,6 +81,7 @@ #endif #include "xmalloc.h" @@ -1717,7 +1716,7 @@ index 5dd8269c2..bc22b8625 100644 #include "compat.h" #include "ssh2.h" #include "cipher.h" -@@ -513,6 +514,13 @@ ssh_packet_get_connection_out(struct ssh *ssh) +@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh *ssh) return ssh->state->connection_out; } @@ -1731,10 +1730,10 @@ index 5dd8269c2..bc22b8625 100644 /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -683,22 +691,19 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) +@@ -675,22 +683,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) @@ -1756,10 +1755,10 @@ index 5dd8269c2..bc22b8625 100644 + state->outgoing_packet = NULL; sshbuf_free(state->incoming_packet); + state->incoming_packet = NULL; - 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) + 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) #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); @@ -1778,7 +1777,7 @@ index 5dd8269c2..bc22b8625 100644 free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); -@@ -1004,6 +1019,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode) +@@ -984,6 +999,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]); @@ -1786,7 +1785,7 @@ index 5dd8269c2..bc22b8625 100644 state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2345,6 +2361,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2325,6 +2341,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1860,7 +1859,7 @@ index 5dd8269c2..bc22b8625 100644 static int ssh_packet_set_postauth(struct ssh *ssh) diff --git a/packet.h b/packet.h -index 072f27425..e087d4c8a 100644 +index 49bb87f0..44a39a9e 100644 --- a/packet.h +++ b/packet.h @@ -223,4 +223,5 @@ const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); @@ -1870,18 +1869,19 @@ index 072f27425..e087d4c8a 100644 +void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ diff --git a/session.c b/session.c -index d034f5c65..107edcf91 100644 +index 28bbb8a7..83fc9418 100644 --- a/session.c +++ b/session.c -@@ -139,6 +139,7 @@ static int session_pty_req(struct ssh *, Session *); - extern ServerOptions options; - extern char *__progname; +@@ -145,7 +145,7 @@ 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 */ -@@ -617,6 +618,14 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) +@@ -653,6 +653,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 d034f5c65..107edcf91 100644 + /* Enter interactive session. */ s->ptymaster = ptymaster; - session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); -@@ -707,15 +716,19 @@ do_exec(struct ssh *ssh, Session *s, const char *command) + ssh_packet_set_interactive(ssh, 1, +@@ -745,15 +753,19 @@ do_exec(struct ssh *ssh, Session *s, const char *command) s->self); #ifdef SSH_AUDIT_EVENTS @@ -1918,7 +1918,7 @@ index d034f5c65..107edcf91 100644 #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1495,7 +1508,11 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1538,7 +1550,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 d034f5c65..107edcf91 100644 /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1710,6 +1727,9 @@ session_unused(int id) +@@ -1750,6 +1766,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1940,7 +1940,7 @@ index d034f5c65..107edcf91 100644 sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1788,6 +1808,19 @@ session_open(Authctxt *authctxt, int chanid) +@@ -1828,6 +1847,19 @@ session_open(Authctxt *authctxt, int chanid) return 1; } @@ -1960,7 +1960,7 @@ index d034f5c65..107edcf91 100644 Session * session_by_tty(char *tty) { -@@ -2405,6 +2438,32 @@ session_exit_message(struct ssh *ssh, Session *s, int status) +@@ -2445,6 +2477,32 @@ session_exit_message(struct ssh *ssh, Session *s, int status) chan_write_failed(ssh, c); } @@ -1993,7 +1993,7 @@ index d034f5c65..107edcf91 100644 void session_close(struct ssh *ssh, Session *s) { -@@ -2418,6 +2477,10 @@ session_close(struct ssh *ssh, Session *s) +@@ -2458,6 +2516,10 @@ session_close(struct ssh *ssh, Session *s) if (s->ttyfd != -1) session_pty_cleanup(s); @@ -2004,7 +2004,7 @@ index d034f5c65..107edcf91 100644 free(s->term); free(s->display); free(s->x11_chanids); -@@ -2494,14 +2557,14 @@ session_close_by_channel(struct ssh *ssh, int id, int force, void *arg) +@@ -2534,14 +2596,14 @@ session_close_by_channel(struct ssh *ssh, int id, int force, void *arg) } void @@ -2021,7 +2021,7 @@ index d034f5c65..107edcf91 100644 else session_close(ssh, s); } -@@ -2627,6 +2690,15 @@ do_authenticated2(struct ssh *ssh, Authctxt *authctxt) +@@ -2668,6 +2730,15 @@ do_authenticated2(struct ssh *ssh, Authctxt *authctxt) server_loop2(ssh, authctxt); } @@ -2037,7 +2037,7 @@ index d034f5c65..107edcf91 100644 void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2690,7 +2762,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2731,7 +2802,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) * or if running in monitor. */ if (mm_is_monitor()) @@ -2047,7 +2047,7 @@ index d034f5c65..107edcf91 100644 /* Return a name for the remote host that fits inside utmp_size */ diff --git a/session.h b/session.h -index 344a1ddf9..a41c6efcd 100644 +index 344a1ddf..a41c6efc 100644 --- a/session.h +++ b/session.h @@ -61,6 +61,12 @@ struct Session { @@ -2078,10 +2078,10 @@ index 344a1ddf9..a41c6efcd 100644 void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); diff --git a/sshd-session.c b/sshd-session.c -index d6bece941..e49e4fb51 100644 +index 81d30152..a808ac9a 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -188,8 +188,8 @@ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); +@@ -194,8 +194,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 d6bece941..e49e4fb51 100644 /* XXX reduce to stub once postauth split */ int -@@ -202,6 +202,35 @@ mm_is_monitor(void) +@@ -208,6 +208,41 @@ mm_is_monitor(void) return (pmonitor && pmonitor->m_pid > 0); } @@ -2108,6 +2108,12 @@ index d6bece941..e49e4fb51 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: { @@ -2128,7 +2134,7 @@ index d6bece941..e49e4fb51 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 -@@ -230,18 +259,40 @@ grace_alarm_handler(int sig) +@@ -236,18 +271,40 @@ grace_alarm_handler(int sig) _exit(EXIT_LOGIN_GRACE); } @@ -2172,7 +2178,7 @@ index d6bece941..e49e4fb51 100644 sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -250,20 +301,38 @@ destroy_sensitive_data(void) +@@ -256,20 +313,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2212,7 +2218,7 @@ index d6bece941..e49e4fb51 100644 } /* Certs do not need demotion */ } -@@ -441,7 +510,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -463,7 +538,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ @@ -2221,7 +2227,7 @@ index d6bece941..e49e4fb51 100644 reseed_prngs(); -@@ -1365,6 +1434,9 @@ main(int ac, char **av) +@@ -1387,6 +1462,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ @@ -2231,7 +2237,7 @@ index d6bece941..e49e4fb51 100644 ssh_packet_get_bytes(ssh, &ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -1410,6 +1482,14 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, +@@ -1432,6 +1510,14 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, void cleanup_exit(int i) { @@ -2246,7 +2252,7 @@ index d6bece941..e49e4fb51 100644 extern int auth_attempted; /* monitor.c */ if (the_active_state != NULL && the_authctxt != NULL) { -@@ -1426,7 +1506,9 @@ cleanup_exit(int i) +@@ -1448,7 +1534,9 @@ cleanup_exit(int i) } #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ @@ -2258,10 +2264,10 @@ index d6bece941..e49e4fb51 100644 #endif /* Override default fatal exit value when auth was attempted */ diff --git a/sshd.c b/sshd.c -index 3ab81e268..ed7faf96d 100644 +index c9ea8e38..8a99f0b2 100644 --- a/sshd.c +++ b/sshd.c -@@ -213,6 +213,15 @@ close_listen_socks(void) +@@ -217,6 +217,15 @@ close_listen_socks(void) num_listen_socks = 0; } @@ -2277,7 +2283,7 @@ index 3ab81e268..ed7faf96d 100644 /* Allocate and initialise the children array */ static void child_alloc(void) -@@ -958,6 +967,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, +@@ -959,6 +968,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2286,5 +2292,5 @@ index 3ab81e268..ed7faf96d 100644 if (options.pid_file != NULL) unlink(options.pid_file); -- -2.52.0 +2.49.0 diff --git a/0036-openssh-7.1p2-audit-race-condition.patch b/0040-openssh-7.1p2-audit-race-condition.patch similarity index 85% rename from 0036-openssh-7.1p2-audit-race-condition.patch rename to 0040-openssh-7.1p2-audit-race-condition.patch index 863f700..fe732a6 100644 --- a/0036-openssh-7.1p2-audit-race-condition.patch +++ b/0040-openssh-7.1p2-audit-race-condition.patch @@ -1,7 +1,7 @@ -From ffa3fdb2ad2c7afc91993d9301e35d2e9a83ea47 Mon Sep 17 00:00:00 2001 +From c288d4a26ad44dc481c9d18d2920c9d70474833c Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 36/53] openssh-7.1p2-audit-race-condition +Subject: [PATCH 40/50] openssh-7.1p2-audit-race-condition --- monitor_wrap.c | 46 +++++++++++++++++++++++++++++++++++++ @@ -10,10 +10,10 @@ Subject: [PATCH 36/53] openssh-7.1p2-audit-race-condition 3 files changed, 102 insertions(+), 7 deletions(-) diff --git a/monitor_wrap.c b/monitor_wrap.c -index fb44ae733..17a6c9786 100644 +index 1a079c15..768a59f9 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -1426,4 +1426,50 @@ mm_audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_ +@@ -1415,4 +1415,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 fb44ae733..17a6c9786 100644 +} #endif /* SSH_AUDIT_EVENTS */ diff --git a/monitor_wrap.h b/monitor_wrap.h -index 1bcbfd305..2b814dbd1 100644 +index 661ed63b..e957ba6e 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -97,6 +97,8 @@ void mm_audit_unsupported_body(struct ssh *, int); +@@ -93,6 +93,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 1bcbfd305..2b814dbd1 100644 struct Session; diff --git a/session.c b/session.c -index 107edcf91..80282dfd8 100644 +index 83fc9418..b4753d93 100644 --- a/session.c +++ b/session.c -@@ -161,6 +161,10 @@ static Session *sessions = NULL; +@@ -167,6 +167,10 @@ static Session *sessions = NULL; login_cap_t *lc; #endif @@ -92,7 +92,7 @@ index 107edcf91..80282dfd8 100644 static int is_child = 0; static int in_chroot = 0; static int have_dev_log = 1; -@@ -358,6 +362,8 @@ xauth_valid_string(const char *s) +@@ -390,6 +394,8 @@ xauth_valid_string(const char *s) return 1; } @@ -101,7 +101,7 @@ index 107edcf91..80282dfd8 100644 #define USE_PIPES 1 /* * This is called to fork and execute a command when we have no tty. This -@@ -481,6 +487,8 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) +@@ -513,6 +519,8 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) close(err[0]); #endif @@ -110,7 +110,7 @@ index 107edcf91..80282dfd8 100644 /* Do processing for the child (exec command etc). */ do_child(ssh, s, command); /* NOTREACHED */ -@@ -595,6 +603,9 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) +@@ -630,6 +638,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 107edcf91..80282dfd8 100644 /* record login, etc. similar to login(1) */ #ifndef HAVE_OSF_SIA do_login(ssh, s, command); -@@ -729,6 +740,8 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -766,6 +777,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 107edcf91..80282dfd8 100644 #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -744,6 +757,20 @@ do_exec(struct ssh *ssh, Session *s, const char *command) +@@ -781,6 +794,20 @@ do_exec(struct ssh *ssh, Session *s, const char *command) */ sshbuf_reset(loginmsg); @@ -150,7 +150,7 @@ index 107edcf91..80282dfd8 100644 return ret; } -@@ -1490,6 +1517,33 @@ child_close_fds(struct ssh *ssh) +@@ -1532,6 +1559,33 @@ child_close_fds(struct ssh *ssh) log_redirect_stderr_to(NULL); } @@ -184,7 +184,7 @@ index 107edcf91..80282dfd8 100644 /* * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group -@@ -1507,13 +1561,6 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1549,13 +1603,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 107edcf91..80282dfd8 100644 if (s->authctxt->force_pwchange) { do_setusercontext(pw); -- -2.52.0 +2.49.0 diff --git a/0037-openssh-9.0p1-audit-log.patch b/0041-openssh-9.0p1-audit-log.patch similarity index 92% rename from 0037-openssh-9.0p1-audit-log.patch rename to 0041-openssh-9.0p1-audit-log.patch index c58a5fe..e04f31b 100644 --- a/0037-openssh-9.0p1-audit-log.patch +++ b/0041-openssh-9.0p1-audit-log.patch @@ -1,7 +1,7 @@ -From ef05b1fceddc64cfc7eb40daac60a137634d0a9f Mon Sep 17 00:00:00 2001 +From 80d967a18261156573e7385f8e534a89d2767d67 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 37/53] openssh-9.0p1-audit-log +Subject: [PATCH 41/50] openssh-9.0p1-audit-log --- audit-bsm.c | 2 +- @@ -11,7 +11,7 @@ Subject: [PATCH 37/53] openssh-9.0p1-audit-log 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/audit-bsm.c b/audit-bsm.c -index a6292cb8f..0f2ef8235 100644 +index a49abb92..c6f56553 100644 --- a/audit-bsm.c +++ b/audit-bsm.c @@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li) @@ -24,7 +24,7 @@ index a6292cb8f..0f2ef8235 100644 /* not implemented */ } diff --git a/audit-linux.c b/audit-linux.c -index 4d3e9d41e..d2bc0b526 100644 +index d484b82b..dcfde3a9 100644 --- a/audit-linux.c +++ b/audit-linux.c @@ -52,7 +52,7 @@ extern u_int utmp_len; @@ -36,8 +36,8 @@ index 4d3e9d41e..d2bc0b526 100644 const char *ip, const char *ttyn, int success, int event) { int audit_fd, rc, saved_errno; -@@ -68,7 +68,7 @@ linux_audit_user_logxxx(int uid, const char *username, - hostname = NULL; +@@ -66,7 +66,7 @@ linux_audit_user_logxxx(int uid, const char *username, + } 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 4d3e9d41e..d2bc0b526 100644 saved_errno = errno; close(audit_fd); -@@ -139,10 +139,12 @@ fatal_report: +@@ -137,10 +137,12 @@ fatal_report: } int @@ -59,7 +59,7 @@ index 4d3e9d41e..d2bc0b526 100644 audit_fd = audit_open(); if (audit_fd < 0) { -@@ -152,14 +154,44 @@ audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) +@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) else return 0; /* Must prevent login */ } @@ -107,7 +107,7 @@ index 4d3e9d41e..d2bc0b526 100644 out: saved_errno = errno; audit_close(audit_fd); -@@ -181,26 +213,34 @@ audit_connection_from(const char *host, int port) +@@ -179,26 +211,34 @@ audit_connection_from(const char *host, int port) int audit_run_command(struct ssh *ssh, const char *command) { @@ -142,7 +142,7 @@ index 4d3e9d41e..d2bc0b526 100644 } void -@@ -213,31 +253,41 @@ void +@@ -211,31 +251,41 @@ void audit_session_open(struct logininfo *li) { if (!user_login_count++) @@ -189,7 +189,7 @@ index 4d3e9d41e..d2bc0b526 100644 ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; case SSH_AUTH_FAIL_PASSWD: -@@ -257,9 +307,11 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) +@@ -255,9 +305,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 4d3e9d41e..d2bc0b526 100644 ssh_remote_ipaddr(ssh), "ssh", 1, AUDIT_USER_LOGOUT); } -@@ -268,12 +320,14 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) +@@ -266,12 +318,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 4d3e9d41e..d2bc0b526 100644 ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); break; default: - debug_f("unhandled event %d", event); + debug("%s: unhandled event %d", __func__, event); break; } + free(audit_hostname); @@ -217,7 +217,7 @@ index 4d3e9d41e..d2bc0b526 100644 void diff --git a/audit.c b/audit.c -index d0433c3a0..28d51a146 100644 +index d0433c3a..28d51a14 100644 --- a/audit.c +++ b/audit.c @@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev) @@ -248,7 +248,7 @@ index d0433c3a0..28d51a146 100644 void diff --git a/audit.h b/audit.h -index 45d66ccff..05ac132cf 100644 +index 45d66ccf..05ac132c 100644 --- a/audit.h +++ b/audit.h @@ -64,7 +64,7 @@ void audit_session_close(struct logininfo *); @@ -261,5 +261,5 @@ index 45d66ccff..05ac132cf 100644 void audit_unsupported(struct ssh *, int); void audit_kex(struct ssh *, int, char *, char *, char *, char *); -- -2.52.0 +2.49.0 diff --git a/0038-openssh-7.7p1-fips.patch b/0042-openssh-7.7p1-fips.patch similarity index 77% rename from 0038-openssh-7.7p1-fips.patch rename to 0042-openssh-7.7p1-fips.patch index 18ebed3..f4729d7 100644 --- a/0038-openssh-7.7p1-fips.patch +++ b/0042-openssh-7.7p1-fips.patch @@ -1,7 +1,7 @@ -From d7dd45f9e19a71269828bc5f8567613a02f6feef Mon Sep 17 00:00:00 2001 +From 6e0e7462959e8bc6a99f50dbf9a5b42ae74c2c87 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy -Date: Thu, 28 Aug 2025 14:01:38 +0200 -Subject: [PATCH 38/53] openssh-7.7p1-fips +Date: Thu, 15 May 2025 13:43:29 +0200 +Subject: [PATCH 42/50] openssh-7.7p1-fips --- dh.c | 41 ++++++++++++++++++++++ @@ -13,19 +13,19 @@ Subject: [PATCH 38/53] openssh-7.7p1-fips myproposal.h | 33 ++++++++++++++++++ readconf.c | 16 ++++++--- sandbox-seccomp-filter.c | 3 ++ - servconf.c | 18 +++++++--- + servconf.c | 16 ++++++--- ssh-ed25519.c | 9 +++++ - ssh-gss.h | 5 +++ - ssh-keygen.c | 20 +++++++++-- + ssh-keygen.c | 22 ++++++++++-- ssh-rsa.c | 3 ++ ssh.c | 5 +++ - sshconnect2.c | 9 ++++- + sshconnect2.c | 61 ++++++++++++++++++--------------- + sshd-auth.c | 13 ++++--- sshd.c | 13 +++++++ sshkey.c | 37 ++++++++++++++++++++ - 18 files changed, 271 insertions(+), 30 deletions(-) + 18 files changed, 301 insertions(+), 60 deletions(-) diff --git a/dh.c b/dh.c -index 168dea1dd..8c9a29fa7 100644 +index 168dea1d..8c9a29fa 100644 --- a/dh.c +++ b/dh.c @@ -36,6 +36,7 @@ @@ -89,7 +89,7 @@ index 168dea1dd..8c9a29fa7 100644 + #endif /* WITH_OPENSSL */ diff --git a/dh.h b/dh.h -index c6326a39d..e51e292b8 100644 +index c6326a39..e51e292b 100644 --- a/dh.h +++ b/dh.h @@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); @@ -101,7 +101,7 @@ index c6326a39d..e51e292b8 100644 u_int dh_estimate(int); void dh_set_moduli_file(const char *); diff --git a/kex-names.c b/kex-names.c -index 31e395aa2..1360a4095 100644 +index 6c0b7c2b..cd3902ad 100644 --- a/kex-names.c +++ b/kex-names.c @@ -33,6 +33,7 @@ @@ -112,7 +112,7 @@ index 31e395aa2..1360a4095 100644 #include #endif -@@ -208,7 +209,10 @@ kex_names_valid(const char *names) +@@ -206,7 +207,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 31e395aa2..1360a4095 100644 return 0; } diff --git a/kex.c b/kex.c -index 44f350ce8..da2a537ce 100644 +index 62f607d6..71fbe5cb 100644 --- a/kex.c +++ b/kex.c -@@ -38,6 +38,7 @@ +@@ -40,6 +40,7 @@ #ifdef WITH_OPENSSL #include #include @@ -136,7 +136,7 @@ index 44f350ce8..da2a537ce 100644 # ifdef HAVE_EVP_KDF_CTX_NEW # include # include -@@ -107,7 +108,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], +@@ -109,7 +110,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 44f350ce8..da2a537ce 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 58edc79ad..9a970adf1 100644 +index 15df591c..eecdceba 100644 --- a/kexgen.c +++ b/kexgen.c @@ -31,6 +31,7 @@ @@ -159,7 +159,7 @@ index 58edc79ad..9a970adf1 100644 #include "kex.h" @@ -115,13 +116,28 @@ kex_gen_client(struct ssh *ssh) break; - #endif /* WITH_OPENSSL */ + #endif case KEX_C25519_SHA256: - r = kex_c25519_keypair(kex); + if (FIPS_mode()) { @@ -191,7 +191,7 @@ index 58edc79ad..9a970adf1 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 /* WITH_OPENSSL */ + #endif case KEX_C25519_SHA256: - r = kex_c25519_dec(kex, server_blob, &shared_secret); + if (FIPS_mode()) { @@ -227,7 +227,7 @@ index 58edc79ad..9a970adf1 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 /* WITH_OPENSSL */ + #endif case KEX_C25519_SHA256: - r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, - &shared_secret); @@ -264,7 +264,7 @@ index 58edc79ad..9a970adf1 100644 default: r = SSH_ERR_INVALID_ARGUMENT; diff --git a/kexgexc.c b/kexgexc.c -index 097d83f30..ccbb9b580 100644 +index e99e0cf2..4c3feae0 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -28,6 +28,7 @@ @@ -274,7 +274,7 @@ index 097d83f30..ccbb9b580 100644 +#include #include - #include "openbsd-compat/openssl-compat.h" + #include @@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh) r = SSH_ERR_ALLOC_FAIL; goto out; @@ -287,7 +287,7 @@ index 097d83f30..ccbb9b580 100644 /* generate and send 'e', client DH public key */ diff --git a/myproposal.h b/myproposal.h -index 8fe9276c2..3e0ec6826 100644 +index 8fe9276c..3e0ec682 100644 --- a/myproposal.h +++ b/myproposal.h @@ -58,6 +58,18 @@ @@ -338,10 +338,10 @@ index 8fe9276c2..3e0ec6826 100644 #define SSH_ALLOWED_CA_SIGALGS \ "ssh-ed25519," \ diff --git a/readconf.c b/readconf.c -index 3f67f4de4..b6ad47b49 100644 +index f340bf50..ea9d293c 100644 --- a/readconf.c +++ b/readconf.c -@@ -39,6 +39,7 @@ +@@ -43,6 +43,7 @@ #include #include #include @@ -349,7 +349,7 @@ index 3f67f4de4..b6ad47b49 100644 #ifdef USE_SYSTEM_GLOB # include #else -@@ -3078,11 +3079,16 @@ fill_default_options(Options * options) +@@ -3043,11 +3044,16 @@ fill_default_options(Options * options) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); /* remove unsupported algos from default lists */ @@ -372,10 +372,10 @@ index 3f67f4de4..b6ad47b49 100644 do { \ if ((r = kex_assemble_names(&options->what, \ diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index e0f2d4289..c52f64897 100644 +index 1fabf99d..ccb61586 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c -@@ -258,6 +258,9 @@ static const struct sock_filter preauth_insns[] = { +@@ -230,6 +230,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_open SC_DENY(__NR_open, EACCES), #endif @@ -386,21 +386,18 @@ index e0f2d4289..c52f64897 100644 SC_DENY(__NR_openat, EACCES), #endif diff --git a/servconf.c b/servconf.c -index ac84b74d9..f78615c28 100644 +index 84891544..8b708cbf 100644 --- a/servconf.c +++ b/servconf.c -@@ -37,7 +37,10 @@ +@@ -37,6 +37,7 @@ #include #include #include +#include -+#ifdef HAVE_UTIL_H + #ifdef HAVE_UTIL_H #include -+#endif - #ifdef USE_SYSTEM_GLOB - # include - #else -@@ -244,11 +247,16 @@ assemble_algorithms(ServerOptions *o) + #endif +@@ -247,11 +248,16 @@ assemble_algorithms(ServerOptions *o) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); /* remove unsupported algos from default lists */ @@ -423,7 +420,7 @@ index ac84b74d9..f78615c28 100644 do { \ if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ diff --git a/ssh-ed25519.c b/ssh-ed25519.c -index c8caa2221..4bcd9ef81 100644 +index 22d8db02..41942f4e 100644 --- a/ssh-ed25519.c +++ b/ssh-ed25519.c @@ -24,6 +24,7 @@ @@ -434,7 +431,7 @@ index c8caa2221..4bcd9ef81 100644 #include "log.h" #include "sshbuf.h" -@@ -163,6 +164,10 @@ ssh_ed25519_sign(struct sshkey *key, +@@ -164,6 +165,10 @@ ssh_ed25519_sign(struct sshkey *key, key->ed25519_sk == NULL || datalen >= INT_MAX - crypto_sign_ed25519_BYTES) return SSH_ERR_INVALID_ARGUMENT; @@ -445,7 +442,7 @@ index c8caa2221..4bcd9ef81 100644 smlen = slen = datalen + crypto_sign_ed25519_BYTES; if ((sig = malloc(slen)) == NULL) return SSH_ERR_ALLOC_FAIL; -@@ -244,6 +249,10 @@ ssh_ed25519_verify(const struct sshkey *key, +@@ -221,6 +226,10 @@ ssh_ed25519_verify(const struct sshkey *key, dlen >= INT_MAX - crypto_sign_ed25519_BYTES || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; @@ -456,54 +453,40 @@ index c8caa2221..4bcd9ef81 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 3c582a83a..afa279097 100644 +index 16cff947..792aafde 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c -@@ -22,6 +22,7 @@ - #include "openbsd-compat/openssl-compat.h" - #include +@@ -20,6 +20,7 @@ + + #ifdef WITH_OPENSSL #include +#include #include + #include "openbsd-compat/openssl-compat.h" #endif - @@ -68,6 +69,7 @@ - #endif + #include "cipher.h" #define DEFAULT_KEY_TYPE_NAME "ed25519" +#define FIPS_DEFAULT_KEY_TYPE_NAME "rsa" /* - * 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) + * Default number of bits in the RSA, DSA and ECDSA keys. These value can be +@@ -202,6 +204,12 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) #endif } #ifdef WITH_OPENSSL + if (FIPS_mode()) { ++ if (type == KEY_DSA) ++ fatal("DSA keys are not allowed in FIPS mode"); + if (type == KEY_ED25519 || type == KEY_ED25519_SK) + fatal("ED25519 keys are not allowed in FIPS mode"); + } switch (type) { - case KEY_RSA: - if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE) -@@ -248,7 +254,7 @@ ask_filename(struct passwd *pw, const char *prompt) + case KEY_DSA: + if (*bitsp != 1024) +@@ -259,7 +267,7 @@ ask_filename(struct passwd *pw, const char *prompt) char *name = NULL; if (key_type_name == NULL) @@ -511,15 +494,15 @@ index 3c582a83a..afa279097 100644 + name = FIPS_mode() ? _PATH_SSH_CLIENT_ID_RSA : _PATH_SSH_CLIENT_ID_ED25519; else { switch (sshkey_type_from_shortname(key_type_name)) { - #ifdef OPENSSL_HAS_ECC -@@ -1057,9 +1063,17 @@ do_gen_all_hostkeys(struct passwd *pw) + #ifdef WITH_DSA +@@ -1144,9 +1152,17 @@ do_gen_all_hostkeys(struct passwd *pw) first = 1; printf("%s: generating new host keys: ", __progname); } + type = sshkey_type_from_shortname(key_types[i].key_type); + + /* Skip the keys that are not supported in FIPS mode */ -+ if (FIPS_mode() && type == KEY_ED25519) { ++ if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) { + logit("Skipping %s key in FIPS mode", + key_types[i].key_type_display); + goto next; @@ -531,7 +514,7 @@ index 3c582a83a..afa279097 100644 if ((fd = mkstemp(prv_tmp)) == -1) { error("Could not save your private key in %s: %s", prv_tmp, strerror(errno)); -@@ -3757,7 +3771,7 @@ main(int argc, char **argv) +@@ -3849,7 +3865,7 @@ main(int argc, char **argv) } if (key_type_name == NULL) @@ -541,11 +524,11 @@ index 3c582a83a..afa279097 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 fe1518984..9428df8d1 100644 +index 3ad1fddc..6c2f771a 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c -@@ -25,6 +25,7 @@ - #include +@@ -23,6 +23,7 @@ + #include #include +#include @@ -562,10 +545,10 @@ index fe1518984..9428df8d1 100644 goto out; } diff --git a/ssh.c b/ssh.c -index 8d27f6379..7d6ba516e 100644 +index 98b103c9..abc8b843 100644 --- a/ssh.c +++ b/ssh.c -@@ -74,6 +74,7 @@ +@@ -78,6 +78,7 @@ #include #include #endif @@ -573,7 +556,7 @@ index 8d27f6379..7d6ba516e 100644 #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -1664,6 +1665,10 @@ main(int ac, char **av) +@@ -1642,6 +1643,10 @@ main(int ac, char **av) exit(0); } @@ -585,7 +568,7 @@ index 8d27f6379..7d6ba516e 100644 if (options.sk_provider != NULL && *options.sk_provider == '$' && strlen(options.sk_provider) > 1) { diff --git a/sshconnect2.c b/sshconnect2.c -index b253f991b..fffa66c8d 100644 +index 0af15bcc..14f7671a 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -45,6 +45,8 @@ @@ -597,40 +580,119 @@ index b253f991b..fffa66c8d 100644 #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -262,6 +264,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +@@ -262,36 +264,41 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { -+ char * gss_kex_filtered = FIPS_mode() ? -+ match_filter_allowlist(options.gss_kex_algorithms, GSS_KEX_DEFAULT_KEX_FIPS) : xstrdup(options.gss_kex_algorithms); +- /* Add the GSSAPI mechanisms currently supported on this +- * client to the key exchange algorithm proposal */ +- orig = myproposal[PROPOSAL_KEX_ALGS]; +- +- 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]; + - /* 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, - } ++ 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, +- 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], +- "%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 (gss) { - debug("Offering GSSAPI proposal: %s", gss); - xasprintf(&myproposal[PROPOSAL_KEX_ALGS], ++ /* If we've got GSSAPI algorithms, then we also support the ++ * 'null' hostkey, as a last resort */ ++ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; ++ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], ++ "%s,null", orig); ++ } + } + } + #endif +diff --git a/sshd-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); diff --git a/sshd.c b/sshd.c -index ed7faf96d..de2baa5e4 100644 +index 8a99f0b2..5ff0b5ff 100644 --- a/sshd.c +++ b/sshd.c -@@ -44,6 +44,7 @@ - #include +@@ -52,6 +52,7 @@ + #endif #include #include +#include #include #include #include -@@ -55,6 +56,7 @@ +@@ -63,6 +64,7 @@ #ifdef WITH_OPENSSL #include #include @@ -638,7 +700,7 @@ index ed7faf96d..de2baa5e4 100644 #include "openbsd-compat/openssl-compat.h" #endif -@@ -1613,6 +1615,13 @@ main(int ac, char **av) +@@ -1611,6 +1613,13 @@ main(int ac, char **av) &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) do_log2_r(r, ll, "Unable to load host key \"%s\"", options.host_key_files[i]); @@ -652,7 +714,7 @@ index ed7faf96d..de2baa5e4 100644 if (sshkey_is_sk(key) && key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { debug("host key %s requires user presence, ignoring", -@@ -1836,6 +1845,10 @@ main(int ac, char **av) +@@ -1830,6 +1839,10 @@ main(int ac, char **av) /* Reinitialize the log (because of the fork above). */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -664,10 +726,10 @@ index ed7faf96d..de2baa5e4 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 148fee2b7..394d9b105 100644 +index 4e41a78c..ca1cdb64 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -36,6 +36,7 @@ +@@ -35,6 +35,7 @@ #include #include #include @@ -675,15 +737,15 @@ index 148fee2b7..394d9b105 100644 #endif #include "crypto_api.h" -@@ -58,6 +59,7 @@ +@@ -59,6 +60,7 @@ #define SSHKEY_INTERNAL #include "sshkey.h" #include "match.h" +#include "log.h" #include "ssh-sk.h" - #include "ssh-pkcs11.h" -@@ -386,6 +388,18 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) + #ifdef WITH_XMSS +@@ -408,6 +410,18 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) impl = keyimpls[i]; if (impl->name == NULL || impl->type == KEY_NULL) continue; @@ -702,7 +764,7 @@ index 148fee2b7..394d9b105 100644 if (!include_sigonly && impl->sigonly) continue; if ((certs_only && !impl->cert) || (plain_only && impl->cert)) -@@ -1418,6 +1432,20 @@ sshkey_read(struct sshkey *ret, char **cpp) +@@ -1441,6 +1455,20 @@ sshkey_read(struct sshkey *ret, char **cpp) return SSH_ERR_EC_CURVE_MISMATCH; } @@ -723,7 +785,7 @@ index 148fee2b7..394d9b105 100644 /* Fill in ret from parsed key */ sshkey_free_contents(ret); *ret = *k; -@@ -2251,6 +2279,11 @@ sshkey_sign(struct sshkey *key, +@@ -2275,6 +2303,11 @@ sshkey_sign(struct sshkey *key, *lenp = 0; if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; @@ -735,7 +797,7 @@ index 148fee2b7..394d9b105 100644 if ((impl = sshkey_impl_from_key(key)) == NULL) return SSH_ERR_KEY_TYPE_UNKNOWN; if ((r = sshkey_unshield_private(key)) != 0) -@@ -2290,6 +2323,10 @@ sshkey_verify(const struct sshkey *key, +@@ -2311,6 +2344,10 @@ sshkey_verify(const struct sshkey *key, *detailsp = NULL; if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; @@ -747,5 +809,5 @@ index 148fee2b7..394d9b105 100644 return SSH_ERR_KEY_TYPE_UNKNOWN; return impl->funcs->verify(key, sig, siglen, data, dlen, -- -2.52.0 +2.49.0 diff --git a/0039-openssh-8.7p1-ssh-manpage.patch b/0043-openssh-8.7p1-ssh-manpage.patch similarity index 87% rename from 0039-openssh-8.7p1-ssh-manpage.patch rename to 0043-openssh-8.7p1-ssh-manpage.patch index d0e984d..89c6ea1 100644 --- a/0039-openssh-8.7p1-ssh-manpage.patch +++ b/0043-openssh-8.7p1-ssh-manpage.patch @@ -1,14 +1,14 @@ -From 7167a191776dacf7e31cf8a8a2ed89887e49f4ee Mon Sep 17 00:00:00 2001 +From 299a602802d7c7d121306eb2aeae1502871a35cb Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 39/53] openssh-8.7p1-ssh-manpage +Subject: [PATCH 43/50] openssh-8.7p1-ssh-manpage --- ssh.1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ssh.1 b/ssh.1 -index 6a9fbdc5b..755cdef2b 100644 +index 6a9fbdc5..755cdef2 100644 --- a/ssh.1 +++ b/ssh.1 @@ -510,12 +510,12 @@ For full details of the options listed below, and their possible values, see @@ -43,5 +43,5 @@ index 6a9fbdc5b..755cdef2b 100644 .It RevokedHostKeys .It SecurityKeyProvider -- -2.52.0 +2.49.0 diff --git a/0040-openssh-8.7p1-negotiate-supported-algs.patch b/0044-openssh-8.7p1-negotiate-supported-algs.patch similarity index 95% rename from 0040-openssh-8.7p1-negotiate-supported-algs.patch rename to 0044-openssh-8.7p1-negotiate-supported-algs.patch index 29f8213..f4c3b8a 100644 --- a/0040-openssh-8.7p1-negotiate-supported-algs.patch +++ b/0044-openssh-8.7p1-negotiate-supported-algs.patch @@ -1,7 +1,7 @@ -From 53e44bd1f669ecd6a7429e94b55beec8e3c0c529 Mon Sep 17 00:00:00 2001 +From 5c92430c08ac392b5b2ace899cc043247c923734 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 40/53] openssh-8.7p1-negotiate-supported-algs +Subject: [PATCH 44/50] openssh-8.7p1-negotiate-supported-algs --- regress/hostkey-agent.sh | 32 +++++++++++++++++++++++++------- @@ -9,7 +9,7 @@ Subject: [PATCH 40/53] 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 28dcfe170..b9e716dcd 100644 +index 28dcfe17..b9e716dc 100644 --- a/regress/hostkey-agent.sh +++ b/regress/hostkey-agent.sh @@ -17,8 +17,21 @@ trace "make CA key" @@ -84,7 +84,7 @@ index 28dcfe170..b9e716dcd 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 fffa66c8d..f43c81ad9 100644 +index 14f7671a..ad3f560f 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, @@ -129,5 +129,5 @@ index fffa66c8d..f43c81ad9 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) -- -2.52.0 +2.49.0 diff --git a/0041-openssh-9.0p1-evp-fips-kex.patch b/0045-openssh-9.0p1-evp-fips-kex.patch similarity index 95% rename from 0041-openssh-9.0p1-evp-fips-kex.patch rename to 0045-openssh-9.0p1-evp-fips-kex.patch index 24ef8e8..610cea0 100644 --- a/0041-openssh-9.0p1-evp-fips-kex.patch +++ b/0045-openssh-9.0p1-evp-fips-kex.patch @@ -1,7 +1,7 @@ -From 1c0d3b6e9868ef31b97be1679389e3db2616eccd Mon Sep 17 00:00:00 2001 +From be23afbab800c9b5ffea56b3f410a04156c08df2 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 41/53] openssh-9.0p1-evp-fips-kex +Subject: [PATCH 45/50] openssh-9.0p1-evp-fips-kex --- dh.c | 98 +++++++++++++++++++++++++++++++++----- @@ -12,7 +12,7 @@ Subject: [PATCH 41/53] openssh-9.0p1-evp-fips-kex 5 files changed, 382 insertions(+), 42 deletions(-) diff --git a/dh.c b/dh.c -index 8c9a29fa7..ea0a0b093 100644 +index 8c9a29fa..ea0a0b09 100644 --- a/dh.c +++ b/dh.c @@ -37,6 +37,9 @@ @@ -140,10 +140,10 @@ index 8c9a29fa7..ea0a0b093 100644 DH * diff --git a/kex.c b/kex.c -index da2a537ce..56c80395c 100644 +index 71fbe5cb..ce6a7b81 100644 --- a/kex.c +++ b/kex.c -@@ -1613,3 +1613,142 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, +@@ -1614,3 +1614,142 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, return r; } @@ -287,7 +287,7 @@ index da2a537ce..56c80395c 100644 +} +#endif /* WITH_OPENSSL */ diff --git a/kex.h b/kex.h -index cb06e85a3..6daafb159 100644 +index 6a55aadf..48f3bb87 100644 --- a/kex.h +++ b/kex.h @@ -37,6 +37,9 @@ @@ -300,7 +300,7 @@ index cb06e85a3..6daafb159 100644 # ifdef OPENSSL_HAS_ECC # include # else /* OPENSSL_HAS_ECC */ -@@ -316,6 +319,9 @@ int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], +@@ -311,6 +314,9 @@ int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); @@ -311,12 +311,12 @@ index cb06e85a3..6daafb159 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 6d5a7813d..b05277aa1 100644 +index 0faab21b..32e1de51 100644 --- a/kexdh.c +++ b/kexdh.c -@@ -36,6 +36,10 @@ +@@ -35,6 +35,10 @@ + #include "openbsd-compat/openssl-compat.h" - #include #include +#include +#include @@ -325,7 +325,7 @@ index 6d5a7813d..b05277aa1 100644 #include "sshkey.h" #include "kex.h" -@@ -84,9 +88,12 @@ int +@@ -83,9 +87,12 @@ int kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) { BIGNUM *shared_secret = NULL; @@ -339,7 +339,7 @@ index 6d5a7813d..b05277aa1 100644 #ifdef DEBUG_KEXDH fprintf(stderr, "dh_pub= "); -@@ -101,24 +108,59 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) +@@ -100,24 +107,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 6d5a7813d..b05277aa1 100644 } diff --git a/kexecdh.c b/kexecdh.c -index 500ec5725..1a1bae35e 100644 +index efb2e55a..d92ba54f 100644 --- a/kexecdh.c +++ b/kexecdh.c -@@ -36,17 +36,57 @@ +@@ -35,17 +35,57 @@ + #include - #include #include +#include +#include @@ -465,7 +465,7 @@ index 500ec5725..1a1bae35e 100644 int kex_ecdh_keypair(struct kex *kex) { -@@ -56,11 +96,7 @@ kex_ecdh_keypair(struct kex *kex) +@@ -55,11 +95,7 @@ kex_ecdh_keypair(struct kex *kex) struct sshbuf *buf = NULL; int r; @@ -478,7 +478,7 @@ index 500ec5725..1a1bae35e 100644 r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -@@ -102,11 +138,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, +@@ -101,11 +137,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, *server_blobp = NULL; *shared_secretp = NULL; @@ -491,7 +491,7 @@ index 500ec5725..1a1bae35e 100644 r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -@@ -141,11 +173,21 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, +@@ -140,11 +172,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 500ec5725..1a1bae35e 100644 *shared_secretp = NULL; if ((buf = sshbuf_new()) == NULL) { -@@ -154,45 +196,82 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, +@@ -153,45 +195,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 500ec5725..1a1bae35e 100644 return r; } -- -2.52.0 +2.49.0 diff --git a/0042-openssh-8.7p1-nohostsha1proof.patch b/0046-openssh-8.7p1-nohostsha1proof.patch similarity index 83% rename from 0042-openssh-8.7p1-nohostsha1proof.patch rename to 0046-openssh-8.7p1-nohostsha1proof.patch index 681d051..9e75c8a 100644 --- a/0042-openssh-8.7p1-nohostsha1proof.patch +++ b/0046-openssh-8.7p1-nohostsha1proof.patch @@ -1,24 +1,24 @@ -From 1cd47036353899fe066f5241d3d70778f103c0e0 Mon Sep 17 00:00:00 2001 +From e4ca3b9dba1cc832a9974493c91207d42e218a68 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 42/53] openssh-8.7p1-nohostsha1proof +Subject: [PATCH 46/50] 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 | 30 ++++++++++++++++---------- - serverloop.c | 6 +++++- + regress/unittests/sshkey/test_sshkey.c | 32 +++++++++++++++++--------- + serverloop.c | 6 ++++- ssh-rsa.c | 3 ++- sshconnect2.c | 8 +++++++ - sshd-session.c | 21 ++++++++++++++++++ - 11 files changed, 88 insertions(+), 24 deletions(-) + sshd-session.c | 21 +++++++++++++++++ + 11 files changed, 90 insertions(+), 24 deletions(-) diff --git a/compat.c b/compat.c -index b59f0bfc0..4e611dc39 100644 +index b59f0bfc..4e611dc3 100644 --- a/compat.c +++ b/compat.c @@ -42,6 +42,7 @@ void @@ -52,7 +52,7 @@ index b59f0bfc0..4e611dc39 100644 /* Always returns pointer to allocated memory, caller must free. */ diff --git a/compat.h b/compat.h -index 1a19060fc..2e6db5bf9 100644 +index 1a19060f..2e6db5bf 100644 --- a/compat.h +++ b/compat.h @@ -30,7 +30,7 @@ @@ -65,10 +65,10 @@ index 1a19060fc..2e6db5bf9 100644 /* #define unused 0x00000020 */ #define SSH_BUG_DEBUG 0x00000040 diff --git a/monitor.c b/monitor.c -index b2f501790..6c83739ee 100644 +index fbc35782..19cb058e 100644 --- a/monitor.c +++ b/monitor.c -@@ -754,11 +754,12 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -747,11 +747,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 b2f501790..6c83739ee 100644 debug3_f("entering"); -@@ -816,18 +817,30 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -809,18 +810,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 b2f501790..6c83739ee 100644 sshbuf_reset(m); diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c -index 16c2f2dff..f4700deeb 100644 +index caf8f57f..09016aea 100644 --- a/regress/unittests/kex/test_kex.c +++ b/regress/unittests/kex/test_kex.c -@@ -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; - } +@@ -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; - 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 16c2f2dff..f4700deeb 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 e412b75d8..5b06bc905 100644 +index 3babe604..cc80fe97 100644 --- a/regress/unittests/sshkey/test_file.c +++ b/regress/unittests/sshkey/test_file.c -@@ -106,6 +106,7 @@ sshkey_file_tests(void) +@@ -109,6 +109,7 @@ sshkey_file_tests(void) sshkey_free(k2); TEST_DONE(); @@ -145,7 +145,7 @@ index e412b75d8..5b06bc905 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); -@@ -113,7 +114,7 @@ sshkey_file_tests(void) +@@ -116,7 +117,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 e412b75d8..5b06bc905 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 d0f47d7cf..ba4d506d5 100644 +index 0aff7c9b..951122e1 100644 --- a/regress/unittests/sshkey/test_fuzz.c +++ b/regress/unittests/sshkey/test_fuzz.c -@@ -273,13 +273,14 @@ sshkey_fuzz_tests(void) +@@ -338,13 +338,14 @@ sshkey_fuzz_tests(void) TEST_DONE(); #ifdef WITH_OPENSSL @@ -175,10 +175,10 @@ index d0f47d7cf..ba4d506d5 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 d0c46a90b..7b5e51b83 100644 +index 5bf4b65c..6d0a35bb 100644 --- a/regress/unittests/sshkey/test_sshkey.c +++ b/regress/unittests/sshkey/test_sshkey.c -@@ -59,6 +59,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type, +@@ -61,6 +61,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type, u_char *sigblob; size_t siglen; @@ -188,7 +188,7 @@ index d0c46a90b..7b5e51b83 100644 ca_buf = sshbuf_new(); ASSERT_PTR_NE(ca_buf, NULL); ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); -@@ -100,8 +103,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type, +@@ -102,8 +105,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,12 +200,14 @@ index d0c46a90b..7b5e51b83 100644 free(sigblob); sshbuf_free(ca_buf); -@@ -118,16 +122,20 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, +@@ -120,16 +124,22 @@ 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 crypto policies */ ++ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp in RHEL, permitted in Fedora */ + 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); @@ -229,7 +231,7 @@ index d0c46a90b..7b5e51b83 100644 free(sig); } -@@ -552,7 +560,7 @@ sshkey_tests(void) +@@ -526,7 +536,7 @@ sshkey_tests(void) ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); k3 = get_private("rsa_1"); @@ -239,10 +241,10 @@ index d0c46a90b..7b5e51b83 100644 SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); ASSERT_PTR_EQ(k4, NULL); diff --git a/serverloop.c b/serverloop.c -index 5d3b194d1..55411a6b4 100644 +index 40ddfb04..9c5b1567 100644 --- a/serverloop.c +++ b/serverloop.c -@@ -76,6 +76,7 @@ +@@ -80,6 +80,7 @@ #include "auth-options.h" #include "serverloop.h" #include "ssherr.h" @@ -250,7 +252,7 @@ index 5d3b194d1..55411a6b4 100644 extern ServerOptions options; -@@ -721,7 +722,10 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) +@@ -699,7 +700,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"; } @@ -263,10 +265,10 @@ index 5d3b194d1..55411a6b4 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 9428df8d1..7843f3e26 100644 +index 6c2f771a..8dd4ab01 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c -@@ -533,7 +533,8 @@ ssh_rsa_verify(const struct sshkey *key, +@@ -509,7 +509,8 @@ ssh_rsa_verify(const struct sshkey *key, ret = SSH_ERR_INVALID_ARGUMENT; goto out; } @@ -277,7 +279,7 @@ index 9428df8d1..7843f3e26 100644 goto out; } diff --git a/sshconnect2.c b/sshconnect2.c -index f43c81ad9..2d98fc3da 100644 +index ad3f560f..3941e089 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1434,6 +1434,14 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp, @@ -296,10 +298,10 @@ index f43c81ad9..2d98fc3da 100644 } diff --git a/sshd-session.c b/sshd-session.c -index e49e4fb51..a558bbc33 100644 +index a808ac9a..c3349a8a 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1288,6 +1288,27 @@ main(int ac, char **av) +@@ -1316,6 +1316,27 @@ main(int ac, char **av) check_ip_options(ssh); @@ -328,5 +330,5 @@ index e49e4fb51..a558bbc33 100644 channel_init_channels(ssh); channel_set_af(ssh, options.address_family); -- -2.52.0 +2.49.0 diff --git a/0047-openssh-9.6p1-pam-rhost.patch b/0047-openssh-9.6p1-pam-rhost.patch new file mode 100644 index 0000000..968e60a --- /dev/null +++ b/0047-openssh-9.6p1-pam-rhost.patch @@ -0,0 +1,25 @@ +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/0043-openssh-9.9p1-separate-keysign.patch b/0048-openssh-9.9p1-separate-keysign.patch similarity index 76% rename from 0043-openssh-9.9p1-separate-keysign.patch rename to 0048-openssh-9.9p1-separate-keysign.patch index 60a6d4f..8d0f691 100644 --- a/0043-openssh-9.9p1-separate-keysign.patch +++ b/0048-openssh-9.9p1-separate-keysign.patch @@ -1,14 +1,14 @@ -From 1799ea7ad21a579b864a536709d732f4a8e533dc Mon Sep 17 00:00:00 2001 +From b97b1040bc0918fe9be89cdb482d046270e92d9c Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 43/53] openssh-9.9p1-separate-keysign +Subject: [PATCH 48/50] openssh-9.9p1-separate-keysign --- ssh_config.5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssh_config.5 b/ssh_config.5 -index 8ac5e1633..a06fbfa11 100644 +index a43b2a27..9d5da2a6 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -797,7 +797,7 @@ or @@ -21,5 +21,5 @@ index 8ac5e1633..a06fbfa11 100644 Sets the escape character (default: .Ql ~ ) . -- -2.52.0 +2.49.0 diff --git a/0049-NIST-curves-hybrid-KEX-implementation.patch b/0049-NIST-curves-hybrid-KEX-implementation.patch deleted file mode 100644 index 9ce23be..0000000 --- a/0049-NIST-curves-hybrid-KEX-implementation.patch +++ /dev/null @@ -1,1216 +0,0 @@ -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/0044-openssh-9.9p1-openssl-mlkem.patch b/0049-openssh-9.9p1-openssl-mlkem.patch similarity index 91% rename from 0044-openssh-9.9p1-openssl-mlkem.patch rename to 0049-openssh-9.9p1-openssl-mlkem.patch index 3e72647..e04d194 100644 --- a/0044-openssh-9.9p1-openssl-mlkem.patch +++ b/0049-openssh-9.9p1-openssl-mlkem.patch @@ -1,19 +1,19 @@ -From 21202362f4ddaeb630d873fb426039004ac82338 Mon Sep 17 00:00:00 2001 +From 0a621a2ccb8444e4c6da906b0e112e0522658122 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 15 May 2025 13:43:29 +0200 -Subject: [PATCH 44/53] openssh-9.9p1-openssl-mlkem +Subject: [PATCH 49/50] openssh-9.9p1-openssl-mlkem --- - kex-names.c | 23 +++- + kex-names.c | 20 +++ kexmlkem768x25519.c | 291 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 313 insertions(+), 1 deletion(-) + 2 files changed, 311 insertions(+) diff --git a/kex-names.c b/kex-names.c -index 1360a4095..9c96e5cb0 100644 +index cd3902ad..36a953ab 100644 --- a/kex-names.c +++ b/kex-names.c -@@ -109,6 +109,19 @@ static const struct kexalg gss_kexalgs[] = { - { NULL, 0, -1, -1, 0}, +@@ -108,6 +108,19 @@ static const struct kexalg gss_kexalgs[] = { + { NULL, 0, -1, -1}, }; +static int is_mlkem768_available() @@ -32,21 +32,17 @@ index 1360a4095..9c96e5cb0 100644 static char * kex_alg_list_internal(char sep, const struct kexalg *algs) { -@@ -116,8 +129,12 @@ kex_alg_list_internal(char sep, const struct kexalg *algs) +@@ -116,6 +129,9 @@ kex_alg_list_internal(char sep, const struct kexalg *algs) const struct kexalg *k; - char sep_str[2] = {sep, '\0'}; -- for (k = kexalgs; k->name != NULL; k++) -+ for (k = kexalgs; k->name != NULL; k++) { + for (k = algs; k->name != NULL; k++) { + if (strcmp(k->name, KEX_MLKEM768X25519_SHA256) == 0 + && !is_mlkem768_available()) + continue; - xextendf(&ret, sep_str, "%s", k->name); -+ } - - return ret; - } -@@ -139,6 +156,10 @@ kex_alg_by_name(const char *name) + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(k->name); +@@ -147,6 +163,10 @@ kex_alg_by_name(const char *name) { const struct kexalg *k; @@ -58,10 +54,10 @@ index 1360a4095..9c96e5cb0 100644 if (strcmp(k->name, name) == 0) return k; diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c -index 2585d1db3..ab6167221 100644 +index 2b5d3960..670049dc 100644 --- a/kexmlkem768x25519.c +++ b/kexmlkem768x25519.c -@@ -44,10 +44,127 @@ +@@ -48,10 +48,127 @@ #ifdef USE_MLKEM768X25519 #include "libcrux_mlkem768_sha3.h" @@ -189,7 +185,7 @@ index 2585d1db3..ab6167221 100644 struct sshbuf *buf = NULL; u_char rnd[LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN], *cp = NULL; size_t need; -@@ -82,6 +199,36 @@ kex_kem_mlkem768x25519_keypair(struct kex *kex) +@@ -86,6 +203,36 @@ kex_kem_mlkem768x25519_keypair(struct kex *kex) explicit_bzero(rnd, sizeof(rnd)); sshbuf_free(buf); return r; @@ -226,7 +222,7 @@ index 2585d1db3..ab6167221 100644 } int -@@ -89,6 +236,7 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, +@@ -93,6 +240,7 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, const struct sshbuf *client_blob, struct sshbuf **server_blobp, struct sshbuf **shared_secretp) { @@ -234,7 +230,7 @@ index 2585d1db3..ab6167221 100644 struct sshbuf *server_blob = NULL; struct sshbuf *buf = NULL; const u_char *client_pub; -@@ -181,12 +329,97 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, +@@ -185,12 +333,97 @@ kex_kem_mlkem768x25519_enc(struct kex *kex, sshbuf_free(server_blob); sshbuf_free(buf); return r; @@ -332,7 +328,7 @@ index 2585d1db3..ab6167221 100644 struct sshbuf *buf = NULL; u_char mlkem_key[crypto_kem_mlkem768_BYTES]; const u_char *ciphertext, *server_pub; -@@ -254,6 +487,64 @@ kex_kem_mlkem768x25519_dec(struct kex *kex, +@@ -258,6 +491,64 @@ kex_kem_mlkem768x25519_dec(struct kex *kex, explicit_bzero(mlkem_key, sizeof(mlkem_key)); sshbuf_free(buf); return r; @@ -398,5 +394,5 @@ index 2585d1db3..ab6167221 100644 #else /* USE_MLKEM768X25519 */ int -- -2.52.0 +2.49.0 diff --git a/0050-Provide-a-way-to-disable-GSSAPIDelegateCredentials-s.patch b/0050-Provide-a-way-to-disable-GSSAPIDelegateCredentials-s.patch deleted file mode 100644 index 85c4140..0000000 --- a/0050-Provide-a-way-to-disable-GSSAPIDelegateCredentials-s.patch +++ /dev/null @@ -1,139 +0,0 @@ -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/0045-openssh-9.9p2-error_processing.patch b/0050-openssh-9.9p2-error_processing.patch similarity index 68% rename from 0045-openssh-9.9p2-error_processing.patch rename to 0050-openssh-9.9p2-error_processing.patch index 48aa76a..aed1c30 100644 --- a/0045-openssh-9.9p2-error_processing.patch +++ b/0050-openssh-9.9p2-error_processing.patch @@ -1,17 +1,17 @@ -From edbbdc306c1710dae777ef315a0d2c5f43134d33 Mon Sep 17 00:00:00 2001 +From fd32e753ae7f3b314712e6aa8b2bed3c1fca1ef5 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Fri, 16 May 2025 14:53:54 +0200 -Subject: [PATCH 45/53] openssh-9.9p2-error_processing +Subject: [PATCH 50/51] openssh-9.9p2-error_processing --- ssh-agent.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ssh-agent.c b/ssh-agent.c -index df241379c..dc246066d 100644 +index 798bf9b6..dfb6ac72 100644 --- a/ssh-agent.c +++ b/ssh-agent.c -@@ -1346,6 +1346,8 @@ process_add_identity(SocketEntry *e) +@@ -1377,6 +1377,8 @@ process_add_identity(SocketEntry *e) if ((r = sshkey_private_deserialize(e->request, &k)) != 0 || k == NULL || (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { @@ -21,5 +21,5 @@ index df241379c..dc246066d 100644 goto out; } -- -2.52.0 +2.49.0 diff --git a/0046-Provide-better-error-for-non-supported-private-keys.patch b/0051-Provide-better-error-for-non-supported-private-keys.patch similarity index 67% rename from 0046-Provide-better-error-for-non-supported-private-keys.patch rename to 0051-Provide-better-error-for-non-supported-private-keys.patch index dd30967..9c1aa4d 100644 --- a/0046-Provide-better-error-for-non-supported-private-keys.patch +++ b/0051-Provide-better-error-for-non-supported-private-keys.patch @@ -1,7 +1,7 @@ -From 0772377e00b13f5afaa1b146ce32d0218e9f0d24 Mon Sep 17 00:00:00 2001 +From 4965cdbc1ee1e6a0c665797bb8b944d96d3d411f Mon Sep 17 00:00:00 2001 From: Zoltan Fridrich Date: Wed, 16 Apr 2025 15:11:59 +0200 -Subject: [PATCH 46/53] Provide better error for non-supported private keys +Subject: [PATCH 51/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 394d9b105..eba55ef92 100644 +index ca1cdb642..aada474e0 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -3539,6 +3539,9 @@ translate_libcrypto_error(unsigned long pem_err) +@@ -3582,6 +3582,9 @@ translate_libcrypto_error(unsigned long pem_err) return SSH_ERR_LIBCRYPTO_ERROR; } case ERR_LIB_ASN1: @@ -23,5 +23,5 @@ index 394d9b105..eba55ef92 100644 } return SSH_ERR_LIBCRYPTO_ERROR; -- -2.52.0 +2.49.0 diff --git a/0047-Ignore-bad-hostkeys-in-known_hosts-file.patch b/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch similarity index 88% rename from 0047-Ignore-bad-hostkeys-in-known_hosts-file.patch rename to 0052-Ignore-bad-hostkeys-in-known_hosts-file.patch index 3bfab92..f071225 100644 --- a/0047-Ignore-bad-hostkeys-in-known_hosts-file.patch +++ b/0052-Ignore-bad-hostkeys-in-known_hosts-file.patch @@ -1,7 +1,7 @@ -From d458a65ccac2283563c0fc0962519bb5a9bbd315 Mon Sep 17 00:00:00 2001 +From 9ed09ef158a113e21be7b3fefa7c5f932632749b Mon Sep 17 00:00:00 2001 From: Zoltan Fridrich Date: Mon, 5 May 2025 11:52:25 +0200 -Subject: [PATCH 47/53] Ignore bad hostkeys in known_hosts file +Subject: [PATCH 52/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 4cec57da5..652d15762 100644 +index c5669c703..5c402f501 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 7d6ba516e..320ac6834 100644 +index abc8b8439..33787a8d4 100644 --- a/ssh.c +++ b/ssh.c -@@ -106,6 +106,7 @@ +@@ -110,6 +110,7 @@ #include "ssherr.h" #include "myproposal.h" #include "utf8.h" @@ -73,7 +73,7 @@ index 7d6ba516e..320ac6834 100644 #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" -@@ -1409,6 +1410,7 @@ main(int ac, char **av) +@@ -1397,6 +1398,7 @@ main(int ac, char **av) options.update_hostkeys = 0; } } @@ -82,5 +82,5 @@ index 7d6ba516e..320ac6834 100644 fatal("Invalid number of ConnectionAttempts"); -- -2.52.0 +2.49.0 diff --git a/0048-support-authentication-indicators-in-GSSAPI.patch b/0053-support-authentication-indicators-in-GSSAPI.patch similarity index 94% rename from 0048-support-authentication-indicators-in-GSSAPI.patch rename to 0053-support-authentication-indicators-in-GSSAPI.patch index 664a006..237e45d 100644 --- a/0048-support-authentication-indicators-in-GSSAPI.patch +++ b/0053-support-authentication-indicators-in-GSSAPI.patch @@ -1,7 +1,7 @@ -From 1cf5e40e14d707de2318747758b012fc7245cb7b Mon Sep 17 00:00:00 2001 +From 5d5a66e96ad03132f65371070f4fa475f10207d9 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 10 Jun 2024 23:00:03 +0300 -Subject: [PATCH 48/53] support authentication indicators in GSSAPI +Subject: [PATCH] support authentication indicators in GSSAPI RFC 6680 defines a set of GSSAPI extensions to handle attributes associated with the GSSAPI names. MIT Kerberos and FreeIPA use @@ -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 805be4b5e..9d3b19925 100644 +index d92a85809..2cbe20bf3 100644 --- a/configure.ac +++ b/configure.ac -@@ -5050,6 +5050,7 @@ AC_ARG_WITH([kerberos5], +@@ -5004,6 +5004,7 @@ AC_ARG_WITH([kerberos5], AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h]) AC_CHECK_HEADERS([gssapi_krb5.h gssapi/gssapi_krb5.h]) AC_CHECK_HEADERS([gssapi_generic.h gssapi/gssapi_generic.h]) @@ -143,7 +143,7 @@ index 03188d9b3..2c786ef14 100644 return retval; } diff --git a/gss-serv.c b/gss-serv.c -index d2bc03486..be80e17ca 100644 +index 9d5435eda..5c0491cf1 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -54,7 +54,7 @@ extern ServerOptions options; @@ -285,10 +285,10 @@ index d2bc03486..be80e17ca 100644 sizeof(ssh_gssapi_client)); return 0; diff --git a/servconf.c b/servconf.c -index f78615c28..e53e8ea30 100644 +index e7e4ad046..aab653244 100644 --- a/servconf.c +++ b/servconf.c -@@ -146,6 +146,7 @@ initialize_server_options(ServerOptions *options) +@@ -147,6 +147,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 f78615c28..e53e8ea30 100644 options->use_kuserok = -1; options->enable_k5users = -1; options->password_authentication = -1; -@@ -591,7 +592,7 @@ typedef enum { +@@ -598,7 +599,7 @@ typedef enum { sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, @@ -305,7 +305,7 @@ index f78615c28..e53e8ea30 100644 sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -687,6 +688,7 @@ static struct { +@@ -694,6 +695,7 @@ static struct { { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, @@ -313,7 +313,7 @@ index f78615c28..e53e8ea30 100644 #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, -@@ -696,6 +698,7 @@ static struct { +@@ -703,6 +705,7 @@ static struct { { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, { "gssapienablek5users", sUnsupported, SSHCFG_ALL }, @@ -321,7 +321,7 @@ index f78615c28..e53e8ea30 100644 #endif { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, -@@ -1722,6 +1725,15 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1730,6 +1733,15 @@ process_server_config_line_depth(ServerOptions *options, char *line, options->gss_kex_algorithms = xstrdup(arg); break; @@ -337,7 +337,7 @@ index f78615c28..e53e8ea30 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3344,6 +3356,7 @@ dump_config(ServerOptions *o) +@@ -3351,6 +3363,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); @@ -346,10 +346,10 @@ index f78615c28..e53e8ea30 100644 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --git a/servconf.h b/servconf.h -index c08cf6a7a..c7cec5ece 100644 +index 7c7e5d434..7c41df417 100644 --- a/servconf.h +++ b/servconf.h -@@ -179,6 +179,7 @@ typedef struct { +@@ -181,6 +181,7 @@ typedef struct { char **allow_groups; u_int num_deny_groups; char **deny_groups; @@ -357,7 +357,7 @@ index c08cf6a7a..c7cec5ece 100644 u_int num_subsystems; char **subsystem_name; -@@ -308,6 +309,7 @@ TAILQ_HEAD(include_list, include_item); +@@ -310,6 +311,7 @@ TAILQ_HEAD(include_list, include_item); M_CP_STROPT(routing_domain); \ M_CP_STROPT(permit_user_env_allowlist); \ M_CP_STROPT(pam_service_name); \ @@ -366,7 +366,7 @@ index c08cf6a7a..c7cec5ece 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 329dc9da0..1506719a9 100644 +index a894e23c9..59cf46d47 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -34,6 +34,12 @@ @@ -382,7 +382,7 @@ index 329dc9da0..1506719a9 100644 #ifdef KRB5 # ifndef HEIMDAL # ifdef HAVE_GSSAPI_GENERIC_H -@@ -112,6 +118,7 @@ typedef struct { +@@ -107,6 +113,7 @@ typedef struct { ssh_gssapi_ccache store; int used; int updated; @@ -391,7 +391,7 @@ index 329dc9da0..1506719a9 100644 typedef struct ssh_gssapi_mech_struct { diff --git a/sshd_config.5 b/sshd_config.5 -index c172d5aab..676d6d4d2 100644 +index 583a01cdb..90ab87edd 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -785,6 +785,50 @@ gss-nistp256-sha256- @@ -446,5 +446,5 @@ index c172d5aab..676d6d4d2 100644 The default is handled system-wide by .Xr crypto-policies 7 . -- -2.52.0 +2.49.0 diff --git a/1000-openssh-6.7p1-coverity.patch b/1000-openssh-coverity.patch similarity index 73% rename from 1000-openssh-6.7p1-coverity.patch rename to 1000-openssh-coverity.patch index 40c298e..88362eb 100644 --- a/1000-openssh-6.7p1-coverity.patch +++ b/1000-openssh-coverity.patch @@ -1,7 +1,7 @@ -From aecc5861e1cf7094a32f893ae4bfd8409b77e5cd Mon Sep 17 00:00:00 2001 +From 24c411970682dc67873c36bac05b4b460d68a628 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy -Date: Fri, 12 Dec 2025 14:25:41 +0100 -Subject: [PATCH 53/53] openssh-6.7p1-coverity +Date: Thu, 15 May 2025 13:43:29 +0200 +Subject: [PATCH 50/50] openssh-6.7p1-coverity --- auth-krb5.c | 2 ++ @@ -15,10 +15,12 @@ Subject: [PATCH 53/53] openssh-6.7p1-coverity readconf.c | 1 + servconf.c | 5 +++-- serverloop.c | 2 +- - 11 files changed, 24 insertions(+), 11 deletions(-) + ssh-agent.c | 1 + + ssh-keygen.c | 3 +++ + 13 files changed, 28 insertions(+), 11 deletions(-) diff --git a/auth-krb5.c b/auth-krb5.c -index b9c261a24..a37be93c3 100644 +index bae153c9..209a3265 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -427,6 +427,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm @@ -38,10 +40,10 @@ index b9c261a24..a37be93c3 100644 } /* make sure the KRB5CCNAME is set for non-standard location */ diff --git a/gss-genr.c b/gss-genr.c -index f2d6f59e5..91602e045 100644 +index 3034370c..c357e973 100644 --- a/gss-genr.c +++ b/gss-genr.c -@@ -178,8 +178,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, +@@ -168,8 +168,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, enclen = __b64_ntop(digest, ssh_digest_bytes(SSH_DIGEST_MD5), encoded, ssh_digest_bytes(SSH_DIGEST_MD5) * 2); @@ -53,10 +55,10 @@ index f2d6f59e5..91602e045 100644 (p = strsep(&cp, ","))) { if (sshbuf_len(buf) != 0 && diff --git a/krl.c b/krl.c -index bea5b1b98..4dd8a24a9 100644 +index 0d0f6953..d8517f12 100644 --- a/krl.c +++ b/krl.c -@@ -1205,6 +1205,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) +@@ -1202,6 +1202,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); free(rb.blob); @@ -64,7 +66,7 @@ index bea5b1b98..4dd8a24a9 100644 if (erb != NULL) { KRL_DBG(("revoked by key SHA1")); return SSH_ERR_KEY_REVOKED; -@@ -1215,6 +1216,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) +@@ -1212,6 +1213,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb); free(rb.blob); @@ -72,7 +74,7 @@ index bea5b1b98..4dd8a24a9 100644 if (erb != NULL) { KRL_DBG(("revoked by key SHA256")); return SSH_ERR_KEY_REVOKED; -@@ -1226,6 +1228,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) +@@ -1223,6 +1225,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); free(rb.blob); @@ -81,10 +83,10 @@ index bea5b1b98..4dd8a24a9 100644 KRL_DBG(("revoked by explicit key")); return SSH_ERR_KEY_REVOKED; diff --git a/loginrec.c b/loginrec.c -index 7d1c9dd43..a017e173b 100644 +index c4a9bd48..2583612c 100644 --- a/loginrec.c +++ b/loginrec.c -@@ -677,9 +677,11 @@ construct_utmp(struct logininfo *li, +@@ -683,9 +683,11 @@ construct_utmp(struct logininfo *li, */ /* Use strncpy because we don't necessarily want null termination */ @@ -97,10 +99,10 @@ index 7d1c9dd43..a017e173b 100644 MIN_SIZEOF(ut->ut_host, li->hostname)); # endif diff --git a/misc.c b/misc.c -index 2fd14159d..d4c4e4164 100644 +index 09722962..cd71c1b2 100644 --- a/misc.c +++ b/misc.c -@@ -1573,6 +1573,8 @@ sanitise_stdfd(void) +@@ -1556,6 +1556,8 @@ sanitise_stdfd(void) } if (nullfd > STDERR_FILENO) close(nullfd); @@ -109,7 +111,7 @@ index 2fd14159d..d4c4e4164 100644 } char * -@@ -2773,6 +2775,7 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) +@@ -2749,6 +2751,7 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr) } if (devnull > STDERR_FILENO) close(devnull); @@ -118,10 +120,10 @@ index 2fd14159d..d4c4e4164 100644 } diff --git a/monitor.c b/monitor.c -index 2f154a3d7..f959e0124 100644 +index 19cb058e..58fbac9d 100644 --- a/monitor.c +++ b/monitor.c -@@ -405,7 +405,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -415,7 +415,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) mm_get_keystate(ssh, pmonitor); /* Drain any buffered messages from the child */ @@ -129,8 +131,8 @@ index 2f154a3d7..f959e0124 100644 + while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) ; - /* Wait for the child's exit status */ -@@ -1819,7 +1819,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) + if (pmonitor->m_recvfd >= 0) +@@ -1813,7 +1813,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) s->ptymaster = s->ptyfd; debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd); @@ -140,7 +142,7 @@ index 2f154a3d7..f959e0124 100644 error: diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c -index 346c7fe56..f42792fde 100644 +index 346c7fe5..f42792fd 100644 --- a/openbsd-compat/bindresvport.c +++ b/openbsd-compat/bindresvport.c @@ -59,7 +59,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) @@ -153,7 +155,7 @@ index 346c7fe56..f42792fde 100644 if (sa == NULL) { diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c -index 26bdc3e08..8e2939b95 100644 +index 26bdc3e0..8e2939b9 100644 --- a/openbsd-compat/bsd-pselect.c +++ b/openbsd-compat/bsd-pselect.c @@ -85,13 +85,13 @@ pselect_notify_setup(void) @@ -184,10 +186,10 @@ index 26bdc3e08..8e2939b95 100644 FD_CLR(notify_pipe[0], readset); } diff --git a/readconf.c b/readconf.c -index b6ad47b49..75e1c953c 100644 +index ea9d293c..9680c38c 100644 --- a/readconf.c +++ b/readconf.c -@@ -2170,6 +2170,7 @@ parse_pubkey_algos: +@@ -2164,6 +2164,7 @@ parse_pubkey_algos: } else if (r != 0) { error("%.200s line %d: glob failed for %s.", filename, linenum, arg2); @@ -196,10 +198,10 @@ index b6ad47b49..75e1c953c 100644 } free(arg2); diff --git a/servconf.c b/servconf.c -index 956205f6d..1093dcbac 100644 +index 8b708cbf..e7e4ad04 100644 --- a/servconf.c +++ b/servconf.c -@@ -2307,8 +2307,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -2293,8 +2293,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, if (*activep && *charptr == NULL) { *charptr = tilde_expand_filename(arg, getuid()); /* increase optional counter */ @@ -212,10 +214,10 @@ index 956205f6d..1093dcbac 100644 break; diff --git a/serverloop.c b/serverloop.c -index 55411a6b4..acc721cd1 100644 +index 9c5b1567..768ee9fa 100644 --- a/serverloop.c +++ b/serverloop.c -@@ -533,7 +533,7 @@ server_request_tun(struct ssh *ssh) +@@ -511,7 +511,7 @@ server_request_tun(struct ssh *ssh) debug_f("invalid tun"); goto done; } @@ -224,6 +226,32 @@ index 55411a6b4..acc721cd1 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.52.0 +2.49.0 diff --git a/openssh.spec b/openssh.spec index ff38f4b..1cc0674 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.2p1 +%global openssh_ver 10.0p1 Summary: An open source implementation of SSH protocol version 2 Name: openssh Version: %{openssh_ver} -Release: 1%{?dist} +Release: 6%{?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,114 +67,124 @@ Source23: parallel_test.Makefile #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) Patch0001: 0001-openssh-7.8p1-role-mls.patch -Patch0002: 0002-openssh-6.6p1-keycat.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 #https://bugzilla.mindrot.org/show_bug.cgi?id=1644 -Patch0003: 0003-openssh-6.6p1-allow-ip-opts.patch +Patch0004: 0004-openssh-6.6p1-allow-ip-opts.patch #(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925 -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 +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 #https://bugzilla.redhat.com/show_bug.cgi?id=198332 -Patch0008: 0008-openssh-4.3p2-askpass-grab-info.patch +Patch0009: 0009-openssh-4.3p2-askpass-grab-info.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) -Patch0009: 0009-openssh-8.7p1-redhat.patch +Patch0010: 0010-openssh-8.7p1-redhat.patch # warn users for unsupported UsePAM=no (#757545) -Patch0010: 0010-openssh-7.8p1-UsePAM-warning.patch +Patch0011: 0011-openssh-7.8p1-UsePAM-warning.patch # GSSAPI Key Exchange (RFC 4462 + RFC 8732) -Patch0011: 0011-openssh-9.6p1-gssapi-keyex.patch +# 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 #http://www.mail-archive.com/kerberos@mit.edu/msg17591.html -Patch0012: 0012-openssh-6.6p1-force_krb.patch +Patch0013: 0013-openssh-6.6p1-force_krb.patch # Improve ccache handling in openssh (#991186, #1199363, #1566494) # https://bugzilla.mindrot.org/show_bug.cgi?id=2775 -Patch0013: 0013-openssh-7.7p1-gssapi-new-unique.patch +Patch0014: 0014-openssh-7.7p1-gssapi-new-unique.patch # Respect k5login_directory option in krk5.conf (#1328243) -Patch0014: 0014-openssh-7.2p2-k5login_directory.patch +Patch0015: 0015-openssh-7.2p2-k5login_directory.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 -Patch0015: 0015-openssh-6.6p1-kuserok.patch +Patch0016: 0016-openssh-6.6p1-kuserok.patch # Use tty allocation for a remote scp (#985650) -Patch0016: 0016-openssh-6.4p1-fromto-remote.patch +Patch0017: 0017-openssh-6.4p1-fromto-remote.patch +# privsep_preauth: use SELinux context from selinux-policy (#1008580) +Patch0018: 0018-openssh-6.6.1p1-selinux-contexts.patch # log via monitor in chroots without /dev/log (#2681) -Patch0017: 0017-openssh-6.6.1p1-log-in-chroot.patch +Patch0019: 0019-openssh-6.6.1p1-log-in-chroot.patch # scp file into non-existing directory (#1142223) -Patch0018: 0018-openssh-6.6.1p1-scp-non-existing-directory.patch +Patch0020: 0020-openssh-6.6.1p1-scp-non-existing-directory.patch # add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843) # CVE-2014-9278 -Patch0019: 0019-openssh-6.6p1-GSSAPIEnablek5users.patch +Patch0021: 0021-openssh-6.6p1-GSSAPIEnablek5users.patch # apply upstream patch and make sshd -T more consistent (#1187521) -Patch0020: 0020-openssh-6.8p1-sshdT-output.patch +Patch0022: 0022-openssh-6.8p1-sshdT-output.patch # Add sftp option to force mode of created files (#1191055) -Patch0021: 0021-openssh-6.7p1-sftp-force-permission.patch +Patch0023: 0023-openssh-6.7p1-sftp-force-permission.patch # make s390 use /dev/ crypto devices -- ignore closefrom -Patch0022: 0022-openssh-7.2p2-s390-closefrom.patch +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 # Pass inetd flags for SELinux down to openbsd compat level -Patch0023: 0023-openssh-7.6p1-cleanup-selinux.patch +Patch0026: 0026-openssh-7.6p1-cleanup-selinux.patch # Sandbox adjustments for s390 and audit -Patch0024: 0024-openssh-7.5p1-sandbox.patch +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 # Unbreak scp between two IPv6 hosts (#1620333) -Patch0025: 0025-openssh-7.8p1-scp-ipv6.patch +Patch0029: 0029-openssh-7.8p1-scp-ipv6.patch # Mention crypto-policies in manual pages (#1668325) # clarify rhbz#2068423 on the man page of ssh_config -Patch0026: 0026-openssh-8.0p1-crypto-policies.patch +Patch0030: 0030-openssh-8.0p1-crypto-policies.patch # Use OpenSSL KDF (#1631761) -Patch0027: 0027-openssh-8.0p1-openssl-kdf.patch +Patch0031: 0031-openssh-8.0p1-openssl-kdf.patch # sk-dummy.so built with -fvisibility=hidden does not work -Patch0028: 0028-openssh-8.2p1-visibility.patch +Patch0032: 0032-openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 -Patch0029: 0029-openssh-8.2p1-x11-without-ipv6.patch +Patch0033: 0033-openssh-8.2p1-x11-without-ipv6.patch # sshd provides PAM an incorrect error code (#1879503) -Patch0030: 0030-openssh-8.0p1-preserve-pam-errors.patch +Patch0034: 0034-openssh-8.0p1-preserve-pam-errors.patch # Implement kill switch for SCP protocol -Patch0031: 0031-openssh-8.7p1-scp-kill-switch.patch +Patch0035: 0035-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 -Patch0032: 0032-openssh-8.7p1-recursive-scp.patch +Patch0036: 0036-openssh-8.7p1-recursive-scp.patch # Downstream alias for MinRSABits -Patch0033: 0033-openssh-8.7p1-minrsabits.patch +Patch0037: 0037-openssh-8.7p1-minrsabits.patch # downstream only, IBMCA tentative fix # From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14 -Patch0034: 0034-openssh-8.7p1-ibmca.patch +Patch0038: 0038-openssh-8.7p1-ibmca.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 # record pfs= field in CRYPTO_SESSION audit event -Patch0035: 0035-openssh-7.6p1-audit.patch +Patch0039: 0039-openssh-7.6p1-audit.patch # Audit race condition in forked child (#1310684) -Patch0036: 0036-openssh-7.1p2-audit-race-condition.patch +Patch0040: 0040-openssh-7.1p2-audit-race-condition.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2049947 -Patch0037: 0037-openssh-9.0p1-audit-log.patch -Patch0038: 0038-openssh-7.7p1-fips.patch +Patch0041: 0041-openssh-9.0p1-audit-log.patch +Patch0042: 0042-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 -Patch0039: 0039-openssh-8.7p1-ssh-manpage.patch +Patch0043: 0043-openssh-8.7p1-ssh-manpage.patch # Don't propose disallowed algorithms during hostkey negotiation # upstream MR: # https://github.com/openssh/openssh-portable/pull/323 -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 +Patch0044: 0044-openssh-8.7p1-negotiate-supported-algs.patch +Patch0045: 0045-openssh-9.0p1-evp-fips-kex.patch +Patch0046: 0046-openssh-8.7p1-nohostsha1proof.patch +Patch0047: 0047-openssh-9.6p1-pam-rhost.patch +Patch0048: 0048-openssh-9.9p1-separate-keysign.patch +Patch0049: 0049-openssh-9.9p1-openssl-mlkem.patch # https://www.openwall.com/lists/oss-security/2025/02/22/1 -Patch0045: 0045-openssh-9.9p2-error_processing.patch +Patch0050: 0050-openssh-9.9p2-error_processing.patch # https://github.com/openssh/openssh-portable/pull/564 -Patch0046: 0046-Provide-better-error-for-non-supported-private-keys.patch +Patch0051: 0051-Provide-better-error-for-non-supported-private-keys.patch # https://github.com/openssh/openssh-portable/pull/567 -Patch0047: 0047-Ignore-bad-hostkeys-in-known_hosts-file.patch +Patch0052: 0052-Ignore-bad-hostkeys-in-known_hosts-file.patch # https://github.com/openssh/openssh-portable/pull/500 -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 +Patch0053: 0053-support-authentication-indicators-in-GSSAPI.patch + #https://bugzilla.mindrot.org/show_bug.cgi?id=2581 -Patch1000: 1000-openssh-6.7p1-coverity.patch +Patch1000: 1000-openssh-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 @@ -344,6 +354,7 @@ 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 \ @@ -575,24 +586,9 @@ 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 +* Wed Dec 10 2025 Pavol Žáčik - 10.0p1-6 - 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 318e485..10b461b 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (openssh-10.2p1.tar.gz) = 66f3dd646179e71aaf41c33b6f14a207dc873d71d24f11c130a89dee317ee45398b818e5b94887b5913240964a38630d7bca3e481e0f1eff2e41d9e1cfdbdfc5 -SHA512 (openssh-10.2p1.tar.gz.asc) = f1f71700b1b0b2117aed505488b98b7ebb51ce26e53184b08df0b07aa2c5a1e54dc4d3cbcbe871b5ad849a2a0e22b02af318ff22a68c980ab53b04be03c9bf3c +SHA512 (openssh-10.0p1.tar.gz) = 2daa1fcf95793b23810142077e68ddfabdf3732b207ef4f033a027f72d733d0e9bcdb6f757e7f3a5934b972de05bfaae3baae381cfc7a400cd8ab4d4e277a0ed +SHA512 (openssh-10.0p1.tar.gz.asc) = 6ab9deb4233ff159e55a18c9fc07d5ff8a41723dad74aa3d803e1476b585f5662aba34f8a7a1f5fe1d248f3ff3cd663f2c2fb8e399c6a4723b6215b0eb423d13 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21