diff --git a/0001-upstream-correctly-restore-sigprocmask-around-ppoll.patch b/0001-upstream-correctly-restore-sigprocmask-around-ppoll.patch new file mode 100644 index 0000000..25a13fe --- /dev/null +++ b/0001-upstream-correctly-restore-sigprocmask-around-ppoll.patch @@ -0,0 +1,55 @@ +From 66aaa678dbe59aa21d0d9d89a3596ecedde0254b Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Tue, 30 Apr 2024 02:14:10 +0000 +Subject: [PATCH] upstream: correctly restore sigprocmask around ppoll() + reported +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +by Tõivo Leedjärv; ok deraadt@ + +OpenBSD-Commit-ID: c0c0f89de5294a166578f071eade2501929c4686 +--- + clientloop.c | 4 ++-- + serverloop.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/clientloop.c b/clientloop.c +index be8bb5fc1f2..8ea2ada4216 100644 +--- a/clientloop.c ++++ b/clientloop.c +#@@ -1,4 +1,4 @@ +#-/* $OpenBSD: clientloop.c,v 1.404 2024/04/30 02:10:49 djm Exp $ */ +#+/* $OpenBSD: clientloop.c,v 1.405 2024/04/30 02:14:10 djm Exp $ */ +# /* +# * Author: Tatu Ylonen +# * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +@@ -1585,7 +1585,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, + client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc, + &npfd_active, channel_did_enqueue, &osigset, + &conn_in_ready, &conn_out_ready); +- if (sigprocmask(SIG_UNBLOCK, &bsigset, &osigset) == -1) ++ if (sigprocmask(SIG_SETMASK, &osigset, NULL) == -1) + error_f("osigset sigprocmask: %s", strerror(errno)); + + if (quit_pending) +diff --git a/serverloop.c b/serverloop.c +index f3683c2e4a6..94c8943a616 100644 +--- a/serverloop.c ++++ b/serverloop.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: serverloop.c,v 1.237 2023/08/21 04:59:54 djm Exp $ */ ++/* $OpenBSD: serverloop.c,v 1.238 2024/04/30 02:14:10 djm Exp $ */ + /* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +@@ -380,7 +380,7 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) + wait_until_can_do_something(ssh, connection_in, connection_out, + &pfd, &npfd_alloc, &npfd_active, &osigset, + &conn_in_ready, &conn_out_ready); +- if (sigprocmask(SIG_UNBLOCK, &bsigset, &osigset) == -1) ++ if (sigprocmask(SIG_SETMASK, &osigset, NULL) == -1) + error_f("osigset sigprocmask: %s", strerror(errno)); + + if (received_sigterm) { diff --git a/0001-upstream-fix-proxy-multiplexing-mode_-broken-when-keystroke.patch b/0001-upstream-fix-proxy-multiplexing-mode_-broken-when-keystroke.patch new file mode 100644 index 0000000..feffd9c --- /dev/null +++ b/0001-upstream-fix-proxy-multiplexing-mode_-broken-when-keystroke.patch @@ -0,0 +1,32 @@ +From 9844aa2521ccfb1a2d73745680327b79e0574445 Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Wed, 21 Feb 2024 05:57:34 +0000 +Subject: [PATCH] upstream: fix proxy multiplexing mode, broken when keystroke + timing + +obfuscation was added. GHPR#463 from montag451 + +OpenBSD-Commit-ID: 4e412d59b3f557d431f1d81c715a3bc0491cc677 +--- + clientloop.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/clientloop.c b/clientloop.c +index eb4902905fb..8ec36af94b3 100644 +--- a/clientloop.c ++++ b/clientloop.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: clientloop.c,v 1.402 2023/11/24 00:31:30 dtucker Exp $ */ ++/* $OpenBSD: clientloop.c,v 1.403 2024/02/21 05:57:34 djm Exp $ */ + /* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +@@ -517,7 +517,7 @@ send_chaff(struct ssh *ssh) + { + int r; + +- if ((ssh->kex->flags & KEX_HAS_PING) == 0) ++ if (ssh->kex == NULL || (ssh->kex->flags & KEX_HAS_PING) == 0) + return 0; + /* XXX probabilistically send chaff? */ + /* diff --git a/0001-upstream-when-sending-ObscureKeystrokeTiming-chaff-packets_.patch b/0001-upstream-when-sending-ObscureKeystrokeTiming-chaff-packets_.patch new file mode 100644 index 0000000..6229cba --- /dev/null +++ b/0001-upstream-when-sending-ObscureKeystrokeTiming-chaff-packets_.patch @@ -0,0 +1,38 @@ +From 146c420d29d055cc75c8606327a1cf8439fe3a08 Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Mon, 1 Jul 2024 04:31:17 +0000 +Subject: [PATCH] upstream: when sending ObscureKeystrokeTiming chaff packets, + we + +can't rely on channel_did_enqueue to tell that there is data to send. This +flag indicates that the channels code enqueued a packet on _this_ ppoll() +iteration, not that data was enqueued in _any_ ppoll() iteration in the +timeslice. ok markus@ + +OpenBSD-Commit-ID: 009b74fd2769b36b5284a0188ade182f00564136 +--- + clientloop.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/clientloop.c b/clientloop.c +index 0b6f3c9be02..8ed8b1c3449 100644 +--- a/clientloop.c ++++ b/clientloop.c +#@@ -1,4 +1,4 @@ +#-/* $OpenBSD: clientloop.c,v 1.407 2024/05/17 06:42:04 jsg Exp $ */ +#+/* $OpenBSD: clientloop.c,v 1.408 2024/07/01 04:31:17 djm Exp $ */ +# /* +# * Author: Tatu Ylonen +# * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +@@ -607,8 +607,9 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout, + if (timespeccmp(&now, &chaff_until, >=)) { + /* Stop if there have been no keystrokes for a while */ + stop_reason = "chaff time expired"; +- } else if (timespeccmp(&now, &next_interval, >=)) { +- /* Otherwise if we were due to send, then send chaff */ ++ } else if (timespeccmp(&now, &next_interval, >=) && ++ !ssh_packet_have_data_to_write(ssh)) { ++ /* If due to send but have no data, then send chaff */ + if (send_chaff(ssh)) + nchaff++; + } diff --git a/fix-CVE-2024-6387.patch b/fix-CVE-2024-6387.patch new file mode 100644 index 0000000..ba9d506 --- /dev/null +++ b/fix-CVE-2024-6387.patch @@ -0,0 +1,19 @@ +Index: openssh-9.6p1/log.c +=================================================================== +--- openssh-9.6p1.orig/log.c ++++ openssh-9.6p1/log.c +@@ -451,12 +451,14 @@ void + sshsigdie(const char *file, const char *func, int line, int showfunc, + LogLevel level, const char *suffix, const char *fmt, ...) + { ++#if 0 + va_list args; + + va_start(args, fmt); + sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_FATAL, + suffix, fmt, args); + va_end(args); ++#endif + _exit(1); + } + diff --git a/fix-memleak-in-process_server_config_line_depth.patch b/fix-memleak-in-process_server_config_line_depth.patch deleted file mode 100644 index 330be2e..0000000 --- a/fix-memleak-in-process_server_config_line_depth.patch +++ /dev/null @@ -1,39 +0,0 @@ -From fcc66557503124ab98491a598b706a24eb3cf0e1 Mon Sep 17 00:00:00 2001 -From: Antonio Larrosa -Date: Mon, 12 Aug 2024 11:32:42 +0200 -Subject: [PATCH] Fix a small memory leak in process_server_config_line_depth - -The return value of argv_assemble is owned by the caller and should be -free'd. When processing the sSubsystem case there are two calls to -argv_assemble but only one of them is freed. This patch fixes the small -(29 bytes according to valgrind) memory leak. - -The output from valgrind: -==115369== 29 bytes in 1 blocks are definitely lost in loss record 573 of 913 -==115369== at 0x4845794: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) -==115369== by 0x124A22: argv_assemble (misc.c:2165) -==115369== by 0x1385E5: process_server_config_line_depth.constprop.0 (servconf.c:2004) -==115369== by 0x13984D: parse_server_config_depth.constprop.0 (servconf.c:3032) -==115369== by 0x139986: parse_server_config.constprop.0 (servconf.c:3049) -==115369== by 0x111C6E: main (sshd.c:1445) - -Submitted to upstream at https://github.com/openssh/openssh-portable/pull/515 ---- - servconf.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/servconf.c b/servconf.c -index 5a20d6f8..0b989b95 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -2006,6 +2006,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, - xasprintf(&options->subsystem_args[options->num_subsystems], - "%s%s%s", arg, *arg2 == '\0' ? "" : " ", arg2); - free(arg2); -+ free(arg); - argv_consume(&ac); - options->num_subsystems++; - break; --- -2.45.2 - diff --git a/fix-missing-lz.patch b/fix-missing-lz.patch new file mode 100644 index 0000000..bc82afa --- /dev/null +++ b/fix-missing-lz.patch @@ -0,0 +1,25 @@ +Index: openssh-9.3p1/Makefile.in +=================================================================== +--- openssh-9.3p1.orig/Makefile.in ++++ openssh-9.3p1/Makefile.in +@@ -250,17 +250,17 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l + $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + + sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-sk.o sk-usbhid.o $(SFTPSERVER_OBJS) +- $(LD) -o $@ $(SFTPSERVER_OBJS) ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) ++ $(LD) -o $@ $(SFTPSERVER_OBJS) ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) -lz + + sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTP_OBJS) + $(LD) -o $@ $(SFTP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT) + + # FIPS tests + cavstest-ctr$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-sk.o sk-usbhid.o cavstest-ctr.o +- $(LD) -o $@ cavstest-ctr.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) ++ $(LD) -o $@ cavstest-ctr.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) -lz + + cavstest-kdf$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-sk.o sk-usbhid.o cavstest-kdf.o +- $(LD) -o $@ cavstest-kdf.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) ++ $(LD) -o $@ cavstest-kdf.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) -lz + + # test driver for the loginrec code - not built by default + logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o diff --git a/logind_set_tty.patch b/logind_set_tty.patch index 4e744f9..5d3e37c 100644 --- a/logind_set_tty.patch +++ b/logind_set_tty.patch @@ -14,11 +14,11 @@ index f0ea07e7b..35dcf45f1 100644 $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS) sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) -- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) $(LIBWTMPDB) -+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) $(LIBWTMPDB) $(LIBSYSTEMD) +- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) ++ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) $(LIBSYSTEMD) - sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS) - $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) + scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) + $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff --git a/configure.ac b/configure.ac index a12c6f7ad..860df3379 100644 --- a/configure.ac @@ -106,7 +106,7 @@ index 86caf83b2..8b413190b 100644 #ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN if (li->type == LTYPE_LOGIN && !sys_auth_record_login(li->username,li->hostname,li->line, -@@ -1476,6 +1486,91 @@ wtmpdb_write_entry(struct logininfo *li) +@@ -1476,6 +1486,88 @@ wtmpdb_write_entry(struct logininfo *li) } #endif @@ -171,12 +171,9 @@ index 86caf83b2..8b413190b 100644 + + free(dbus_path); + -+ if (sd_bus_flush(bus) < 0) { -+ sd_bus_unref(bus); ++ if (sd_bus_flush(bus) < 0) + return (0); -+ } + -+ sd_bus_unref(bus); + return (1); +} + diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index af7730b..42e43d1 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -104,10 +104,10 @@ Index: openssh-9.6p1/openbsd-compat/port-linux.h #endif #ifdef LINUX_OOM_ADJUST -Index: openssh-9.6p1/sshd-session.c +Index: openssh-9.6p1/sshd.c =================================================================== ---- openssh-9.6p1.orig/sshd-session.c -+++ openssh-9.6p1/sshd-session.c +--- openssh-9.6p1.orig/sshd.c ++++ openssh-9.6p1/sshd.c @@ -511,7 +511,7 @@ privsep_preauth_child(struct ssh *ssh) demote_sensitive_data(ssh); diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 1301374..f61bb4c 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -37,14 +37,14 @@ Index: openssh-9.3p2/Makefile.in =================================================================== --- openssh-9.3p2.orig/Makefile.in +++ openssh-9.3p2/Makefile.in -@@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server +@@ -24,6 +24,7 @@ SSH_PROGRAM=@bindir@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign +SSH_KEYCAT=$(libexecdir)/ssh-keycat - SSHD_SESSION=$(libexecdir)/sshd-session SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper + SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper @@ -57,6 +58,7 @@ CHANNELLIBS=@CHANNELLIBS@ K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ @@ -53,12 +53,12 @@ Index: openssh-9.3p2/Makefile.in LIBEDIT=@LIBEDIT@ LIBFIDO2=@LIBFIDO2@ LIBWTMPDB=@LIBWTMPDB@ -@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ +@@ -75,7 +77,7 @@ MKDIR_P=@MKDIR_P@ .SUFFIXES: .lo --TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) -+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) +-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) 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) TARGETS += cavstest-ctr$(EXEEXT) cavstest-kdf$(EXEEXT) @@ -99,9 +99,9 @@ Index: openssh-9.3p2/openbsd-compat/port-linux-sshd.c =================================================================== --- openssh-9.3p2.orig/openbsd-compat/port-linux-sshd.c +++ openssh-9.3p2/openbsd-compat/port-linux-sshd.c -@@ -54,6 +54,20 @@ extern Authctxt *the_authctxt; - extern Authctxt *the_authctxt; +@@ -53,6 +53,20 @@ extern Authctxt *the_authctxt; extern int inetd_flag; + extern int rexeced_flag; +/* Wrapper around is_selinux_enabled() to log its return value once only */ +int @@ -129,14 +129,14 @@ Index: openssh-9.3p2/openbsd-compat/port-linux-sshd.c { const char *reqlvl; char *role; -@@ -319,16 +333,16 @@ sshd_selinux_setup_pam_variables(void) +@@ -329,16 +343,16 @@ sshd_selinux_setup_pam_variables(void) ssh_selinux_get_role_level(&role, &reqlvl); - rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); + rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : ""); - if (inetd_flag) { + if (inetd_flag && !rexeced_flag) { use_current = "1"; } else { use_current = ""; diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 0330f72..805a0f8 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -52,7 +52,7 @@ Index: openssh-9.3p2/session.c platform_setusercontext(pw); - if (platform_privileged_uidswap()) { -+ if (platform_privileged_uidswap() && !is_child) { ++ if (platform_privileged_uidswap() && (!is_child || !use_privsep)) { #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { @@ -98,11 +98,11 @@ Index: openssh-9.3p2/session.c exit(sftp_server_main(i, argv, s->pw)); } -Index: openssh-9.3p2/sshd-session.c +Index: openssh-9.3p2/sshd.c =================================================================== ---- openssh-9.3p2.orig/sshd-session.c -+++ openssh-9.3p2/sshd-session.c -@@ -342,6 +342,10 @@ privsep_preauth_child(struct ssh *ssh) +--- openssh-9.3p2.orig/sshd.c ++++ openssh-9.3p2/sshd.c +@@ -510,6 +510,10 @@ privsep_preauth_child(struct ssh *ssh) /* Demote the private keys to public keys. */ demote_sensitive_data(ssh); @@ -113,12 +113,13 @@ Index: openssh-9.3p2/sshd-session.c /* Demote the child */ if (privsep_chroot) { /* Change our root directory */ -@@ -444,7 +448,7 @@ privsep_postauth(struct ssh *ssh, Authct - * 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 +@@ -602,6 +606,9 @@ privsep_postauth(struct ssh *ssh, Authct + #ifdef DISABLE_FD_PASSING + if (1) { ++#elif defined(WITH_SELINUX) ++ if (0) { ++ /* even root user can be confined by SELinux */ + #else + if (authctxt->pw->pw_uid == 0) { + #endif diff --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch index 04159e1..5cf0e8f 100644 --- a/openssh-7.6p1-cleanup-selinux.patch +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -9,16 +9,16 @@ Index: openssh-9.3p2/auth2-pubkey.c +extern int inetd_flag; +extern int rexeced_flag; +extern Authctxt *the_authctxt; - extern struct authmethod_cfg methodcfg_pubkey; static char * + format_key(const struct sshkey *key) @@ -459,7 +462,8 @@ match_principals_command(struct passwd * if ((pid = subprocess("AuthorizedPrincipalsCommand", command, ac, av, &f, SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, - runas_pw, temporarily_use_uid, restore_uid)) == 0) + runas_pw, temporarily_use_uid, restore_uid, -+ inetd_flag, the_authctxt)) == 0) ++ (inetd_flag && !rexeced_flag), the_authctxt)) == 0) goto out; uid_swapped = 1; @@ -28,7 +28,7 @@ Index: openssh-9.3p2/auth2-pubkey.c SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, - runas_pw, temporarily_use_uid, restore_uid)) == 0) + runas_pw, temporarily_use_uid, restore_uid, -+ inetd_flag, the_authctxt)) == 0) ++ (inetd_flag && !rexeced_flag), the_authctxt)) == 0) goto out; uid_swapped = 1; @@ -87,13 +87,14 @@ Index: openssh-9.3p2/openbsd-compat/port-linux-sshd.c =================================================================== --- openssh-9.3p2.orig/openbsd-compat/port-linux-sshd.c +++ openssh-9.3p2/openbsd-compat/port-linux-sshd.c -@@ -49,10 +49,6 @@ +@@ -49,11 +49,6 @@ #include #endif -extern ServerOptions options; -extern Authctxt *the_authctxt; -extern int inetd_flag; +-extern int rexeced_flag; - /* Wrapper around is_selinux_enabled() to log its return value once only */ int @@ -132,7 +133,7 @@ Index: openssh-9.3p2/openbsd-compat/port-linux-sshd.c if (r == 0) { /* If launched from xinetd, we must use current level */ -- if (inetd_flag) { +- if (inetd_flag && !rexeced_flag) { + if (inetd) { security_context_t sshdsc=NULL; @@ -156,7 +157,7 @@ Index: openssh-9.3p2/openbsd-compat/port-linux-sshd.c rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : ""); -- if (inetd_flag) { +- if (inetd_flag && !rexeced_flag) { + if (inetd) { use_current = "1"; } else { @@ -221,46 +222,56 @@ Index: openssh-9.3p2/platform.c =================================================================== --- openssh-9.3p2.orig/platform.c +++ openssh-9.3p2/platform.c -@@ -34,6 +34,8 @@ - #include "openbsd-compat/openbsd-compat.h" +@@ -34,6 +34,9 @@ + extern int use_privsep; extern ServerOptions options; +extern int inetd_flag; ++extern int rexeced_flag; +extern Authctxt *the_authctxt; - /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ - int -@@ -185,7 +187,9 @@ platform_setusercontext_post_groups(stru + void + platform_pre_listen(void) +@@ -185,7 +188,9 @@ platform_setusercontext_post_groups(stru } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX - sshd_selinux_setup_exec_context(pw->pw_name); + sshd_selinux_setup_exec_context(pw->pw_name, -+ inetd_flag, do_pam_putenv, the_authctxt, ++ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt, + options.use_pam); #endif } -Index: openssh-9.3p2/sshd-session.c +Index: openssh-9.3p2/sshd.c =================================================================== ---- openssh-9.3p2.orig/sshd-session.c -+++ openssh-9.3p2/sshd-session.c +--- openssh-9.3p2.orig/sshd.c ++++ openssh-9.3p2/sshd.c @@ -166,7 +166,7 @@ int debug_flag = 0; - int debug_flag = 0; + static int test_flag = 0; /* Flag indicating that the daemon is being started from inetd. */ -static int inetd_flag = 0; +int inetd_flag = 0; - /* debug goes to stderr unless inetd_flag is set */ - static int log_stderr = 0; + /* Flag indicating that sshd should not detach and become a daemon. */ + static int no_daemon_flag = 0; +@@ -179,7 +179,7 @@ static char **saved_argv; + static int saved_argc; + + /* re-exec */ +-static int rexeced_flag = 0; ++int rexeced_flag = 0; + static int rexec_flag = 1; + static int rexec_argc = 0; + static char **rexec_argv; @@ -2396,7 +2396,9 @@ main(int ac, char **av) } #endif #ifdef WITH_SELINUX - sshd_selinux_setup_exec_context(authctxt->pw->pw_name); + sshd_selinux_setup_exec_context(authctxt->pw->pw_name, -+ inetd_flag, do_pam_putenv, the_authctxt, ++ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt, + options.use_pam); #endif #ifdef USE_PAM diff --git a/openssh-7.7p1-cavstest-ctr.patch b/openssh-7.7p1-cavstest-ctr.patch index 0498b75..17b6672 100644 --- a/openssh-7.7p1-cavstest-ctr.patch +++ b/openssh-7.7p1-cavstest-ctr.patch @@ -7,7 +7,7 @@ Index: openssh-8.8p1/Makefile.in --- openssh-8.8p1.orig/Makefile.in +++ openssh-8.8p1/Makefile.in @@ -26,6 +26,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server - SSHD_SESSION=$(libexecdir)/sshd-session + SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper +CAVSTEST_CTR=$(libexecdir)/cavstest-ctr @@ -16,7 +16,7 @@ Index: openssh-8.8p1/Makefile.in STRIP_OPT=@STRIP_OPT@ @@ -69,6 +70,8 @@ MKDIR_P=@MKDIR_P@ - TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) + TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) +TARGETS += cavstest-ctr$(EXEEXT) + @@ -29,7 +29,7 @@ Index: openssh-8.8p1/Makefile.in +# FIPS tests +cavstest-ctr$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-sk.o sk-usbhid.o cavstest-ctr.o -+ $(LD) -o $@ cavstest-ctr.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) -lz ++ $(LD) -o $@ cavstest-ctr.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) + # test driver for the loginrec code - not built by default logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o diff --git a/openssh-7.7p1-cavstest-kdf.patch b/openssh-7.7p1-cavstest-kdf.patch index 864be49..bc5763e 100644 --- a/openssh-7.7p1-cavstest-kdf.patch +++ b/openssh-7.7p1-cavstest-kdf.patch @@ -16,7 +16,7 @@ Index: openssh-8.8p1/Makefile.in STRIP_OPT=@STRIP_OPT@ @@ -70,7 +71,7 @@ MKDIR_P=@MKDIR_P@ - TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) + TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) -TARGETS += cavstest-ctr$(EXEEXT) +TARGETS += cavstest-ctr$(EXEEXT) cavstest-kdf$(EXEEXT) @@ -25,10 +25,10 @@ Index: openssh-8.8p1/Makefile.in ssh-xmss.o \ @@ -252,6 +253,9 @@ sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(S cavstest-ctr$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-sk.o sk-usbhid.o cavstest-ctr.o - $(LD) -o $@ cavstest-ctr.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) -lz + $(LD) -o $@ cavstest-ctr.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) +cavstest-kdf$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-sk.o sk-usbhid.o cavstest-kdf.o -+ $(LD) -o $@ cavstest-kdf.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) -lz ++ $(LD) -o $@ cavstest-kdf.o ssh-sk.o sk-usbhid.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(LIBFIDO2) + # test driver for the loginrec code - not built by default logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 5a75ca7..08b9d30 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -389,17 +389,17 @@ Index: openssh-9.6p1/hmac.c ssh_hmac_update(ctx, m, mlen) < 0 || Index: openssh-9.6p1/kex.c =================================================================== ---- openssh-9.6p1.orig/kex-names.c -+++ openssh-9.6p1/kex-names.c +--- openssh-9.6p1.orig/kex.c ++++ openssh-9.6p1/kex.c @@ -64,6 +64,8 @@ - #include "ssherr.h" + #include "digest.h" #include "xmalloc.h" +#include "fips.h" + - struct kexalg { - char *name; - u_int type; + /* prototype */ + static int kex_choose_conf(struct ssh *, uint32_t seq); + static int kex_input_newkeys(int, u_int32_t, struct ssh *); @@ -87,7 +89,7 @@ struct kexalg { int ec_nid; int hash_alg; @@ -647,8 +647,8 @@ Index: openssh-9.6p1/servconf.c #include "digest.h" +#include "fips.h" - #if !defined(SSHD_PAM_SERVICE) - # define SSHD_PAM_SERVICE "sshd" + static void add_listen_addr(ServerOptions *, const char *, + const char *, int); @@ -207,6 +208,23 @@ option_clear_or_none(const char *o) return o == NULL || strcasecmp(o, "none") == 0; } @@ -785,8 +785,8 @@ Index: openssh-9.6p1/sshd.c --- openssh-9.6p1.orig/sshd.c +++ openssh-9.6p1/sshd.c @@ -128,6 +128,8 @@ - #include "addr.h" #include "srclimit.h" + #include "dh.h" +#include "fips.h" + diff --git a/openssh-7.7p1-fips_checks.patch b/openssh-7.7p1-fips_checks.patch index 921c1bf..ebbf1ab 100644 --- a/openssh-7.7p1-fips_checks.patch +++ b/openssh-7.7p1-fips_checks.patch @@ -459,13 +459,13 @@ Index: openssh-8.8p1/sshd.c --- openssh-8.8p1.orig/sshd.c +++ openssh-8.8p1/sshd.c @@ -1547,6 +1547,10 @@ main(int ac, char **av) - struct connection_info connection_info; + struct connection_info *connection_info = NULL; sigset_t sigmask; + /* initialize fips - can go before ssh_malloc_init(), since that is a + * OpenBSD-only thing (as of OpenSSH 7.6p1) */ + fips_ssh_init(); + - memset(&connection_info, 0, sizeof(connection_info)); #ifdef HAVE_SECUREWARE (void)set_auth_parameters(ac, av); + #endif diff --git a/openssh-7.7p1-ldap.patch b/openssh-7.7p1-ldap.patch index 3df2a64..cfa9249 100644 --- a/openssh-7.7p1-ldap.patch +++ b/openssh-7.7p1-ldap.patch @@ -128,7 +128,7 @@ Index: openssh-8.9p1/Makefile.in --- openssh-8.9p1.orig/Makefile.in +++ openssh-8.9p1/Makefile.in @@ -27,6 +27,8 @@ SFTP_SERVER=$(libexecdir)/sftp-server - SSHD_SESSION=$(libexecdir)/sshd-session + SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper +SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper @@ -168,7 +168,7 @@ Index: openssh-8.9p1/Makefile.in $(LD) -o $@ $(SFTPSERVER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -421,6 +429,10 @@ install-files: - $(INSTALL) -m 0755 $(STRIP_OPT) sshd-session$(EXEEXT) $(DESTDIR)$(SSHD_SESSION)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) $(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) + if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ diff --git a/openssh-7.7p1-pam_check_locks.patch b/openssh-7.7p1-pam_check_locks.patch index 42c847d..4186015 100644 --- a/openssh-7.7p1-pam_check_locks.patch +++ b/openssh-7.7p1-pam_check_locks.patch @@ -32,17 +32,17 @@ Index: openssh-8.8p1/servconf.c --- openssh-8.8p1.orig/servconf.c +++ openssh-8.8p1/servconf.c @@ -92,6 +92,7 @@ initialize_server_options(ServerOptions + /* Portable-specific options */ options->use_pam = -1; - options->pam_service_name = NULL; + options->use_pam_check_locks = -1; /* Standard Options */ options->num_ports = 0; @@ -278,6 +279,8 @@ fill_default_server_options(ServerOption + /* Portable-specific options */ + if (options->use_pam == -1) options->use_pam = 0; - if (options->pam_service_name == NULL) - options->pam_service_name = xstrdup(SSHD_PAM_SERVICE); + if (options->use_pam_check_locks == -1) + options->use_pam_check_locks = 0; @@ -52,27 +52,26 @@ Index: openssh-8.8p1/servconf.c typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ -- sUsePAM, sPAMServiceName, -+ sUsePAM, sPAMServiceName, sUsePAMChecklocks, +- sUsePAM, ++ sUsePAM, sUsePAMChecklocks, /* Standard Options */ sPort, sHostKeyFile, sLoginGraceTime, sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, -@@ -535,9 +538,11 @@ static struct { +@@ -535,8 +538,10 @@ static struct { + /* Portable-specific options */ #ifdef USE_PAM { "usepam", sUsePAM, SSHCFG_GLOBAL }, - { "pamservicename", sPAMServiceName, SSHCFG_ALL }, + { "usepamchecklocks", sUsePAMChecklocks, SSHCFG_GLOBAL }, #else { "usepam", sUnsupported, SSHCFG_GLOBAL }, - { "pamservicename", sUnsupported, SSHCFG_ALL }, + { "usepamchecklocks", sUnsupported, SSHCFG_GLOBAL }, #endif { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, /* Standard Options */ @@ -1331,6 +1336,9 @@ process_server_config_line_depth(ServerO - if (*activep && *charptr == NULL) - *charptr = xstrdup(arg); - break; + case sUsePAM: + intptr = &options->use_pam; + goto parse_flag; + case sUsePAMChecklocks: + intptr = &options->use_pam_check_locks; + goto parse_flag; @@ -84,9 +83,9 @@ Index: openssh-8.8p1/servconf.h --- openssh-8.8p1.orig/servconf.h +++ openssh-8.8p1/servconf.h @@ -200,6 +200,7 @@ typedef struct { + char *adm_forced_command; int use_pam; /* Enable auth via PAM */ - char *pam_service_name; + int use_pam_check_locks; /* internally check for locked accounts even when using PAM */ int permit_tun; diff --git a/openssh-7.7p1-systemd-notify.patch b/openssh-7.7p1-systemd-notify.patch index bb69a3b..ae55aae 100644 --- a/openssh-7.7p1-systemd-notify.patch +++ b/openssh-7.7p1-systemd-notify.patch @@ -61,7 +61,7 @@ Index: openssh-8.8p1/sshd.c + #include "xmalloc.h" #include "ssh.h" - #include "sshpty.h" + #include "ssh2.h" @@ -308,6 +312,10 @@ sighup_handler(int sig) static void sighup_restart(void) @@ -84,4 +84,4 @@ Index: openssh-8.8p1/sshd.c + /* Accept a connection and return in a forked child */ server_accept_loop(&sock_in, &sock_out, - &newsock, config_s, log_stderr); + &newsock, config_s); diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index a07128e..a73ca13 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -1,7 +1,8 @@ -diff -up openssh/auth2.c.role-mls openssh/auth2.c ---- openssh/auth2.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth2.c 2018-08-22 11:14:56.815430916 +0200 -@@ -256,6 +256,9 @@ input_userauth_request(int type, u_int32 +Index: openssh-9.6p1/auth2.c +=================================================================== +--- openssh-9.6p1.orig/auth2.c ++++ openssh-9.6p1/auth2.c +@@ -273,6 +273,9 @@ input_userauth_request(int type, u_int32 Authctxt *authctxt = ssh->authctxt; Authmethod *m = NULL; char *user = NULL, *service = NULL, *method = NULL, *style = NULL; @@ -11,7 +12,7 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c int r, authenticated = 0; double tstart = monotime_double(); -@@ -268,6 +271,11 @@ input_userauth_request(int type, u_int32 +@@ -286,6 +289,11 @@ input_userauth_request(int type, u_int32 debug("userauth-request for user %s service %s method %s", user, service, method); debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); @@ -23,32 +24,36 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c if ((style = strchr(user, ':')) != NULL) *style++ = 0; -@@ -314,7 +314,13 @@ input_userauth_request(int type, u_int32 - setproctitle("%s [net]", authctxt->valid ? user : "unknown"); +@@ -313,8 +321,15 @@ input_userauth_request(int type, u_int32 + use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; +- if (use_privsep) +#ifdef WITH_SELINUX + authctxt->role = role ? xstrdup(role) : NULL; +#endif - mm_inform_authserv(service, style); ++ if (use_privsep) { + mm_inform_authserv(service, style); +#ifdef WITH_SELINUX -+ mm_inform_authrole(role); ++ mm_inform_authrole(role); +#endif ++ } userauth_banner(ssh); if ((r = kex_server_update_ext_info(ssh)) != 0) fatal_fr(r, "kex_server_update_ext_info failed"); -diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c ---- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200 -@@ -281,6 +281,7 @@ input_gssapi_mic(int type, u_int32_t ple +Index: openssh-9.6p1/auth2-gss.c +=================================================================== +--- openssh-9.6p1.orig/auth2-gss.c ++++ openssh-9.6p1/auth2-gss.c +@@ -331,6 +331,7 @@ input_gssapi_mic(int type, u_int32_t ple Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; int r, authenticated = 0; + char *micuser; struct sshbuf *b; gss_buffer_desc mic, gssbuf; - u_char *p; -@@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple + const char *displayname; +@@ -348,7 +349,13 @@ input_gssapi_mic(int type, u_int32_t ple fatal_f("sshbuf_new failed"); mic.value = p; mic.length = len; @@ -63,7 +68,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c "gssapi-with-mic", ssh->kex->session_id); if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -@@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -362,6 +369,8 @@ input_gssapi_mic(int type, u_int32_t ple logit("GSSAPI MIC check failed"); sshbuf_free(b); @@ -71,11 +76,12 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c + free(micuser); free(mic.value); - authctxt->postponed = 0; -diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c ---- openssh/auth2-hostbased.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth2-hostbased.c 2018-08-22 11:14:56.816430924 +0200 -@@ -123,7 +123,16 @@ userauth_hostbased(struct ssh *ssh) + if ((!use_privsep || mm_is_monitor()) && +Index: openssh-9.6p1/auth2-hostbased.c +=================================================================== +--- openssh-9.6p1.orig/auth2-hostbased.c ++++ openssh-9.6p1/auth2-hostbased.c +@@ -128,7 +128,16 @@ userauth_hostbased(struct ssh *ssh, cons /* reconstruct packet */ if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || @@ -92,10 +98,11 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || (r = sshbuf_put_cstring(b, method)) != 0 || (r = sshbuf_put_string(b, pkalg, alen)) != 0 || -diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.role-mls 2018-08-22 11:14:56.816430924 +0200 -+++ openssh/auth2-pubkey.c 2018-08-22 11:17:07.331483958 +0200 -@@ -169,9 +169,16 @@ userauth_pubkey(struct ssh *ssh) +Index: openssh-9.6p1/auth2-pubkey.c +=================================================================== +--- openssh-9.6p1.orig/auth2-pubkey.c ++++ openssh-9.6p1/auth2-pubkey.c +@@ -200,9 +200,16 @@ userauth_pubkey(struct ssh *ssh, const c goto done; } /* reconstruct packet */ @@ -114,9 +121,10 @@ diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, userstyle)) != 0 || (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || -diff -up openssh/auth.h.role-mls openssh/auth.h ---- openssh/auth.h.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth.h 2018-08-22 11:14:56.816430924 +0200 +Index: openssh-9.6p1/auth.h +=================================================================== +--- openssh-9.6p1.orig/auth.h ++++ openssh-9.6p1/auth.h @@ -65,6 +65,9 @@ struct Authctxt { char *service; struct passwd *pw; /* set if 'valid' */ @@ -127,10 +135,11 @@ diff -up openssh/auth.h.role-mls openssh/auth.h /* Method lists for multiple authentication */ char **auth_methods; /* modified from server config */ -diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c ---- openssh/auth-pam.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth-pam.c 2018-08-22 11:14:56.816430924 +0200 -@@ -1172,7 +1172,7 @@ is_pam_session_open(void) +Index: openssh-9.6p1/auth-pam.c +=================================================================== +--- openssh-9.6p1.orig/auth-pam.c ++++ openssh-9.6p1/auth-pam.c +@@ -1242,7 +1242,7 @@ is_pam_session_open(void) * during the ssh authentication process. */ int @@ -139,22 +148,24 @@ diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c { int ret = 1; char *compound; -diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h ---- openssh/auth-pam.h.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/auth-pam.h 2018-08-22 11:14:56.817430932 +0200 +Index: openssh-9.6p1/auth-pam.h +=================================================================== +--- openssh-9.6p1.orig/auth-pam.h ++++ openssh-9.6p1/auth-pam.h @@ -33,7 +33,7 @@ u_int do_pam_account(void); void do_pam_session(struct ssh *); - void do_pam_setcred(void); + void do_pam_setcred(int ); void do_pam_chauthtok(void); -int do_pam_putenv(char *, char *); +int do_pam_putenv(char *, const char *); char ** fetch_pam_environment(void); char ** fetch_pam_child_environment(void); void free_pam_environment(char **); -diff -up openssh/misc.c.role-mls openssh/misc.c ---- openssh/misc.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/misc.c 2018-08-22 11:14:56.817430932 +0200 -@@ -542,6 +542,7 @@ char * +Index: openssh-9.6p1/misc.c +=================================================================== +--- openssh-9.6p1.orig/misc.c ++++ openssh-9.6p1/misc.c +@@ -771,6 +771,7 @@ char * colon(char *cp) { int flag = 0; @@ -162,7 +173,7 @@ diff -up openssh/misc.c.role-mls openssh/misc.c if (*cp == ':') /* Leading colon is part of file name. */ return NULL; -@@ -557,6 +558,13 @@ colon(char *cp) +@@ -786,6 +787,13 @@ colon(char *cp) return (cp); if (*cp == '/') return NULL; @@ -176,10 +187,11 @@ diff -up openssh/misc.c.role-mls openssh/misc.c } return NULL; } -diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c ---- openssh-8.6p1/monitor.c.role-mls 2021-04-16 05:55:25.000000000 +0200 -+++ openssh-8.6p1/monitor.c 2021-05-21 14:21:56.719414087 +0200 -@@ -117,6 +117,9 @@ int mm_answer_sign(struct ssh *, int, st +Index: openssh-9.6p1/monitor.c +=================================================================== +--- openssh-9.6p1.orig/monitor.c ++++ openssh-9.6p1/monitor.c +@@ -120,6 +120,9 @@ int mm_answer_sign(struct ssh *, int, st int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); int mm_answer_authserv(struct ssh *, int, struct sshbuf *); @@ -189,7 +201,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c 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 *); -@@ -195,6 +198,9 @@ struct mon_table mon_dispatch_proto20[] +@@ -200,6 +203,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}, @@ -199,7 +211,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -803,6 +809,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in +@@ -834,6 +840,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -209,7 +221,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM -@@ -877,6 +886,26 @@ key_base_type_match(const char *method, +@@ -908,6 +917,26 @@ key_base_type_match(const char *method, return found; } @@ -236,16 +248,16 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c int mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { -@@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh, +@@ -1280,7 +1309,7 @@ monitor_valid_userblob(struct ssh *ssh, struct sshbuf *b; - struct sshkey *hostkey = NULL; + struct sshkey *hostkey = NULL; const u_char *p; - char *userstyle, *cp; + char *userstyle, *s, *cp; size_t len; u_char type; int hostbound = 0, r, fail = 0; -@@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh, +@@ -1311,6 +1340,8 @@ monitor_valid_userblob(struct ssh *ssh, fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse userstyle"); @@ -254,7 +266,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char +@@ -1361,7 +1392,7 @@ monitor_valid_hostbasedblob(const u_char { struct sshbuf *b; const u_char *p; @@ -263,7 +275,7 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c size_t len; int r, fail = 0; u_char type; -@@ -1338,6 +1370,8 @@ monitor_valid_hostbasedblob(const u_char +@@ -1382,6 +1413,8 @@ monitor_valid_hostbasedblob(const u_char fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal_fr(r, "parse userstyle"); @@ -272,9 +284,10 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -diff -up openssh/monitor.h.role-mls openssh/monitor.h ---- openssh/monitor.h.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/monitor.h 2018-08-22 11:14:56.818430941 +0200 +Index: openssh-9.6p1/monitor.h +=================================================================== +--- openssh-9.6p1.orig/monitor.h ++++ openssh-9.6p1/monitor.h @@ -55,6 +55,10 @@ enum monitor_reqtype { MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, @@ -286,10 +299,11 @@ diff -up openssh/monitor.h.role-mls openssh/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, -diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.role-mls 2018-08-22 11:14:56.818430941 +0200 -+++ openssh/monitor_wrap.c 2018-08-22 11:21:47.938747968 +0200 -@@ -390,6 +390,27 @@ mm_inform_authserv(char *service, char * +Index: openssh-9.6p1/monitor_wrap.c +=================================================================== +--- openssh-9.6p1.orig/monitor_wrap.c ++++ openssh-9.6p1/monitor_wrap.c +@@ -396,6 +396,27 @@ mm_inform_authserv(char *service, char * sshbuf_free(m); } @@ -317,10 +331,11 @@ diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c /* Do the password authentication */ int mm_auth_password(struct ssh *ssh, char *password) -diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.role-mls 2018-08-22 11:14:56.818430941 +0200 -+++ openssh/monitor_wrap.h 2018-08-22 11:22:10.439929513 +0200 -@@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int); +Index: openssh-9.6p1/monitor_wrap.h +=================================================================== +--- openssh-9.6p1.orig/monitor_wrap.h ++++ openssh-9.6p1/monitor_wrap.h +@@ -49,6 +49,9 @@ int mm_sshkey_sign(struct ssh *, struct const u_char *, size_t, const char *, const char *, const char *, u_int compat); void mm_inform_authserv(char *, char *); @@ -330,10 +345,11 @@ diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h struct passwd *mm_getpwnamallow(struct ssh *, const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); -diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in ---- openssh/openbsd-compat/Makefile.in.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/openbsd-compat/Makefile.in 2018-08-22 11:14:56.819430949 +0200 -@@ -92,7 +92,8 @@ PORTS= port-aix.o \ +Index: openssh-9.6p1/openbsd-compat/Makefile.in +=================================================================== +--- openssh-9.6p1.orig/openbsd-compat/Makefile.in ++++ openssh-9.6p1/openbsd-compat/Makefile.in +@@ -100,7 +100,8 @@ PORTS= port-aix.o \ port-prngd.o \ port-solaris.o \ port-net.o \ @@ -343,10 +359,11 @@ diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Make .c.o: $(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< -diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/port-linux.c ---- openssh/openbsd-compat/port-linux.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/openbsd-compat/port-linux.c 2018-08-22 11:14:56.819430949 +0200 -@@ -100,37 +100,6 @@ ssh_selinux_getctxbyname(char *pwname) +Index: openssh-9.6p1/openbsd-compat/port-linux.c +=================================================================== +--- openssh-9.6p1.orig/openbsd-compat/port-linux.c ++++ openssh-9.6p1/openbsd-compat/port-linux.c +@@ -101,37 +101,6 @@ ssh_selinux_getctxbyname(char *pwname) return sc; } @@ -384,7 +401,7 @@ diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/por /* Set the TTY context for the specified user */ void ssh_selinux_setup_pty(char *pwname, const char *tty) -@@ -145,7 +114,11 @@ ssh_selinux_setup_pty(char *pwname, cons +@@ -144,7 +113,11 @@ ssh_selinux_setup_pty(char *pwname, cons debug3("%s: setting TTY context on %s", __func__, tty); @@ -397,9 +414,10 @@ diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/por /* XXX: should these calls fatal() upon failure in enforcing mode? */ -diff -up openssh/openbsd-compat/port-linux.h.role-mls openssh/openbsd-compat/port-linux.h ---- openssh/openbsd-compat/port-linux.h.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/openbsd-compat/port-linux.h 2018-08-22 11:14:56.819430949 +0200 +Index: openssh-9.6p1/openbsd-compat/port-linux.h +=================================================================== +--- openssh-9.6p1.orig/openbsd-compat/port-linux.h ++++ openssh-9.6p1/openbsd-compat/port-linux.h @@ -20,9 +20,10 @@ #ifdef WITH_SELINUX int ssh_selinux_enabled(void); @@ -412,10 +430,11 @@ diff -up openssh/openbsd-compat/port-linux.h.role-mls openssh/openbsd-compat/por #endif #ifdef LINUX_OOM_ADJUST -diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compat/port-linux-sshd.c ---- openssh/openbsd-compat/port-linux-sshd.c.role-mls 2018-08-22 11:14:56.819430949 +0200 -+++ openssh/openbsd-compat/port-linux-sshd.c 2018-08-22 11:14:56.819430949 +0200 -@@ -0,0 +1,420 @@ +Index: openssh-9.6p1/openbsd-compat/port-linux-sshd.c +=================================================================== +--- /dev/null ++++ openssh-9.6p1/openbsd-compat/port-linux-sshd.c +@@ -0,0 +1,421 @@ +/* + * Copyright (c) 2005 Daniel Walsh + * Copyright (c) 2014 Petr Lautrbach @@ -469,6 +488,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa +extern ServerOptions options; +extern Authctxt *the_authctxt; +extern int inetd_flag; ++extern int rexeced_flag; + +/* Send audit message */ +static int @@ -674,7 +694,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + + if (r == 0) { + /* If launched from xinetd, we must use current level */ -+ if (inetd_flag) { ++ if (inetd_flag && !rexeced_flag) { + security_context_t sshdsc=NULL; + + if (getcon_raw(&sshdsc) < 0) @@ -748,7 +768,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + + rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); + -+ if (inetd_flag) { ++ if (inetd_flag && !rexeced_flag) { + use_current = "1"; + } else { + use_current = ""; @@ -836,10 +856,11 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa +#endif +#endif + -diff -up openssh/platform.c.role-mls openssh/platform.c ---- openssh/platform.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/platform.c 2018-08-22 11:14:56.819430949 +0200 -@@ -183,7 +183,7 @@ platform_setusercontext_post_groups(stru +Index: openssh-9.6p1/platform.c +=================================================================== +--- openssh-9.6p1.orig/platform.c ++++ openssh-9.6p1/platform.c +@@ -185,7 +185,7 @@ platform_setusercontext_post_groups(stru } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX @@ -848,10 +869,11 @@ diff -up openssh/platform.c.role-mls openssh/platform.c #endif } -diff -up openssh/sshd.c.role-mls openssh/sshd.c ---- openssh/sshd-session.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/sshd-session.c 2018-08-22 11:14:56.820430957 +0200 -@@ -2186,6 +2186,9 @@ main(int ac, char **av) +Index: openssh-9.6p1/sshd.c +=================================================================== +--- openssh-9.6p1.orig/sshd.c ++++ openssh-9.6p1/sshd.c +@@ -2387,6 +2387,9 @@ main(int ac, char **av) restore_uid(); } #endif @@ -860,4 +882,4 @@ diff -up openssh/sshd.c.role-mls openssh/sshd.c +#endif #ifdef USE_PAM if (options.use_pam) { - do_pam_setcred(); + do_pam_setcred(1); diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 5bce9b5..2f949b1 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -1,37 +1,29 @@ -diff --git a/Makefile.in b/Makefile.in -index e7549470..b68c1710 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -109,6 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ +Index: openssh-9.6p1/Makefile.in +=================================================================== +--- openssh-9.6p1.orig/Makefile.in ++++ openssh-9.6p1/Makefile.in +@@ -114,6 +114,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ sshbuf-io.o -@@ -125,7 +126,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ - auth2-chall.o groupaccess.o \ +@@ -132,7 +133,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ -- monitor.o monitor_wrap.o auth-krb5.o \ -+ monitor.o monitor_wrap.o auth-krb5.o kexgsss.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o \ + monitor.o monitor_wrap.o auth-krb5.o \ +- auth2-gss.o gss-serv.o gss-serv-krb5.o \ ++ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ - sftp-server.o sftp-common.o \ -@@ -523,7 +523,7 @@ regress-prep: - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile - - REGRESSLIBS=libssh.a $(LIBCOMPAT) --TESTLIBS=$(LIBS) $(CHANNELLIBS) -+TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS) - - regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ -diff -up a/auth.c.gsskex b/auth.c ---- a/auth.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/auth.c 2021-08-27 12:41:51.262788953 +0200 -@@ -402,7 +402,8 @@ auth_root_allowed(struct ssh *ssh, const + srclimit.o sftp-server.o sftp-common.o \ + sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ +Index: openssh-9.6p1/auth.c +=================================================================== +--- openssh-9.6p1.orig/auth.c ++++ openssh-9.6p1/auth.c +@@ -357,7 +357,8 @@ auth_root_allowed(struct ssh *ssh, const case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -41,15 +33,121 @@ diff -up a/auth.c.gsskex b/auth.c return 1; break; case PERMIT_FORCED_ONLY: -diff --git a/auth2-gss.c b/auth2-gss.c -index 9351e042..d6446c0c 100644 ---- a/auth2-gss.c -+++ b/auth2-gss.c -@@ -54,6 +54,48 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); - static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); +@@ -638,97 +639,6 @@ fakepw(void) + } + + /* +- * Returns the remote DNS hostname as a string. The returned string must not +- * be freed. NB. this will usually trigger a DNS query the first time it is +- * called. +- * This function does additional checks on the hostname to mitigate some +- * attacks on based on conflation of hostnames and IP addresses. +- */ +- +-static char * +-remote_hostname(struct ssh *ssh) +-{ +- struct sockaddr_storage from; +- socklen_t fromlen; +- struct addrinfo hints, *ai, *aitop; +- char name[NI_MAXHOST], ntop2[NI_MAXHOST]; +- const char *ntop = ssh_remote_ipaddr(ssh); +- +- /* Get IP address of client. */ +- fromlen = sizeof(from); +- memset(&from, 0, sizeof(from)); +- if (getpeername(ssh_packet_get_connection_in(ssh), +- (struct sockaddr *)&from, &fromlen) == -1) { +- debug("getpeername failed: %.100s", strerror(errno)); +- return xstrdup(ntop); +- } +- +- ipv64_normalise_mapped(&from, &fromlen); +- if (from.ss_family == AF_INET6) +- fromlen = sizeof(struct sockaddr_in6); +- +- debug3("Trying to reverse map address %.100s.", ntop); +- /* Map the IP address to a host name. */ +- if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), +- NULL, 0, NI_NAMEREQD) != 0) { +- /* Host name not found. Use ip address. */ +- return xstrdup(ntop); +- } +- +- /* +- * if reverse lookup result looks like a numeric hostname, +- * someone is trying to trick us by PTR record like following: +- * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 +- */ +- memset(&hints, 0, sizeof(hints)); +- hints.ai_socktype = SOCK_DGRAM; /*dummy*/ +- hints.ai_flags = AI_NUMERICHOST; +- if (getaddrinfo(name, NULL, &hints, &ai) == 0) { +- logit("Nasty PTR record \"%s\" is set up for %s, ignoring", +- name, ntop); +- freeaddrinfo(ai); +- return xstrdup(ntop); +- } +- +- /* Names are stored in lowercase. */ +- lowercase(name); +- +- /* +- * Map it back to an IP address and check that the given +- * address actually is an address of this host. This is +- * necessary because anyone with access to a name server can +- * define arbitrary names for an IP address. Mapping from +- * name to IP address can be trusted better (but can still be +- * fooled if the intruder has access to the name server of +- * the domain). +- */ +- memset(&hints, 0, sizeof(hints)); +- hints.ai_family = from.ss_family; +- hints.ai_socktype = SOCK_STREAM; +- if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { +- logit("reverse mapping checking getaddrinfo for %.700s " +- "[%s] failed.", name, ntop); +- return xstrdup(ntop); +- } +- /* Look for the address from the list of addresses. */ +- for (ai = aitop; ai; ai = ai->ai_next) { +- if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, +- sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && +- (strcmp(ntop, ntop2) == 0)) +- break; +- } +- freeaddrinfo(aitop); +- /* If we reached the end of the list, the address was not there. */ +- if (ai == NULL) { +- /* Address not found for the host name. */ +- logit("Address %.100s maps to %.600s, but this does not " +- "map back to the address.", ntop, name); +- return xstrdup(ntop); +- } +- return xstrdup(name); +-} +- +-/* + * Return the canonical name of the host in the other side of the current + * connection. The host name is cached, so it is efficient to call this + * several times. +Index: openssh-9.6p1/auth2-gss.c +=================================================================== +--- openssh-9.6p1.orig/auth2-gss.c ++++ openssh-9.6p1/auth2-gss.c +@@ -1,7 +1,7 @@ + /* $OpenBSD: auth2-gss.c,v 1.34 2023/03/31 04:22:27 djm Exp $ */ + + /* +- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. ++ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -58,6 +58,48 @@ static int input_gssapi_exchange_complet static int input_gssapi_errtok(int, u_int32_t, struct ssh *); -+/* + /* + * The 'gssapi_keyex' userauth mechanism. + */ +static int @@ -64,10 +162,10 @@ index 9351e042..d6446c0c 100644 + + if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) -+ fatal_fr(r, "parsing"); ++ fatal("%s: %s", __func__, ssh_err(r)); + + if ((b = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + + mic.value = p; + mic.length = len; @@ -76,14 +174,14 @@ index 9351e042..d6446c0c 100644 + "gssapi-keyex", ssh->kex->session_id); + + if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -+ fatal_f("sshbuf_mutable_ptr failed"); ++ fatal("%s: sshbuf_mutable_ptr failed", __func__); + gssbuf.length = sshbuf_len(b); + + /* gss_kex_context is NULL with privsep, so we can't check it here */ -+ if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gss_kex_context, -+ &gssbuf, &mic))) -+ authenticated = mm_ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 1); ++ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, ++ &gssbuf, &mic)))) ++ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, ++ authctxt->pw, 1)); + + sshbuf_free(b); + free(mic.value); @@ -91,50 +189,49 @@ index 9351e042..d6446c0c 100644 + return (authenticated); +} + - /* ++/* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -260,7 +302,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) + */ +@@ -267,7 +309,8 @@ input_gssapi_exchange_complete(int type, if ((r = sshpkt_get_end(ssh)) != 0) fatal_fr(r, "parse packet"); -- authenticated = mm_ssh_gssapi_userok(authctxt->user); -+ authenticated = mm_ssh_gssapi_userok(authctxt->user, authctxt->pw, 1); +- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); ++ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, ++ authctxt->pw, 1)); - authctxt->postponed = 0; - ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -306,7 +349,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) + if ((!use_privsep || mm_is_monitor()) && + (displayname = ssh_gssapi_displayname()) != NULL) +@@ -313,7 +356,8 @@ input_gssapi_mic(int type, u_int32_t ple gssbuf.length = sshbuf_len(b); - if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))) -- authenticated = mm_ssh_gssapi_userok(authctxt->user); -+ authenticated = mm_ssh_gssapi_userok(authctxt->user, authctxt->pw, 0); + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) +- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); ++ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, ++ authctxt->pw, 0)); else logit("GSSAPI MIC check failed"); -@@ -326,6 +370,17 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -333,6 +377,13 @@ input_gssapi_mic(int type, u_int32_t ple return 0; } -+struct authmethod_cfg methodcfg_gsskeyex = { ++Authmethod method_gsskeyex = { + "gssapi-keyex", -+ NULL, ++ "NULL", ++ userauth_gsskeyex, + &options.gss_authentication +}; -+ -+Authmethod method_gsskeyex = { -+ &methodcfg_gsskeyex, -+ userauth_gsskeyex, -+}; + Authmethod method_gssapi = { - &methodcfg_gssapi, - userauth_gssapi, -diff --git a/auth2.c b/auth2.c -index 0e776224..1c217268 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -73,6 +73,7 @@ extern Authmethod method_passwd; + "gssapi-with-mic", + NULL, +Index: openssh-9.6p1/auth2.c +=================================================================== +--- openssh-9.6p1.orig/auth2.c ++++ openssh-9.6p1/auth2.c +@@ -71,6 +71,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI @@ -142,7 +239,7 @@ index 0e776224..1c217268 100644 extern Authmethod method_gssapi; #endif -@@ -80,6 +81,7 @@ Authmethod *authmethods[] = { +@@ -78,6 +79,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI @@ -150,10 +247,10 @@ index 0e776224..1c217268 100644 &method_gssapi, #endif &method_passwd, -diff --git a/canohost.c b/canohost.c -index abea9c6e..8e81b519 100644 ---- a/canohost.c -+++ b/canohost.c +Index: openssh-9.6p1/canohost.c +=================================================================== +--- openssh-9.6p1.orig/canohost.c ++++ openssh-9.6p1/canohost.c @@ -35,6 +35,99 @@ #include "canohost.h" #include "misc.h" @@ -254,10 +351,10 @@ index abea9c6e..8e81b519 100644 void ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) { -diff --git a/canohost.h b/canohost.h -index 26d62855..0cadc9f1 100644 ---- a/canohost.h -+++ b/canohost.h +Index: openssh-9.6p1/canohost.h +=================================================================== +--- openssh-9.6p1.orig/canohost.h ++++ openssh-9.6p1/canohost.h @@ -15,6 +15,9 @@ #ifndef _CANOHOST_H #define _CANOHOST_H @@ -268,41 +365,41 @@ index 26d62855..0cadc9f1 100644 char *get_peer_ipaddr(int); int get_peer_port(int); char *get_local_ipaddr(int); -diff --git a/clientloop.c b/clientloop.c -index ebd0dbca..1bdac6a4 100644 ---- a/clientloop.c -+++ b/clientloop.c -@@ -112,6 +112,10 @@ - #include "ssherr.h" - #include "hostfile.h" +Index: openssh-9.6p1/clientloop.c +=================================================================== +--- openssh-9.6p1.orig/clientloop.c ++++ openssh-9.6p1/clientloop.c +@@ -121,6 +121,10 @@ + /* Uncertainty (in percent) of keystroke timing intervals */ + #define SSH_KEYSTROKE_TIMING_FUZZ 10 +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + - /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ - #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" + /* import options */ + extern Options options; -@@ -1379,6 +1383,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, +@@ -1594,6 +1598,14 @@ client_loop(struct ssh *ssh, int have_pt /* Do channel operations. */ channel_after_poll(ssh, pfd, npfd_active); +#ifdef GSSAPI -+ if (options.gss_renewal_rekey && -+ ssh_gssapi_credentials_updated(NULL)) { -+ debug("credentials updated - forcing rekey"); -+ need_rekeying = 1; -+ } ++ if (options.gss_renewal_rekey && ++ ssh_gssapi_credentials_updated(NULL)) { ++ debug("credentials updated - forcing rekey"); ++ need_rekeying = 1; ++ } +#endif + /* Buffer input from the connection. */ if (conn_in_ready) client_process_net_input(ssh); -diff --git a/configure.ac b/configure.ac -index b689db4b..efafb6bd 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -674,6 +674,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +Index: openssh-9.6p1/configure.ac +=================================================================== +--- openssh-9.6p1.orig/configure.ac ++++ openssh-9.6p1/configure.ac +@@ -766,6 +766,30 @@ int main(void) { if (NSVersionOfRunTimeL [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -333,20 +430,29 @@ index b689db4b..efafb6bd 100644 m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff --git a/gss-genr.c b/gss-genr.c -index d56257b4..763a63ff 100644 ---- a/gss-genr.c -+++ b/gss-genr.c -@@ -41,9 +41,33 @@ - #include "sshbuf.h" +Index: openssh-9.6p1/gss-genr.c +=================================================================== +--- openssh-9.6p1.orig/gss-genr.c ++++ openssh-9.6p1/gss-genr.c +@@ -1,7 +1,7 @@ + /* $OpenBSD: gss-genr.c,v 1.28 2021/01/27 10:05:28 djm Exp $ */ + + /* +- * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. ++ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -43,8 +43,34 @@ #include "log.h" #include "ssh2.h" + +#include "cipher.h" +#include "sshkey.h" +#include "kex.h" +#include "digest.h" +#include "packet.h" - ++ #include "ssh-gss.h" +typedef struct { @@ -364,14 +470,15 @@ index d56257b4..763a63ff 100644 +static ssh_gss_kex_mapping *gss_enc2oid = NULL; + +int -+ssh_gssapi_oid_table_ok(void) { ++ssh_gssapi_oid_table_ok(void) ++{ + return (gss_enc2oid != NULL); +} + /* sshbuf_get for gss_buffer_desc */ int ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) -@@ -62,6 +86,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) +@@ -60,6 +86,161 @@ ssh_gssapi_get_buffer_desc(struct sshbuf return 0; } @@ -415,8 +522,7 @@ index d56257b4..763a63ff 100644 + const char *host, const char *client, const char *kex) { + struct sshbuf *buf = NULL; + size_t i; -+ int r = SSH_ERR_ALLOC_FAIL; -+ int oidpos, enclen; ++ int r, oidpos, enclen; + char *mechs, *encoded; + u_char digest[SSH_DIGEST_MAX_LENGTH]; + char deroid[2]; @@ -433,7 +539,7 @@ index d56257b4..763a63ff 100644 + (gss_supported->count + 1)); + + if ((buf = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + + oidpos = 0; + s = cp = xstrdup(kex); @@ -450,7 +556,8 @@ index d56257b4..763a63ff 100644 + 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"); ++ fatal("%s: digest failed: %s", __func__, ++ ssh_err(r)); + ssh_digest_free(md); + md = NULL; + @@ -465,10 +572,12 @@ index d56257b4..763a63ff 100644 + (p = strsep(&cp, ","))) { + if (sshbuf_len(buf) != 0 && + (r = sshbuf_put_u8(buf, ',')) != 0) -+ fatal_fr(r, "sshbuf_put_u8 error"); ++ fatal("%s: sshbuf_put_u8 error: %s", ++ __func__, ssh_err(r)); + if ((r = sshbuf_put(buf, p, strlen(p))) != 0 || + (r = sshbuf_put(buf, encoded, enclen)) != 0) -+ fatal_fr(r, "sshbuf_put error"); ++ fatal("%s: sshbuf_put error: %s", ++ __func__, ssh_err(r)); + } + + gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); @@ -481,7 +590,7 @@ index d56257b4..763a63ff 100644 + gss_enc2oid[oidpos].encoded = NULL; + + if ((mechs = sshbuf_dup_string(buf)) == NULL) -+ fatal_f("sshbuf_dup_string failed"); ++ fatal("%s: sshbuf_dup_string failed", __func__); + + sshbuf_free(buf); + @@ -531,7 +640,7 @@ index d56257b4..763a63ff 100644 /* Check that the OID in a data stream matches that in the context */ int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) -@@ -218,7 +398,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, +@@ -216,7 +397,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int de } ctx->major = gss_init_sec_context(&ctx->minor, @@ -540,11 +649,10 @@ index d56257b4..763a63ff 100644 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); -@@ -247,9 +427,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) - return (ctx->major); +@@ -246,8 +427,42 @@ ssh_gssapi_import_name(Gssctxt *ctx, con } -+OM_uint32 + OM_uint32 +ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) +{ + gss_buffer_desc gssbuf; @@ -575,7 +683,7 @@ index d56257b4..763a63ff 100644 + return(ctx->major); +} + - OM_uint32 ++OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) { + if (ctx == NULL) @@ -584,7 +692,7 @@ index d56257b4..763a63ff 100644 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, GSS_C_QOP_DEFAULT, buffer, hash))) ssh_gssapi_error(ctx); -@@ -257,6 +471,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) +@@ -255,6 +470,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer return (ctx->major); } @@ -604,7 +712,7 @@ index d56257b4..763a63ff 100644 void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context, const struct sshbuf *session_id) -@@ -273,11 +500,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, +@@ -271,11 +499,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, co } int @@ -621,8 +729,8 @@ index d56257b4..763a63ff 100644 + ctx = &intctx; /* RFC 4462 says we MUST NOT do SPNEGO */ - if (oid->length == spnego_oid.length && -@@ -500,6 +500,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) + if (oid->length == spnego_oid.length && +@@ -285,6 +518,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx ssh_gssapi_build_ctx(ctx); ssh_gssapi_set_oid(*ctx, oid); major = ssh_gssapi_import_name(*ctx, host); @@ -631,13 +739,13 @@ index d56257b4..763a63ff 100644 + major = ssh_gssapi_client_identity(*ctx, client); + if (!GSS_ERROR(major)) { - major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, + major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL); -@@ -527,10 +527,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx +@@ -294,10 +531,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx GSS_C_NO_BUFFER); } -- if (GSS_ERROR(major)) +- if (GSS_ERROR(major)) + if (GSS_ERROR(major) || intctx != NULL) ssh_gssapi_delete_ctx(ctx); @@ -701,10 +809,10 @@ index d56257b4..763a63ff 100644 +} + #endif /* GSSAPI */ -diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c -index a151bc1e..8d2b677f 100644 ---- a/gss-serv-krb5.c -+++ b/gss-serv-krb5.c +Index: openssh-9.6p1/gss-serv-krb5.c +=================================================================== +--- openssh-9.6p1.orig/gss-serv-krb5.c ++++ openssh-9.6p1/gss-serv-krb5.c @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */ @@ -714,7 +822,7 @@ index a151bc1e..8d2b677f 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -120,7 +120,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; @@ -723,7 +831,7 @@ index a151bc1e..8d2b677f 100644 const char *errmsg; if (client->creds == NULL) { -@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -180,11 +180,26 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl return; } @@ -754,7 +862,7 @@ index a151bc1e..8d2b677f 100644 #ifdef USE_PAM if (options.use_pam) -@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +@@ -193,9 +208,76 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_cc_close(krb_context, ccache); @@ -841,10 +949,10 @@ index a151bc1e..8d2b677f 100644 }; #endif /* KRB5 */ -diff --git a/gss-serv.c b/gss-serv.c -index ab3a15f0..6ce56e92 100644 ---- a/gss-serv.c -+++ b/gss-serv.c +Index: openssh-9.6p1/gss-serv.c +=================================================================== +--- openssh-9.6p1.orig/gss-serv.c ++++ openssh-9.6p1/gss-serv.c @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ @@ -877,11 +985,10 @@ index ab3a15f0..6ce56e92 100644 #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -140,6 +142,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) - return (ssh_gssapi_acquire_cred(*ctx)); +@@ -141,6 +143,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss } -+/* Unprivileged */ + /* Unprivileged */ +char * +ssh_gssapi_server_mechanisms(void) { + if (supported_oids == NULL) @@ -898,16 +1005,17 @@ index ab3a15f0..6ce56e92 100644 + Gssctxt *ctx = NULL; + int res; + -+ res = !GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctx, oid)); ++ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); + ssh_gssapi_delete_ctx(&ctx); + + return (res); +} + - /* Unprivileged */ ++/* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) -@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) + { +@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -940,8 +1048,7 @@ index ab3a15f0..6ce56e92 100644 + ssh_gssapi_error(ctx); + return (ctx->major); + } - -- gss_buffer_desc ename; ++ + ctx->major = gss_compare_name(&ctx->minor, client->name, + new_name, &equal); + @@ -954,7 +1061,8 @@ index ab3a15f0..6ce56e92 100644 + debug("Rekeyed credentials have different name"); + return GSS_S_COMPLETE; + } -+ + +- gss_buffer_desc ename; + debug("Marking rekeyed credentials for export"); + + gss_release_name(&ctx->minor, &client->name); @@ -968,7 +1076,7 @@ index ab3a15f0..6ce56e92 100644 client->mech = NULL; -@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g if (client->mech == NULL) return GSS_S_FAILURE; @@ -982,7 +1090,7 @@ index ab3a15f0..6ce56e92 100644 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g return (ctx->major); } @@ -991,7 +1099,7 @@ index ab3a15f0..6ce56e92 100644 /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g void ssh_gssapi_cleanup_creds(void) { @@ -1005,10 +1113,10 @@ index ab3a15f0..6ce56e92 100644 + + if (gssapi_client.store.data != NULL) { + if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { -+ debug_f("krb5_cc_resolve(): %.100s", ++ debug("%s: krb5_cc_resolve(): %.100s", __func__, + krb5_get_err_text(gssapi_client.store.data, problem)); + } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { -+ debug_f("krb5_cc_destroy(): %.100s", ++ debug("%s: krb5_cc_destroy(): %.100s", __func__, + krb5_get_err_text(gssapi_client.store.data, problem)); + } else { + krb5_free_context(gssapi_client.store.data); @@ -1017,7 +1125,7 @@ index ab3a15f0..6ce56e92 100644 } } -@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) +@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int /* Privileged */ int @@ -1044,7 +1152,7 @@ index ab3a15f0..6ce56e92 100644 /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -382,14 +471,85 @@ ssh_gssapi_userok(char *user) +@@ -382,14 +471,90 @@ ssh_gssapi_userok(char *user) return (0); } @@ -1087,7 +1195,7 @@ index ab3a15f0..6ce56e92 100644 + gssapi_client.store.envvar == NULL) + return; + -+ ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); ++ ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); + + if (!ok) + return; @@ -1099,6 +1207,11 @@ index ab3a15f0..6ce56e92 100644 + * for rekeying. So, use our own :) + */ +#ifdef USE_PAM ++ if (!use_privsep) { ++ debug("Not even going to try and do PAM with privsep disabled"); ++ return; ++ } ++ + ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name, + &pamconv, &pamh); + if (ret) @@ -1136,40 +1249,26 @@ index ab3a15f0..6ce56e92 100644 } /* Privileged */ -diff --git a/kex.c b/kex.c -index a5ae6ac0..fe714141 100644 ---- a/kex.c -+++ b/kex.c -@@ -698,6 +755,9 @@ kex_free(struct kex *kex) - sshbuf_free(kex->server_version); - sshbuf_free(kex->client_pub); - sshbuf_free(kex->session_id); -+#ifdef GSSAPI -+ free(kex->gss_host); -+#endif /* GSSAPI */ - sshbuf_free(kex->initial_sig); - sshkey_free(kex->initial_hostkey); - free(kex->failed_choice); -diff --git a/kex-names.c b/kex-names.c -index ce85f043..574c7609 100644 ---- a/kex-names.c -+++ b/kex-names.c -@@ -57,6 +57,10 @@ - - #include "fips.h" +Index: openssh-9.6p1/kex.c +=================================================================== +--- openssh-9.6p1.orig/kex.c ++++ openssh-9.6p1/kex.c +@@ -64,6 +64,10 @@ + #include "digest.h" + #include "xmalloc.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + - struct kexalg { - char *name; - u_int type; -@@ -110,6 +113,30 @@ static const struct kexalg kexalgs[] = { - #endif /* WITH_OPENSSL */ - { NULL, -1, -1, -1}, + #include "fips.h" + + /* prototype */ +@@ -121,6 +125,19 @@ static const struct kexalg kexalgs_all[] + #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ + { NULL, 0, -1, -1}, }; -+static const struct kexalg gss_kexalgs_all[] = { ++static const struct kexalg gss_kexalgs[] = { +#ifdef GSSAPI + { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, @@ -1180,46 +1279,31 @@ index ce85f043..574c7609 100644 + 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}, -+}; -+ -+static const struct kexalg gss_kexalgs_fips140_2[] = { -+#ifdef GSSAPI -+ { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, -+ { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, -+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, -+ { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, -+#endif -+ { NULL, 0, -1, -1}, ++ { NULL, 0, -1, -1 }, +}; + static const struct kexalg kexalgs_fips140_2[] = { + #ifdef WITH_OPENSSL +@@ -148,12 +165,12 @@ static const struct kexalg kexalgs_fips1 + /* Returns array of macs available depending on selected FIPS mode */ static const struct kexalg * -@@ -120,14 +140,31 @@ fips_select_kexalgs(void) - } +-fips_select_kexalgs(void) ++fips_select_kexalgs(const struct kexalg *algs) + { + int fips = fips_mode(); + switch (fips) { + case 0: +- return kexalgs_all; ++ return algs; + case 1: + return kexalgs_fips140_2; + default: +@@ -164,13 +181,13 @@ fips_select_kexalgs(void) } -+/* Returns array of macs available depending on selected FIPS mode */ -+static const struct kexalg * -+fips_select_gss_kexalgs(void) -+{ -+ int fips = fips_mode(); -+ switch (fips) { -+ case 0: -+ return gss_kexalgs_all; -+ case 1: -+ return gss_kexalgs_fips140_2; -+ default: -+ /* should not be reached */ -+ fatal("Fatal error: incorrect FIPS mode '%i' at %s:%u", -+ fips, __FILE__, __LINE__); -+ } -+} -+ --char * + char * -kex_alg_list(char sep) -+static char * +kex_alg_list_internal(char sep, const struct kexalg *algs) { char *ret = NULL, *tmp; @@ -1227,45 +1311,47 @@ index ce85f043..574c7609 100644 const struct kexalg *k; - for (k = fips_select_kexalgs(); k->name != NULL; k++) { -+ for (k = algs; k->name != NULL; k++) { ++ for (k = fips_select_kexalgs(algs); k->name != NULL; k++) { if (ret != NULL) ret[rlen++] = sep; nlen = strlen(k->name); -@@ -138,6 +156,18 @@ kex_alg_list(char sep) +@@ -185,15 +202,31 @@ kex_alg_list(char sep) return ret; } +char * +kex_alg_list(char sep) +{ -+ return kex_alg_list_internal(sep, fips_select_kexalgs()); ++ return kex_alg_list_internal(sep, kexalgs_all); +} + +char * +kex_gss_alg_list(char sep) +{ -+ return kex_alg_list_internal(sep, fips_select_gss_kexalgs()); ++ return kex_alg_list_internal(sep, gss_kexalgs); +} + static const struct kexalg * kex_alg_by_name(const char *name) { -@@ -147,6 +177,10 @@ kex_alg_by_name(const char *name) + const struct kexalg *k; + +- for (k = fips_select_kexalgs(); k->name != NULL; k++) { ++ for (k = fips_select_kexalgs(kexalgs_all); k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; } -+ for (k = gss_kexalgs_all; k->name != NULL; k++) { ++ for (k = gss_kexalgs; k->name != NULL; k++) { + if (strncmp(k->name, name, strlen(k->name)) == 0) + return k; + } return NULL; } -@@ -315,3 +349,26 @@ kex_assemble_names(char **listp, const char *def, const char *all) - free(ret); +@@ -375,6 +408,29 @@ kex_assemble_names(char **listp, const c return r; } -+ + +/* Validate GSS KEX method name list */ +int +kex_gss_names_valid(const char *names) @@ -1288,10 +1374,24 @@ index ce85f043..574c7609 100644 + free(s); + return 1; +} -diff --git a/kex.h b/kex.h -index a5ae6ac0..fe714141 100644 ---- a/kex.h -+++ b/kex.h ++ + /* + * Fill out a proposal array with dynamically allocated values, which may + * be modified as required for compatibility reasons. +@@ -1010,6 +1066,9 @@ kex_free(struct kex *kex) + sshbuf_free(kex->session_id); + sshbuf_free(kex->initial_sig); + sshkey_free(kex->initial_hostkey); ++#ifdef GSSAPI ++ free(kex->gss_host); ++#endif /* GSSAPI */ + free(kex->failed_choice); + free(kex->hostkey_alg); + free(kex->name); +Index: openssh-9.6p1/kex.h +=================================================================== +--- openssh-9.6p1.orig/kex.h ++++ openssh-9.6p1/kex.h @@ -102,6 +102,15 @@ enum kex_exchange { KEX_ECDH_SHA2, KEX_C25519_SHA256, @@ -1308,7 +1408,7 @@ index a5ae6ac0..fe714141 100644 KEX_MAX }; -@@ -153,6 +162,12 @@ struct kex { +@@ -164,6 +173,12 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1321,22 +1421,22 @@ index a5ae6ac0..fe714141 100644 char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -174,8 +189,10 @@ struct kex { - int kex_nid_from_name(const char *); +@@ -185,8 +200,10 @@ struct kex { + int kex_names_valid(const char *); char *kex_alg_list(char); +char *kex_gss_alg_list(char); char *kex_names_cat(const char *, const char *); - int kex_has_any_alg(const char *, const char *); -+int kex_gss_names_valid(const char *); int kex_assemble_names(char **, const char *, const char *); ++int kex_gss_names_valid(const char *); void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], const char *, const char *, const char *, const char *, const char *); -@@ -202,6 +219,12 @@ int kexgex_client(struct ssh *); + void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]); +@@ -219,6 +236,12 @@ int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kex_gen_client(struct ssh *); int kex_gen_server(struct ssh *); -+#if defined(GSSAPI) && defined(WITH_OPENSSL) ++#ifdef GSSAPI +int kexgssgex_client(struct ssh *); +int kexgssgex_server(struct ssh *); +int kexgss_client(struct ssh *); @@ -1345,7 +1445,7 @@ index a5ae6ac0..fe714141 100644 int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -234,6 +257,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, +@@ -251,6 +274,12 @@ int kexgex_hash(int, const struct sshbu const BIGNUM *, const u_char *, size_t, u_char *, size_t *); @@ -1358,11 +1458,11 @@ index a5ae6ac0..fe714141 100644 void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); -diff --git a/kexdh.c b/kexdh.c -index 67133e33..edaa4676 100644 ---- a/kexdh.c -+++ b/kexdh.c -@@ -48,13 +48,23 @@ kex_dh_keygen(struct kex *kex) +Index: openssh-9.6p1/kexdh.c +=================================================================== +--- openssh-9.6p1.orig/kexdh.c ++++ openssh-9.6p1/kexdh.c +@@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: @@ -1386,10 +1486,10 @@ index 67133e33..edaa4676 100644 kex->dh = dh_new_group16(); break; case KEX_DH_GRP18_SHA512: -diff --git a/kexgen.c b/kexgen.c -index 69348b96..c0e8c2f4 100644 ---- a/kexgen.c -+++ b/kexgen.c +Index: openssh-9.6p1/kexgen.c +=================================================================== +--- openssh-9.6p1.orig/kexgen.c ++++ openssh-9.6p1/kexgen.c @@ -44,7 +44,7 @@ static int input_kex_gen_init(int, u_int32_t, struct ssh *); static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); @@ -1399,12 +1499,11 @@ index 69348b96..c0e8c2f4 100644 kex_gen_hash( int hash_alg, const struct sshbuf *client_version, -diff --git a/kexgssc.c b/kexgssc.c -new file mode 100644 -index 00000000..f6e1405e +Index: openssh-9.6p1/kexgssc.c +=================================================================== --- /dev/null -+++ b/kexgssc.c -@@ -0,0 +1,612 @@ ++++ openssh-9.6p1/kexgssc.c +@@ -0,0 +1,595 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1466,7 +1565,7 @@ index 00000000..f6e1405e + struct sshbuf *server_blob = NULL; + struct sshbuf *shared_secret = NULL; + struct sshbuf *server_host_key_blob = NULL; -+ struct sshbuf *empty = NULL; ++ struct sshbuf *empty = sshbuf_new(); + u_char *msg; + int type = 0; + int first = 1; @@ -1503,12 +1602,10 @@ index 00000000..f6e1405e + r = kex_c25519_keypair(kex); + break; + default: -+ fatal_f("Unexpected KEX type %d", kex->kex_type); ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } -+ if (r != 0) { -+ ssh_gssapi_delete_ctx(&ctxt); ++ if (r != 0) + return r; -+ } + + token_ptr = GSS_C_NO_BUFFER; + @@ -1571,16 +1668,11 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -+ u_char *tmp = NULL; -+ size_t tmp_len = 0; -+ + debug("Received KEXGSS_HOSTKEY"); + if (server_host_key_blob) + fatal("Server host key received more than once"); -+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) ++ if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) + fatal("Failed to read server host key: %s", ssh_err(r)); -+ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) -+ fatal("sshbuf_from failed"); + } + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); + @@ -1681,11 +1773,6 @@ index 00000000..f6e1405e + if (r != 0) + goto out; + -+ if ((empty = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ + hashlen = sizeof(hash); + if ((r = kex_gen_hash( + kex->hash_alg, @@ -1698,7 +1785,7 @@ index 00000000..f6e1405e + server_blob, + shared_secret, + hash, &hashlen)) != 0) -+ fatal_f("Unexpected KEX type %d", kex->kex_type); ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + + gssbuf.value = hash; + gssbuf.length = hashlen; @@ -1755,7 +1842,7 @@ index 00000000..f6e1405e + size_t hashlen; + const BIGNUM *pub_key, *dh_p, *dh_g; + int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; -+ struct sshbuf *empty = NULL; ++ struct sshbuf *empty = sshbuf_new(); + u_char c; + int r; + @@ -1867,16 +1954,11 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { -+ u_char *tmp = NULL; -+ size_t tmp_len = 0; -+ + debug("Received KEXGSS_HOSTKEY"); + if (server_host_key_blob) + fatal("Server host key received more than once"); -+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) ++ if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); -+ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) -+ fatal("sshbuf_from failed"); + } + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); + @@ -1952,7 +2034,6 @@ index 00000000..f6e1405e + (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) + goto out; + sshbuf_free(buf); -+ buf = NULL; + + if ((shared_secret = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; @@ -1961,10 +2042,6 @@ index 00000000..f6e1405e + + if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) + goto out; -+ if ((empty = sshbuf_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } + + DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); + hashlen = sizeof(hash); @@ -1992,6 +2069,13 @@ index 00000000..f6e1405e + + gss_release_buffer(&min_status, &msg_tok); + ++ /* save session id */ ++ if (kex->session_id == NULL) { ++ kex->session_id = sshbuf_new (); ++ if ((r = sshbuf_put(kex->session_id, hash, hashlen)) != 0) ++ goto out; ++ } ++ + if (kex->gss_deleg_creds) + ssh_gssapi_credentials_updated(ctxt); + @@ -2004,7 +2088,6 @@ index 00000000..f6e1405e + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); +out: -+ sshbuf_free(buf); + sshbuf_free(server_blob); + sshbuf_free(empty); + explicit_bzero(hash, sizeof(hash)); @@ -2015,14 +2098,12 @@ index 00000000..f6e1405e + sshbuf_free(server_host_key_blob); + return r; +} -+ +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --git a/kexgsss.c b/kexgsss.c -new file mode 100644 -index 00000000..60bc02de +Index: openssh-9.6p1/kexgsss.c +=================================================================== --- /dev/null -+++ b/kexgsss.c -@@ -0,0 +1,482 @@ ++++ openssh-9.6p1/kexgsss.c +@@ -0,0 +1,474 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -2089,7 +2170,7 @@ index 00000000..60bc02de + */ + + OM_uint32 ret_flags = 0; -+ gss_buffer_desc gssbuf = {0, NULL}, recv_tok, msg_tok; ++ gss_buffer_desc gssbuf, recv_tok, msg_tok; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + Gssctxt *ctxt = NULL; + struct sshbuf *shared_secret = NULL; @@ -2114,14 +2195,14 @@ index 00000000..60bc02de + free(mechs); + } + -+ debug2_f("Identifying %s", kex->name); ++ debug2("%s: Identifying %s", __func__, kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) + fatal("Unknown gssapi mechanism"); + -+ debug2_f("Acquiring credentials"); ++ debug2("%s: Acquiring credentials", __func__); + -+ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + fatal("Unable to acquire credentials for the server"); + + do { @@ -2129,7 +2210,7 @@ index 00000000..60bc02de + type = ssh_packet_read(ssh); + switch(type) { + case SSH2_MSG_KEXGSS_INIT: -+ if (gssbuf.value != NULL) ++ if (client_pubkey != NULL) + fatal("Received KEXGSS_INIT after initialising"); + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, + &recv_tok)) != 0 || @@ -2154,37 +2235,12 @@ index 00000000..60bc02de + &shared_secret); + break; + default: -+ fatal_f("Unexpected KEX type %d", kex->kex_type); ++ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } + if (r != 0) + goto out; + + /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ -+ -+ /* Calculate the hash early so we can free the -+ * client_pubkey, which has reference to the parent -+ * buffer state->incoming_packet -+ */ -+ hashlen = sizeof(hash); -+ if ((r = kex_gen_hash( -+ kex->hash_alg, -+ kex->client_version, -+ kex->server_version, -+ kex->peer, -+ kex->my, -+ empty, -+ client_pubkey, -+ server_pubkey, -+ shared_secret, -+ hash, &hashlen)) != 0) -+ goto out; -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ -+ sshbuf_free(client_pubkey); -+ client_pubkey = NULL; -+ + break; + case SSH2_MSG_KEXGSS_CONTINUE: + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, @@ -2198,15 +2254,15 @@ index 00000000..60bc02de + type); + } + -+ maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, -+ &send_tok, &ret_flags); ++ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, ++ &send_tok, &ret_flags)); + + gss_release_buffer(&min_status, &recv_tok); + + if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) + fatal("Zero length token output when incomplete"); + -+ if (gssbuf.value == NULL) ++ if (client_pubkey == NULL) + fatal("No client public key"); + + if (maj_status & GSS_S_CONTINUE_NEEDED) { @@ -2235,7 +2291,24 @@ index 00000000..60bc02de + if (!(ret_flags & GSS_C_INTEG_FLAG)) + fatal("Integrity flag wasn't set"); + -+ if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) ++ hashlen = sizeof(hash); ++ if ((r = kex_gen_hash( ++ kex->hash_alg, ++ kex->client_version, ++ kex->server_version, ++ kex->peer, ++ kex->my, ++ empty, ++ client_pubkey, ++ server_pubkey, ++ shared_secret, ++ hash, &hashlen)) != 0) ++ goto out; ++ ++ gssbuf.value = hash; ++ gssbuf.length = hashlen; ++ ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) + fatal("Couldn't get MIC"); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || @@ -2318,14 +2391,14 @@ index 00000000..60bc02de + if ((mechs = ssh_gssapi_server_mechanisms())) + free(mechs); + -+ debug2_f("Identifying %s", kex->name); ++ debug2("%s: Identifying %s", __func__, kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) + fatal("Unknown gssapi mechanism"); + -+ debug2_f("Acquiring credentials"); ++ debug2("%s: Acquiring credentials", __func__); + -+ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + fatal("Unable to acquire credentials for the server"); + + /* 5. S generates an ephemeral key pair (do the allocations early) */ @@ -2347,7 +2420,7 @@ index 00000000..60bc02de + if (max < min || nbits < min || max < nbits) + fatal("GSS_GEX, bad parameters: %d !< %d !< %d", + min, nbits, max); -+ kex->dh = mm_choose_dh(min, nbits, max); ++ kex->dh = PRIVSEP(choose_dh(min, nbits, max)); + if (kex->dh == NULL) { + sshpkt_disconnect(ssh, "Protocol error: no matching group found"); + fatal("Protocol error: no matching group found"); @@ -2394,8 +2467,8 @@ index 00000000..60bc02de + type); + } + -+ maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, -+ &send_tok, &ret_flags); ++ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, ++ &send_tok, &ret_flags)); + + gss_release_buffer(&min_status, &recv_tok); + @@ -2460,7 +2533,7 @@ index 00000000..60bc02de + gssbuf.value = hash; + gssbuf.length = hashlen; + -+ if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) ++ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) + fatal("Couldn't get MIC"); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || @@ -2505,20 +2578,20 @@ index 00000000..60bc02de + return r; +} +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --git a/monitor.c b/monitor.c -index 2ce89fe9..ebf76c7f 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -148,6 +148,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); +Index: openssh-9.6p1/monitor.c +=================================================================== +--- openssh-9.6p1.orig/monitor.c ++++ openssh-9.6p1/monitor.c +@@ -142,6 +142,8 @@ int mm_answer_gss_setup_ctx(struct ssh * int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); -+int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); -+int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); ++int mm_answer_gss_sign(struct ssh*, int, struct sshbuf *); ++int mm_answer_gss_updatecreds(struct ssh*, int, struct sshbuf *); #endif #ifdef SSH_AUDIT_EVENTS -@@ -220,11 +222,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -214,11 +216,18 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, @@ -2537,7 +2610,7 @@ index 2ce89fe9..ebf76c7f 100644 #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -293,6 +302,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -287,6 +296,10 @@ monitor_child_preauth(struct ssh *ssh, s /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -2548,24 +2621,7 @@ index 2ce89fe9..ebf76c7f 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -376,8 +376,15 @@ monitor_child_preauth(struct ssh *ssh, s - if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { - auth_log(ssh, authenticated, partial, - auth_method, auth_submethod); -- if (!partial && !authenticated) -+ if (!partial && !authenticated) { -+#ifdef GSSAPI -+ /* If gssapi-with-mic failed, MONITOR_REQ_GSSCHECKMIC is disabled. -+ * We have to reenable it to try again for gssapi-keyex */ -+ if (strcmp(auth_method, "gssapi-with-mic") == 0 && options.gss_keyex) -+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); -+#endif - authctxt->failures++; -+ } - if (authenticated || partial) { - auth2_update_session_info(authctxt, - auth_method, auth_submethod); -@@ -406,6 +419,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -403,6 +416,10 @@ monitor_child_postauth(struct ssh *ssh, monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2576,25 +2632,25 @@ index 2ce89fe9..ebf76c7f 100644 if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1713,6 +1730,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1745,6 +1762,17 @@ monitor_apply_keystate(struct ssh *ssh, # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif +# ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; -+ } ++ if (options.gss_keyex) { ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; ++ } +# endif #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -@@ -1806,8 +1834,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1837,8 +1865,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, u_char *p; int r; @@ -2605,7 +2661,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal_fr(r, "parse"); -@@ -1839,8 +1867,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1870,8 +1898,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2616,7 +2672,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal_fr(r, "ssh_gssapi_get_buffer_desc"); -@@ -1860,6 +1888,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1891,6 +1919,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2624,7 +2680,7 @@ index 2ce89fe9..ebf76c7f 100644 } return (0); } -@@ -1871,8 +1900,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1902,8 +1931,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, OM_uint32 ret; int r; @@ -2635,7 +2691,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -1898,13 +1927,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1929,13 +1958,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -2650,14 +2706,14 @@ index 2ce89fe9..ebf76c7f 100644 - authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); + if ((r = sshbuf_get_u32(m, &kex)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + authenticated = authctxt->valid && + ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1913,7 +1946,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1944,7 +1977,11 @@ mm_answer_gss_userok(struct ssh *ssh, in debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -2670,7 +2726,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1921,5 +1958,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1952,5 +1989,85 @@ mm_answer_gss_userok(struct ssh *ssh, in /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2686,15 +2742,16 @@ index 2ce89fe9..ebf76c7f 100644 + int r; + + if (!options.gss_authentication && !options.gss_keyex) -+ fatal_f("GSSAPI not enabled"); ++ fatal("%s: GSSAPI not enabled", __func__); + + if ((r = sshbuf_get_string(m, &p, &len)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + data.value = p; + data.length = len; + /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ + if (data.length != 20 && data.length != 32 && data.length != 64) -+ fatal_f("data length incorrect: %d", (int) data.length); ++ fatal("%s: data length incorrect: %d", __func__, ++ (int) data.length); + + /* Save the session ID on the first time around */ + if (session_id2_len == 0) { @@ -2710,7 +2767,7 @@ index 2ce89fe9..ebf76c7f 100644 + + if ((r = sshbuf_put_u32(m, major)) != 0 || + (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); + @@ -2731,12 +2788,12 @@ index 2ce89fe9..ebf76c7f 100644 + int r, ok; + + if (!options.gss_authentication && !options.gss_keyex) -+ fatal_f("GSSAPI not enabled"); ++ fatal("%s: GSSAPI not enabled", __func__); + + if ((r = sshbuf_get_string(m, (u_char **)&store.filename, NULL)) != 0 || + (r = sshbuf_get_string(m, (u_char **)&store.envvar, NULL)) != 0 || + (r = sshbuf_get_string(m, (u_char **)&store.envval, NULL)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + ok = ssh_gssapi_update_creds(&store); + @@ -2746,7 +2803,7 @@ index 2ce89fe9..ebf76c7f 100644 + + sshbuf_reset(m); + if ((r = sshbuf_put_u32(m, ok)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); + @@ -2755,10 +2812,10 @@ index 2ce89fe9..ebf76c7f 100644 + #endif /* GSSAPI */ -diff --git a/monitor.h b/monitor.h -index 683e5e07..2b1a2d59 100644 ---- a/monitor.h -+++ b/monitor.h +Index: openssh-9.6p1/monitor.h +=================================================================== +--- openssh-9.6p1.orig/monitor.h ++++ openssh-9.6p1/monitor.h @@ -63,6 +63,8 @@ enum monitor_reqtype { MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, @@ -2768,11 +2825,11 @@ index 683e5e07..2b1a2d59 100644 }; struct ssh; -diff --git a/monitor_wrap.c b/monitor_wrap.c -index 001a8fa1..6edb509a 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -993,13 +993,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +Index: openssh-9.6p1/monitor_wrap.c +=================================================================== +--- openssh-9.6p1.orig/monitor_wrap.c ++++ openssh-9.6p1/monitor_wrap.c +@@ -998,13 +998,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -2785,11 +2842,11 @@ index 001a8fa1..6edb509a 100644 if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, kex)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, -@@ -1012,6 +1014,59 @@ mm_ssh_gssapi_userok(char *user) +@@ -1017,4 +1019,57 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -2802,16 +2859,16 @@ index 001a8fa1..6edb509a 100644 + int r; + + if ((m = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_string(m, data->value, data->length)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, m); + + if ((r = sshbuf_get_u32(m, &major)) != 0 || + (r = ssh_gssapi_get_buffer_desc(m, hash)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + sshbuf_free(m); + @@ -2825,7 +2882,7 @@ index 001a8fa1..6edb509a 100644 + int r, ok; + + if ((m = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + + if ((r = sshbuf_put_cstring(m, + store->filename ? store->filename : "")) != 0 || @@ -2833,13 +2890,13 @@ index 001a8fa1..6edb509a 100644 + store->envvar ? store->envvar : "")) != 0 || + (r = sshbuf_put_cstring(m, + store->envval ? store->envval : "")) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, m); + + if ((r = sshbuf_get_u32(m, &ok)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + sshbuf_free(m); + @@ -2847,13 +2904,11 @@ index 001a8fa1..6edb509a 100644 +} + #endif /* GSSAPI */ - - /* -diff --git a/monitor_wrap.h b/monitor_wrap.h -index 23ab096a..485590c1 100644 ---- a/monitor_wrap.h -+++ b/monitor_wrap.h -@@ -64,8 +64,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, +Index: openssh-9.6p1/monitor_wrap.h +=================================================================== +--- openssh-9.6p1.orig/monitor_wrap.h ++++ openssh-9.6p1/monitor_wrap.h +@@ -65,8 +65,10 @@ int mm_sshkey_verify(const struct sshkey 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 *); @@ -2865,10 +2920,11 @@ index 23ab096a..485590c1 100644 #endif #ifdef USE_PAM -diff -up a/readconf.c.gsskex b/readconf.c ---- a/readconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/readconf.c 2021-08-27 12:25:42.556421509 +0200 -@@ -67,6 +67,7 @@ +Index: openssh-9.6p1/readconf.c +=================================================================== +--- openssh-9.6p1.orig/readconf.c ++++ openssh-9.6p1/readconf.c +@@ -70,6 +70,7 @@ #include "uidswap.h" #include "myproposal.h" #include "digest.h" @@ -2876,7 +2932,7 @@ diff -up a/readconf.c.gsskex b/readconf.c #include "fips.h" -@@ -161,6 +162,8 @@ typedef enum { +@@ -166,6 +167,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -2885,7 +2941,7 @@ diff -up a/readconf.c.gsskex b/readconf.c 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 }, @@ -2908,7 +2964,7 @@ diff -up a/readconf.c.gsskex b/readconf.c #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1113,10 +1128,42 @@ parse_time: +@@ -1212,10 +1227,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2951,7 +3007,7 @@ diff -up a/readconf.c.gsskex b/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -2306,7 +2353,13 @@ initialize_options(Options * options) +@@ -2524,7 +2571,13 @@ initialize_options(Options * options) options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; options->gss_authentication = -1; @@ -2965,7 +3021,7 @@ diff -up a/readconf.c.gsskex b/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2463,8 +2516,18 @@ fill_default_options(Options * options) +@@ -2687,8 +2740,18 @@ fill_default_options(Options * options) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2984,7 +3040,7 @@ diff -up a/readconf.c.gsskex b/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -3246,7 +3309,14 @@ dump_client_config(Options *o, const cha +@@ -3518,7 +3581,14 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -2999,10 +3055,11 @@ diff -up a/readconf.c.gsskex b/readconf.c #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff -up a/readconf.h.gsskex b/readconf.h ---- a/readconf.h.gsskex 2021-08-27 12:05:29.248142431 +0200 -+++ b/readconf.h 2021-08-27 12:22:19.270679852 +0200 -@@ -39,7 +39,13 @@ typedef struct { +Index: openssh-9.6p1/readconf.h +=================================================================== +--- openssh-9.6p1.orig/readconf.h ++++ openssh-9.6p1/readconf.h +@@ -40,7 +40,13 @@ typedef struct { int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ int gss_authentication; /* Try GSS authentication */ @@ -3016,17 +3073,18 @@ diff -up a/readconf.h.gsskex b/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up a/servconf.c.gsskex b/servconf.c ---- a/servconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 -+++ b/servconf.c 2021-08-27 12:28:15.887735189 +0200 -@@ -70,6 +70,7 @@ +Index: openssh-9.6p1/servconf.c +=================================================================== +--- openssh-9.6p1.orig/servconf.c ++++ openssh-9.6p1/servconf.c +@@ -68,6 +68,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" +#include "ssh-gss.h" #include "fips.h" - #if !defined(SSHD_PAM_SERVICE) + static void add_listen_addr(ServerOptions *, const char *, @@ -136,8 +137,11 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -3039,7 +3097,7 @@ diff -up a/servconf.c.gsskex b/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -356,10 +360,18 @@ fill_default_server_options(ServerOption +@@ -381,10 +385,18 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3058,15 +3116,15 @@ diff -up a/servconf.c.gsskex b/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -506,6 +518,7 @@ typedef enum { - sPerSourcePenalties, sPerSourcePenaltyExemptList, +@@ -543,6 +555,7 @@ typedef enum { + sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -587,12 +600,22 @@ static struct { +@@ -627,12 +640,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3089,7 +3147,7 @@ diff -up a/servconf.c.gsskex b/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ -@@ -1576,6 +1599,10 @@ process_server_config_line_depth(ServerO +@@ -1646,6 +1669,10 @@ process_server_config_line_depth(ServerO intptr = &options->gss_authentication; goto parse_flag; @@ -3100,7 +3158,7 @@ diff -up a/servconf.c.gsskex b/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1584,6 +1611,22 @@ process_server_config_line_depth(ServerO +@@ -1654,6 +1681,22 @@ process_server_config_line_depth(ServerO intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3123,7 +3181,7 @@ diff -up a/servconf.c.gsskex b/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2892,6 +2935,10 @@ dump_config(ServerOptions *o) +@@ -3088,6 +3131,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -3134,11 +3192,11 @@ diff -up a/servconf.c.gsskex b/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff --git a/servconf.h b/servconf.h -index 4202a2d0..3f47ea25 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -132,8 +132,11 @@ typedef struct { +Index: openssh-9.6p1/servconf.h +=================================================================== +--- openssh-9.6p1.orig/servconf.h ++++ openssh-9.6p1/servconf.h +@@ -139,8 +139,11 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -3150,11 +3208,11 @@ index 4202a2d0..3f47ea25 100644 int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff --git a/session.c b/session.c -index 8c0e54f7..06a33442 100644 ---- a/session.c -+++ b/session.c -@@ -2678,13 +2678,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +Index: openssh-9.6p1/session.c +=================================================================== +--- openssh-9.6p1.orig/session.c ++++ openssh-9.6p1/session.c +@@ -2726,13 +2726,19 @@ do_cleanup(struct ssh *ssh, Authctxt *au #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3176,11 +3234,19 @@ index 8c0e54f7..06a33442 100644 #endif /* remove agent socket */ -diff --git a/ssh-gss.h b/ssh-gss.h -index 36180d07..70dd3665 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -61,10 +61,34 @@ +Index: openssh-9.6p1/ssh-gss.h +=================================================================== +--- openssh-9.6p1.orig/ssh-gss.h ++++ openssh-9.6p1/ssh-gss.h +@@ -1,6 +1,6 @@ + /* $OpenBSD: ssh-gss.h,v 1.15 2021/01/27 10:05:28 djm Exp $ */ + /* +- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. ++ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -61,10 +61,30 @@ #define SSH_GSS_OIDTYPE 0x06 @@ -3200,12 +3266,8 @@ index 36180d07..70dd3665 100644 +#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" + +#define GSS_KEX_DEFAULT_KEX \ -+ KEX_GSS_GRP14_SHA256_ID "," \ -+ KEX_GSS_GRP16_SHA512_ID "," \ -+ KEX_GSS_NISTP256_SHA256_ID "," \ -+ KEX_GSS_C25519_SHA256_ID "," \ -+ KEX_GSS_GRP14_SHA1_ID "," \ -+ KEX_GSS_GEX_SHA1_ID ++ KEX_GSS_GEX_SHA1_ID "," \ ++ KEX_GSS_GRP14_SHA1_ID + typedef struct { char *filename; @@ -3248,7 +3310,7 @@ index 36180d07..70dd3665 100644 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -109,6 +134,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); +@@ -109,6 +134,7 @@ OM_uint32 ssh_gssapi_test_oid_supported( struct sshbuf; int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); @@ -3276,7 +3338,7 @@ index 36180d07..70dd3665 100644 + const char *); OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); -int ssh_gssapi_userok(char *name); -+int ssh_gssapi_userok(char *name, struct passwd *, int kex); ++int ssh_gssapi_userok(char *, struct passwd *, int kex); OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_do_child(char ***, u_int *); void ssh_gssapi_cleanup_creds(void); @@ -3292,11 +3354,11 @@ index 36180d07..70dd3665 100644 #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff --git a/ssh.1 b/ssh.1 -index 60de6087..db5c65bc 100644 ---- a/ssh.1 -+++ b/ssh.1 -@@ -503,7 +503,13 @@ For full details of the options listed below, and their possible values, see +Index: openssh-9.6p1/ssh.1 +=================================================================== +--- openssh-9.6p1.orig/ssh.1 ++++ openssh-9.6p1/ssh.1 +@@ -536,7 +536,13 @@ For full details of the options listed b .It GatewayPorts .It GlobalKnownHostsFile .It GSSAPIAuthentication @@ -3310,7 +3372,7 @@ index 60de6087..db5c65bc 100644 .It HashKnownHosts .It Host .It HostbasedAcceptedAlgorithms -@@ -624,6 +624,8 @@ +@@ -624,6 +630,8 @@ flag), (supported message integrity codes), .Ar kex (key exchange algorithms), @@ -3319,11 +3381,11 @@ index 60de6087..db5c65bc 100644 .Ar key (key types), .Ar key-ca-sign -diff --git a/ssh.c b/ssh.c -index 15aee569..110cf9c1 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -747,6 +747,8 @@ main(int ac, char **av) +Index: openssh-9.6p1/ssh.c +=================================================================== +--- openssh-9.6p1.orig/ssh.c ++++ openssh-9.6p1/ssh.c +@@ -833,6 +833,8 @@ main(int ac, char **av) else if (strcmp(optarg, "kex") == 0 || strcasecmp(optarg, "KexAlgorithms") == 0) cp = kex_alg_list('\n'); @@ -3332,22 +3394,20 @@ index 15aee569..110cf9c1 100644 else if (strcmp(optarg, "key") == 0) cp = sshkey_alg_list(0, 0, 0, '\n'); else if (strcmp(optarg, "key-cert") == 0) -@@ -772,8 +774,8 @@ main(int ac, char **av) +@@ -862,7 +864,7 @@ main(int ac, char **av) + cp[n] = '\n'; } else if (strcmp(optarg, "help") == 0) { cp = xstrdup( - "cipher\ncipher-auth\ncompression\nkex\n" -- "key\nkey-cert\nkey-plain\nkey-sig\nmac\n" -- "protocol-version\nsig"); -+ "kex-gss\nkey\nkey-cert\nkey-plain\n" -+ "key-sig\nmac\nprotocol-version\nsig"); +- "cipher\ncipher-auth\ncompression\nkex\n" ++ "cipher\ncipher-auth\ncompression\nkex\nkex-gss\n" + "key\nkey-cert\nkey-plain\nkey-sig\nmac\n" + "protocol-version\nsig"); } - if (cp == NULL) - fatal("Unsupported query \"%s\"", optarg); -diff --git a/ssh_config b/ssh_config -index 5e8ef548..1ff999b6 100644 ---- a/ssh_config -+++ b/ssh_config -@@ -24,6 +24,8 @@ +Index: openssh-9.6p1/ssh_config +=================================================================== +--- openssh-9.6p1.orig/ssh_config ++++ openssh-9.6p1/ssh_config +@@ -40,6 +40,8 @@ Host * # HostbasedAuthentication no # GSSAPIAuthentication no # GSSAPIDelegateCredentials no @@ -3356,11 +3416,11 @@ index 5e8ef548..1ff999b6 100644 # BatchMode no # CheckHostIP no # AddressFamily any -diff --git a/ssh_config.5 b/ssh_config.5 -index 06a32d31..3f490697 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -766,10 +766,68 @@ The default is +Index: openssh-9.6p1/ssh_config.5 +=================================================================== +--- openssh-9.6p1.orig/ssh_config.5 ++++ openssh-9.6p1/ssh_config.5 +@@ -930,10 +930,67 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -3423,18 +3483,26 @@ index 06a32d31..3f490697 100644 +.Ed +.Pp +The default is -+.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, -+gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . -+This option only applies to connections using GSSAPI. ++.Dq gss-gex-sha1-,gss-group14-sha1- . ++This option only applies to protocol version 2 connections using GSSAPI. .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff --git a/sshconnect2.c b/sshconnect2.c -index af00fb30..03bc87eb 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -163,6 +161,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) - char *all_key, *hkalgs = NULL; +Index: openssh-9.6p1/sshconnect2.c +=================================================================== +--- openssh-9.6p1.orig/sshconnect2.c ++++ openssh-9.6p1/sshconnect2.c +@@ -80,8 +80,6 @@ + #endif + + /* import */ +-extern char *client_version_string; +-extern char *server_version_string; + extern Options options; + + /* +@@ -224,10 +222,44 @@ ssh_kex2(struct ssh *ssh, char *host, st + char *s, *all_key, *hkalgs = NULL; int r, use_known_hosts_order = 0; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3445,30 +3513,19 @@ index af00fb30..03bc87eb 100644 xxx_host = host; xxx_hostaddr = hostaddr; xxx_conn_info = cinfo; -@@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) - options.kex_algorithms, options.ciphers, options.macs, - compression_alg_list(options.compression), - hkalgs ? hkalgs : options.hostkeyalgorithms); -+ + +#if defined(GSSAPI) && defined(WITH_OPENSSL) + if (options.gss_keyex) { + /* Add the GSSAPI mechanisms currently supported on this + * client to the key exchange algorithm proposal */ + orig = myproposal[PROPOSAL_KEX_ALGS]; + -+ if (options.gss_server_identity) { ++ if (options.gss_server_identity) + gss_host = xstrdup(options.gss_server_identity); -+ } else if (options.gss_trust_dns) { ++ 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 { ++ else + gss_host = xstrdup(host); -+ } + + gss = ssh_gssapi_client_mechanisms(gss_host, + options.gss_client_identity, options.gss_kex_algorithms); @@ -3485,10 +3542,11 @@ index af00fb30..03bc87eb 100644 + } + } +#endif - - free(hkalgs); - -@@ -224,14 +256,44 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) ++ + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +@@ -275,17 +307,47 @@ ssh_kex2(struct ssh *ssh, char *host, st # ifdef OPENSSL_HAS_ECC ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; # endif @@ -3519,8 +3577,11 @@ index af00fb30..03bc87eb 100644 +#endif + ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); - kex_proposal_free_entries(myproposal); + /* remove ext-info from the KEX proposals for rekeying */ + free(myproposal[PROPOSAL_KEX_ALGS]); + myproposal[PROPOSAL_KEX_ALGS] = + compat_kex_proposal(ssh, options.kex_algorithms); +#if defined(GSSAPI) && defined(WITH_OPENSSL) + /* repair myproposal after it was crumpled by the */ + /* ext-info removal above */ @@ -3531,10 +3592,10 @@ index af00fb30..03bc87eb 100644 + free(gss); + } +#endif - #ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || -@@ -330,6 +392,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); + if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) + fatal_r(r, "kex_prop2buf"); + +@@ -379,6 +441,7 @@ static int input_gssapi_response(int typ static int input_gssapi_token(int type, u_int32_t, struct ssh *); static int input_gssapi_error(int, u_int32_t, struct ssh *); static int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -3542,7 +3603,7 @@ index af00fb30..03bc87eb 100644 #endif void userauth(struct ssh *, char *); -@@ -346,6 +409,11 @@ static char *authmethods_get(void); +@@ -395,6 +458,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -3554,41 +3615,32 @@ index af00fb30..03bc87eb 100644 {"gssapi-with-mic", userauth_gssapi, userauth_gssapi_cleanup, -@@ -716,12 +784,32 @@ userauth_gssapi(struct ssh *ssh) +@@ -766,12 +834,23 @@ userauth_gssapi(struct ssh *ssh) OM_uint32 min; int r, ok = 0; gss_OID mech = NULL; -+ char *gss_host = NULL; ++ char *gss_host; + -+ if (options.gss_server_identity) { ++ if (options.gss_server_identity) + gss_host = xstrdup(options.gss_server_identity); -+ } else if (options.gss_trust_dns) { ++ else if (options.gss_trust_dns) + gss_host = remote_hostname(ssh); -+ /* Fall back to specified host if we are using proxy command -+ * and can not use DNS on that socket */ -+ if (strcmp(gss_host, "UNKNOWN") == 0) { -+ free(gss_host); -+ gss_host = xstrdup(authctxt->host); -+ } -+ } else { ++ else + gss_host = xstrdup(authctxt->host); -+ } /* Try one GSSAPI method at a time, rather than sending them all at * once. */ if (authctxt->gss_supported_mechs == NULL) - gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); -+ if (GSS_ERROR(gss_indicate_mechs(&min, -+ &authctxt->gss_supported_mechs))) { -+ authctxt->gss_supported_mechs = NULL; ++ if (GSS_ERROR(gss_indicate_mechs(&min, &authctxt->gss_supported_mechs))) { + free(gss_host); + return 0; + } /* Check to see whether the mechanism is usable before we offer it */ while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && -@@ -730,13 +811,15 @@ userauth_gssapi(struct ssh *ssh) +@@ -780,13 +859,15 @@ userauth_gssapi(struct ssh *ssh) elements[authctxt->mech_tried]; /* My DER encoding requires length<128 */ if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, @@ -3605,7 +3657,7 @@ index af00fb30..03bc87eb 100644 if (!ok || mech == NULL) return 0; -@@ -976,6 +1059,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) +@@ -1020,6 +1101,55 @@ input_gssapi_error(int type, u_int32_t p free(lang); return r; } @@ -3630,13 +3682,13 @@ index af00fb30..03bc87eb 100644 + } + + if ((b = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + + ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, + "gssapi-keyex", ssh->kex->session_id); + + if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -+ fatal_f("sshbuf_mutable_ptr failed"); ++ fatal("%s: sshbuf_mutable_ptr failed", __func__); + gssbuf.length = sshbuf_len(b); + + if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { @@ -3650,7 +3702,7 @@ index af00fb30..03bc87eb 100644 + (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || + (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || + (r = sshpkt_send(ssh)) != 0) -+ fatal_fr(r, "parsing"); ++ fatal("%s: %s", __func__, ssh_err(r)); + + sshbuf_free(b); + gss_release_buffer(&ms, &mic); @@ -3661,11 +3713,22 @@ index af00fb30..03bc87eb 100644 #endif /* GSSAPI */ static int -diff --git a/sshd.c b/sshd.c -index 60b2aaf7..d92f03aa 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -1852,7 +1852,8 @@ main(int ac, char **av) +Index: openssh-9.6p1/sshd.c +=================================================================== +--- openssh-9.6p1.orig/sshd.c ++++ openssh-9.6p1/sshd.c +@@ -808,8 +808,8 @@ notify_hostkeys(struct ssh *ssh) + } + debug3_f("sent %u hostkeys", nkeys); + if (nkeys == 0) +- fatal_f("no hostkeys"); +- if ((r = sshpkt_send(ssh)) != 0) ++ debug3("%s: no hostkeys", __func__); ++ else if ((r = sshpkt_send(ssh)) != 0) + sshpkt_fatal(ssh, r, "%s: send", __func__); + sshbuf_free(buf); + } +@@ -1944,7 +1944,8 @@ main(int ac, char **av) free(fp); } accumulate_host_timing_secret(cfg, NULL); @@ -3675,22 +3738,7 @@ index 60b2aaf7..d92f03aa 100644 logit("sshd: no hostkeys available -- exiting."); exit(1); } -diff --git a/sshd-session.c b/sshd-session.c -index 60b2aaf7..d92f03aa 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -817,8 +817,8 @@ notify_hostkeys(struct ssh *ssh) - } - debug3_f("sent %u hostkeys", nkeys); - if (nkeys == 0) -- fatal_f("no hostkeys"); -- if ((r = sshpkt_send(ssh)) != 0) -+ debug3_f("no hostkeys"); -+ else if ((r = sshpkt_send(ssh)) != 0) - sshpkt_fatal(ssh, r, "%s: send", __func__); - sshbuf_free(buf); - } -@@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2421,6 +2422,48 @@ do_ssh2_kex(struct ssh *ssh) free(hkalgs); @@ -3739,10 +3787,10 @@ index 60b2aaf7..d92f03aa 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) fatal_r(r, "kex_setup"); -@@ -2362,7 +2405,18 @@ do_ssh2_kex(struct ssh *ssh) - #ifdef OPENSSL_HAS_ECC +@@ -2438,7 +2481,18 @@ do_ssh2_kex(struct ssh *ssh) + # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; - #endif + # endif -#endif +# ifdef GSSAPI + if (options.gss_keyex) { @@ -3759,10 +3807,10 @@ index 60b2aaf7..d92f03aa 100644 kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; kex->load_host_public_key=&get_hostkey_public_by_type; -diff --git a/sshd_config b/sshd_config -index 19b7c91a..2c48105f 100644 ---- a/sshd_config -+++ b/sshd_config +Index: openssh-9.6p1/sshd_config +=================================================================== +--- openssh-9.6p1.orig/sshd_config ++++ openssh-9.6p1/sshd_config @@ -69,6 +69,8 @@ AuthorizedKeysFile .ssh/authorized_keys # GSSAPI options #GSSAPIAuthentication no @@ -3772,11 +3820,11 @@ index 19b7c91a..2c48105f 100644 # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will -diff --git a/sshd_config.5 b/sshd_config.5 -index 70ccea44..f6b41a2f 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -646,6 +646,11 @@ Specifies whether to automatically destroy the user's credentials cache +Index: openssh-9.6p1/sshd_config.5 +=================================================================== +--- openssh-9.6p1.orig/sshd_config.5 ++++ openssh-9.6p1/sshd_config.5 +@@ -733,6 +733,11 @@ Specifies whether to automatically destr on logout. The default is .Cm yes . @@ -3788,7 +3836,7 @@ index 70ccea44..f6b41a2f 100644 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -660,6 +665,32 @@ machine's default store. +@@ -747,6 +752,31 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Cm yes . @@ -3815,79 +3863,20 @@ index 70ccea44..f6b41a2f 100644 +.Ed +.Pp +The default is -+.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, -+gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . -+This option only applies to connections using GSSAPI. ++.Dq gss-gex-sha1-,gss-group14-sha1- . ++This option only applies to protocol version 2 connections using GSSAPI. .It Cm HostbasedAcceptedAlgorithms Specifies the signature algorithms that will be accepted for hostbased authentication as a list of comma-separated patterns. -diff --git a/sshkey.c b/sshkey.c -index 57995ee6..fd5b7724 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -127,6 +127,75 @@ static const struct keytype keytypes[] = { +Index: openssh-9.6p1/sshkey.c +=================================================================== +--- openssh-9.6p1.orig/sshkey.c ++++ openssh-9.6p1/sshkey.c +@@ -128,6 +128,17 @@ extern const struct sshkey_impl sshkey_d 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 *) -+{ -+ return SSH_ERR_FEATURE_UNSUPPORTED; -+} -+ -+static int ssh_gss_serialize_public(const struct sshkey *, struct sshbuf *, -+ enum sshkey_serialize_rep) -+{ -+ return SSH_ERR_FEATURE_UNSUPPORTED; -+} -+ -+static int ssh_gss_deserialize_public(const char *, struct sshbuf *, -+ struct sshkey *) -+{ -+ return SSH_ERR_FEATURE_UNSUPPORTED; -+} -+ -+static int ssh_gss_serialize_private(const struct sshkey *, struct sshbuf *, -+ enum sshkey_serialize_rep) -+{ -+ return SSH_ERR_FEATURE_UNSUPPORTED; -+} -+ -+static int ssh_gss_deserialize_private(const char *, struct sshbuf *, -+ struct sshkey *) -+{ -+ return SSH_ERR_FEATURE_UNSUPPORTED; -+} -+ -+static int ssh_gss_copy_public(const struct sshkey *, struct sshkey *) -+{ -+ return SSH_ERR_FEATURE_UNSUPPORTED; -+} -+ -+static int ssh_gss_verify(const struct sshkey *, const u_char *, size_t, -+ const u_char *, size_t, const char *, u_int, -+ struct sshkey_sig_details **) -+{ -+ return SSH_ERR_FEATURE_UNSUPPORTED; -+} -+ -+static const struct sshkey_impl_funcs sshkey_gss_funcs = { -+ /* .size = */ NULL, -+ /* .alloc = */ NULL, -+ /* .cleanup = */ NULL, -+ /* .equal = */ ssh_gss_equal, -+ /* .ssh_serialize_public = */ ssh_gss_serialize_public, -+ /* .ssh_deserialize_public = */ ssh_gss_deserialize_public, -+ /* .ssh_serialize_private = */ ssh_gss_serialize_private, -+ /* .ssh_deserialize_private = */ ssh_gss_deserialize_private, -+ /* .generate = */ NULL, -+ /* .copy_public = */ ssh_gss_copy_public, -+ /* .sign = */ NULL, -+ /* .verify = */ ssh_gss_verify, -+}; -+ -+/* The struct is intentionally dummy and has no gss calls */ -+static const struct sshkey_impl sshkey_gss_kex_impl = { ++const struct sshkey_impl sshkey_null_impl = { + /* .name = */ "null", + /* .shortname = */ "null", + /* .sigalg = */ NULL, @@ -3895,21 +3884,21 @@ index 57995ee6..fd5b7724 100644 + /* .nid = */ 0, + /* .cert = */ 0, + /* .sigonly = */ 0, -+ /* .keybits = */ 0, /* FIXME */ -+ /* .funcs = */ &sshkey_gss_funcs, ++ /* .keybits = */ 0, ++ /* .funcs = */ NULL, +}; const struct sshkey_impl * const keyimpls[] = { &sshkey_ed25519_impl, -@@ -154,6 +154,7 @@ static const struct keytype keytypes[] = { +@@ -165,6 +176,7 @@ const struct sshkey_impl * const keyimpl &sshkey_xmss_impl, &sshkey_xmss_cert_impl, #endif -+ &sshkey_gss_kex_impl, ++ &sshkey_null_impl, NULL }; -@@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -320,7 +332,7 @@ sshkey_alg_list(int certs_only, int plai for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -3918,11 +3907,11 @@ index 57995ee6..fd5b7724 100644 continue; if (!include_sigonly && impl->sigonly) continue; -diff --git a/sshkey.h b/sshkey.h -index 71a3fddc..37a43a67 100644 ---- a/sshkey.h -+++ b/sshkey.h -@@ -69,6 +69,7 @@ enum sshkey_types { +Index: openssh-9.6p1/sshkey.h +=================================================================== +--- openssh-9.6p1.orig/sshkey.h ++++ openssh-9.6p1/sshkey.h +@@ -71,6 +71,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, KEY_ED25519_SK_CERT, @@ -3930,24 +3919,14 @@ index 71a3fddc..37a43a67 100644 KEY_UNSPEC }; -diff --git a/packet.h b/packet.h ---- a/packet.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/packet.h (date 1703172586447) -@@ -124,6 +124,7 @@ - int ssh_packet_send2(struct ssh *); - - int ssh_packet_read(struct ssh *); -+int ssh_packet_read_expect(struct ssh *, u_int type); - int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); - int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); - int ssh_packet_process_read(struct ssh *, int); -diff --git a/packet.c b/packet.c ---- a/packet.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) -+++ b/packet.c (date 1703172586447) -@@ -1425,6 +1416,29 @@ +Index: openssh-9.6p1/packet.c +=================================================================== +--- openssh-9.6p1.orig/packet.c ++++ openssh-9.6p1/packet.c +@@ -1425,6 +1425,29 @@ ssh_packet_read(struct ssh *ssh) return type; } - + +/* + * Waits until a packet has been received, verifies that its type matches + * that given, and gives a fatal error and exits if there is a mismatch. @@ -3974,3 +3953,15 @@ diff --git a/packet.c b/packet.c static int ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { +Index: openssh-9.6p1/packet.h +=================================================================== +--- openssh-9.6p1.orig/packet.h ++++ openssh-9.6p1/packet.h +@@ -124,6 +124,7 @@ int ssh_packet_send2_wrapped(struct ssh + int ssh_packet_send2(struct ssh *); + + int ssh_packet_read(struct ssh *); ++int ssh_packet_read_expect(struct ssh *, u_int type); + int ssh_packet_read_poll(struct ssh *); + int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); + int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); diff --git a/openssh-8.1p1-audit.patch b/openssh-8.1p1-audit.patch index 04c8026..6479633 100644 --- a/openssh-8.1p1-audit.patch +++ b/openssh-8.1p1-audit.patch @@ -236,7 +236,7 @@ Index: openssh-8.9p1/audit-linux.c /* Below is the sshd audit API code */ void -@@ -76,49 +176,211 @@ audit_connection_from(const char *host, +@@ -76,49 +176,210 @@ audit_connection_from(const char *host, /* not implemented */ } @@ -315,7 +315,6 @@ Index: openssh-8.9p1/audit-linux.c case SSH_AUTH_FAIL_PASSWD: + if (options.use_pam) + break; -+ /* Fallthrough */ + case SSH_LOGIN_EXCEED_MAXTRIES: case SSH_AUTH_FAIL_KBDINT: case SSH_AUTH_FAIL_PUBKEY: @@ -452,7 +451,7 @@ Index: openssh-8.9p1/audit-linux.c + } + audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, + buf, NULL, -+ ssh_remote_ipaddr(ssh), /*FIXME listening_for_clients() ? NULL : ssh_remote_ipaddr(ssh) */ ++ listening_for_clients() ? NULL : ssh_remote_ipaddr(ssh), + NULL, 1); + audit_close(audit_fd); + /* do not abort if the error is EPERM and sshd is run as non root user */ @@ -519,19 +518,19 @@ Index: openssh-8.9p1/audit.c +void +audit_unsupported(struct ssh *ssh, int what) +{ -+ mm_audit_unsupported_body(ssh, what); ++ PRIVSEP(audit_unsupported_body(ssh, what)); +} + +void +audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs) +{ -+ mm_audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid()); ++ PRIVSEP(audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid())); +} + +void +audit_session_key_free(struct ssh *ssh, int ctos) +{ -+ mm_audit_session_key_free_body(ssh, ctos, getpid(), getuid()); ++ PRIVSEP(audit_session_key_free_body(ssh, ctos, getpid(), getuid())); +} + # ifndef CUSTOM_SSH_AUDIT_EVENTS @@ -779,18 +778,18 @@ Index: openssh-8.9p1/auth.h + const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); /* Key / cert options linkage to auth layer */ - int auth_activate_options(struct ssh *, struct sshauthopt *); + const struct sshauthopt *auth_options(struct ssh *); Index: openssh-8.9p1/auth2-hostbased.c =================================================================== --- openssh-8.9p1.orig/auth2-hostbased.c +++ openssh-8.9p1/auth2-hostbased.c @@ -149,7 +149,7 @@ userauth_hostbased(struct ssh *ssh, cons authenticated = 0; - if (mm_hostbased_key_allowed(ssh, authctxt->pw, cuser, - chost, key) && -- mm_sshkey_verify(key, sig, slen, -+ mm_hostbased_key_verify(ssh, key, sig, slen, - sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL) == 0) + if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser, + chost, key)) && +- PRIVSEP(sshkey_verify(key, sig, slen, ++ PRIVSEP(hostbased_key_verify(ssh, key, sig, slen, + sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0) authenticated = 1; @@ -166,6 +166,19 @@ done: @@ -820,12 +819,12 @@ Index: openssh-8.9p1/auth2-pubkey.c @@ -223,7 +223,7 @@ userauth_pubkey(struct ssh *ssh, const c /* test for correct signature */ authenticated = 0; - if (mm_user_key_allowed(ssh, pw, key, 1, &authopts) && -- mm_sshkey_verify(key, sig, slen, -+ mm_user_key_verify(ssh, key, sig, slen, + if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && +- PRIVSEP(sshkey_verify(key, sig, slen, ++ PRIVSEP(user_key_verify(ssh, key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, - ssh->compat, &sig_details) == 0) { + ssh->compat, &sig_details)) == 0) { @@ -316,6 +316,19 @@ done: return authenticated; } @@ -855,7 +854,7 @@ Index: openssh-8.9p1/auth2.c /* Invalid user, fake password information */ authctxt->pw = fakepw(); -#ifdef SSH_AUDIT_EVENTS -- mm_audit_event(ssh, SSH_INVALID_USER); +- PRIVSEP(audit_event(ssh, SSH_INVALID_USER)); -#endif } #ifdef USE_PAM @@ -940,8 +939,8 @@ Index: openssh-8.9p1/kex.c #include "xmalloc.h" +#include "audit.h" - /* prototype */ - static int kex_choose_conf(struct ssh *, uint32_t seq); + #ifdef GSSAPI + #include "ssh-gss.h" @@ -879,12 +880,16 @@ kex_start_rekex(struct ssh *ssh) } @@ -1125,7 +1124,7 @@ Index: openssh-8.9p1/monitor.c extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ -+extern void destroy_sensitive_data(struct ssh *); ++extern void destroy_sensitive_data(struct ssh *, int); + /* State exported from the child */ static struct sshbuf *child_state; @@ -1258,7 +1257,7 @@ Index: openssh-8.9p1/monitor.c sshpam_cleanup(); #endif -+ destroy_sensitive_data(ssh); ++ destroy_sensitive_data(ssh, 0); + while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) @@ -1302,12 +1301,12 @@ Index: openssh-8.9p1/monitor.c + debug3("%s entering", __func__); + if ((r = sshbuf_get_u32(m, &handle)) != 0 || + (r = sshbuf_get_string(m, &cmd, &len)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + s = session_by_id(handle); + if (s == NULL || s->ttyfd != -1 || s->command == NULL || + strcmp(s->command, cmd) != 0) -+ fatal_f("invalid handle"); ++ fatal("%s: invalid handle", __func__); + mm_session_close(ssh, s); free(cmd); return (0); @@ -1350,7 +1349,7 @@ Index: openssh-8.9p1/monitor.c + int what, r; + + if ((r = sshbuf_get_u32(m, &what)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + audit_unsupported_body(ssh, what); + @@ -1375,10 +1374,10 @@ Index: openssh-8.9p1/monitor.c + (r = sshbuf_get_cstring(m, &compress, NULL)) != 0 || + (r = sshbuf_get_cstring(m, &pfs, NULL)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + uid = (pid_t) tmp; + + audit_kex_body(ssh, ctos, cipher, mac, compress, pfs, pid, uid); @@ -1403,10 +1402,10 @@ Index: openssh-8.9p1/monitor.c + + if ((r = sshbuf_get_u32(m, &ctos)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + uid = (uid_t) tmp; + + audit_session_key_free_body(ssh, ctos, pid, uid); @@ -1428,10 +1427,10 @@ Index: openssh-8.9p1/monitor.c + + if ((r = sshbuf_get_cstring(m, &fp, &len)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + uid = (uid_t) tmp; + + audit_destroy_sensitive_data(ssh, fp, pid, uid); @@ -1527,7 +1526,7 @@ Index: openssh-8.9p1/monitor_wrap.c + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, m); + + if ((r = sshbuf_get_u32(m, &handle)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + sshbuf_free(m); + + return (handle); @@ -1542,19 +1541,19 @@ Index: openssh-8.9p1/monitor_wrap.c + debug3("%s entering command %s", __func__, command); + + if ((m = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u32(m, handle)) != 0 || + (r = sshbuf_put_cstring(m, command)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, m); sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1217,3 +1257,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc - return &ci; +@@ -1074,3 +1114,130 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc } + #endif /* GSSAPI */ +#ifdef SSH_AUDIT_EVENTS +void +mm_audit_unsupported_body(struct ssh *ssh, int what) @@ -1563,9 +1562,9 @@ Index: openssh-8.9p1/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u32(m, what)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED, @@ -1582,7 +1581,7 @@ Index: openssh-8.9p1/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u32(m, ctos)) != 0 || + (r = sshbuf_put_cstring(m, cipher)) != 0 || + (r = sshbuf_put_cstring(m, (mac ? mac : ""))) != 0 || @@ -1590,7 +1589,7 @@ Index: openssh-8.9p1/monitor_wrap.c + (r = sshbuf_put_cstring(m, fps)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX, @@ -1606,11 +1605,11 @@ Index: openssh-8.9p1/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u32(m, ctos)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, @@ -1625,15 +1624,62 @@ Index: openssh-8.9p1/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal_f("sshbuf_new failed"); ++ fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_cstring(m, fp)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal_fr(r, "buffer error"); ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m); + sshbuf_free(m); +} ++ ++int mm_forward_audit_messages(int fdin) ++{ ++ u_char buf[4]; ++ u_int blen, msg_len; ++ struct sshbuf *m; ++ int ret = 0; ++ ++ debug3("%s: entering", __func__); ++ m = sshbuf_new(); ++ do { ++ int r; ++ ++ blen = atomicio(read, fdin, buf, sizeof(buf)); ++ if (blen == 0) /* closed pipe */ ++ break; ++ if (blen != sizeof(buf)) { ++ error("%s: Failed to read the buffer from child", __func__); ++ ret = -1; ++ break; ++ } ++ ++ msg_len = get_u32(buf); ++ if (msg_len > 256 * 1024) ++ fatal("%s: read: bad msg_len %d", __func__, msg_len); ++ sshbuf_reset(m); ++ if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0) ++ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) { ++ error("%s: Failed to read the the buffer conent from the child", __func__); ++ ret = -1; ++ break; ++ } ++ if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen || ++ atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) { ++ error("%s: Failed to write the messag to the monitor", __func__); ++ ret = -1; ++ break; ++ } ++ } while (1); ++ sshbuf_free(m); ++ return ret; ++} ++void mm_set_monitor_pipe(int fd) ++{ ++ pmonitor->m_recvfd = fd; ++} +#endif /* SSH_AUDIT_EVENTS */ Index: openssh-8.9p1/monitor_wrap.h =================================================================== @@ -1649,8 +1695,8 @@ Index: openssh-8.9p1/monitor_wrap.h +int mm_user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t, const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); - void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); -@@ -83,7 +85,12 @@ void mm_sshpam_free_ctx(void *); + #ifdef GSSAPI +@@ -83,7 +85,14 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(struct ssh *, ssh_audit_event_t); @@ -1661,6 +1707,8 @@ Index: openssh-8.9p1/monitor_wrap.h +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); ++int mm_forward_audit_messages(int); ++void mm_set_monitor_pipe(int); #endif struct Session; @@ -1690,7 +1738,12 @@ Index: openssh-8.9p1/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -579,22 +587,19 @@ ssh_packet_rdomain_in(struct ssh *ssh) +@@ -579,26 +587,23 @@ ssh_packet_rdomain_in(struct ssh *ssh) + /* Closes the connection and clears and frees internal data structures. */ + + static void +-ssh_packet_close_internal(struct ssh *ssh, int do_close) ++ssh_packet_close_internal(struct ssh *ssh, int do_close, int do_audit) { struct session_state *state = ssh->state; u_int mode; @@ -1722,7 +1775,7 @@ Index: openssh-8.9p1/packet.c #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); -+ if (had_keys && state->server_side) { ++ if (do_audit && had_keys && state->server_side) { + /* Assuming this is called only from privsep child */ + audit_session_key_free(ssh, MODE_MAX); + } @@ -1737,6 +1790,28 @@ Index: openssh-8.9p1/packet.c free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); +@@ -650,13 +665,19 @@ ssh_packet_close_internal(struct ssh *ss + void + ssh_packet_close(struct ssh *ssh) + { +- ssh_packet_close_internal(ssh, 1); ++ ssh_packet_close_internal(ssh, 1, 1); + } + + void + ssh_packet_clear_keys(struct ssh *ssh) + { +- ssh_packet_close_internal(ssh, 0); ++ ssh_packet_close_internal(ssh, 0, 1); ++} ++ ++void ++ssh_packet_clear_keys_noaudit(struct ssh *ssh) ++{ ++ ssh_packet_close_internal(ssh, 0, 0); + } + + /* Sets remote side protocol flags. */ @@ -892,6 +913,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod (unsigned long long)state->p_send.bytes, (unsigned long long)state->p_send.blocks); @@ -1745,7 +1820,7 @@ Index: openssh-8.9p1/packet.c state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2183,6 +2205,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2183,6 +2205,73 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1775,8 +1850,9 @@ Index: openssh-8.9p1/packet.c + return; + + cipher_free(state->receive_context); ++ state->receive_context = NULL; + cipher_free(state->send_context); -+ state->send_context = state->receive_context = NULL; ++ state->send_context = NULL; + + sshbuf_free(state->input); + state->input = NULL; @@ -1822,6 +1898,14 @@ Index: openssh-8.9p1/packet.h =================================================================== --- openssh-8.9p1.orig/packet.h +++ openssh-8.9p1/packet.h +@@ -102,6 +102,7 @@ int ssh_packet_get_connection_out(s + void ssh_packet_close(struct ssh *); + void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); + void ssh_packet_clear_keys(struct ssh *); ++void ssh_packet_clear_keys_noaudit(struct ssh *); + void ssh_clear_newkeys(struct ssh *, int); + + int ssh_packet_is_rekeying(struct ssh *); @@ -220,4 +221,5 @@ const u_char *sshpkt_ptr(struct ssh *, s # undef EC_POINT #endif @@ -1837,11 +1921,22 @@ Index: openssh-8.9p1/session.c extern u_int utmp_len; extern int startup_pipe; -extern void destroy_sensitive_data(void); -+extern void destroy_sensitive_data(struct ssh *); ++extern void destroy_sensitive_data(struct ssh *, int); extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; extern char *tun_fwd_ifnames; /* serverloop.c */ -@@ -644,6 +644,14 @@ do_exec_pty(struct ssh *ssh, Session *s, +@@ -157,6 +157,10 @@ static Session *sessions = NULL; + login_cap_t *lc; + #endif + ++#ifdef SSH_AUDIT_EVENTS ++int paudit[2]; ++#endif ++ + static int is_child = 0; + static int in_chroot = 0; + +@@ -642,6 +646,14 @@ do_exec_pty(struct ssh *ssh, Session *s, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1856,42 +1951,85 @@ Index: openssh-8.9p1/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; ssh_packet_set_interactive(ssh, 1, -@@ -736,15 +744,19 @@ do_exec(struct ssh *ssh, Session *s, con +@@ -706,15 +718,21 @@ do_exec(struct ssh *ssh, Session *s, con s->self); #ifdef SSH_AUDIT_EVENTS + if (s->command != NULL || s->command_handle != -1) + fatal("do_exec: command already set"); if (command != NULL) -- mm_audit_run_command(command); +- PRIVSEP(audit_run_command(command)); + s->command = xstrdup(command); else if (s->ttyfd == -1) { char *shell = s->pw->pw_shell; if (shell[0] == '\0') /* empty shell means /bin/sh */ shell =_PATH_BSHELL; -- mm_audit_run_command(shell); +- PRIVSEP(audit_run_command(shell)); + s->command = xstrdup(shell); } + if (s->command != NULL && s->ptyfd == -1) -+ s->command_handle = mm_audit_run_command(ssh, s->command); ++ s->command_handle = PRIVSEP(audit_run_command(ssh, s->command)); ++ if (pipe(paudit) < 0) ++ fatal("pipe: %s", strerror(errno)); #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1550,8 +1562,11 @@ do_child(struct ssh *ssh, Session *s, co +@@ -730,6 +748,20 @@ do_exec(struct ssh *ssh, Session *s, con + */ + sshbuf_reset(loginmsg); + ++#ifdef SSH_AUDIT_EVENTS ++ close(paudit[1]); ++ if (use_privsep && ret == 0) { ++ /* ++ * Read the audit messages from forked child and send them ++ * back to monitor. We don't want to communicate directly, ++ * because the messages might get mixed up. ++ * Continue after the pipe gets closed (all messages sent). ++ */ ++ ret = mm_forward_audit_messages(paudit[0]); ++ } ++ close(paudit[0]); ++#endif /* SSH_AUDIT_EVENTS */ ++ + return ret; + } + +@@ -1530,11 +1562,30 @@ do_child(struct ssh *ssh, Session *s, co + int env_size; + int r = 0; + ++#ifdef SSH_AUDIT_EVENTS ++ int pparent = paudit[1]; ++ close(paudit[0]); ++ /* Hack the monitor pipe to avoid race condition with parent */ ++ if (use_privsep) ++ mm_set_monitor_pipe(pparent); ++#endif ++ sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); /* remove hostkey from the child's memory */ - destroy_sensitive_data(); -+ destroy_sensitive_data(ssh); - ssh_packet_clear_keys(ssh); -+ /* Don't audit this - both us and the parent would be talking to the -+ monitor over a single socket, with no synchronization. */ +- ssh_packet_clear_keys(ssh); ++ destroy_sensitive_data(ssh, use_privsep); ++ ssh_packet_clear_keys_noaudit(ssh); ++ /* ++ * We can audit this, because we hacked the pipe to direct the ++ * messages over postauth child. But this message requires an answer ++ * which we can't do using a one-way pipe. ++ */ + packet_destroy_all(ssh, 0, 1); ++ ++#ifdef SSH_AUDIT_EVENTS ++ /* Notify parent that we are done */ ++ close(pparent); ++#endif /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1763,6 +1778,9 @@ session_unused(int id) +@@ -1743,6 +1794,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1901,7 +2039,7 @@ Index: openssh-8.9p1/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1843,6 +1861,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1822,6 +1876,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1912,7 +2050,7 @@ Index: openssh-8.9p1/session.c + if (s->used) + return s; + } -+ debug_f("unknown id %d", id); ++ debug("%s: unknown id %d", __func__, id); + session_dump(); + return NULL; +} @@ -1921,7 +2059,7 @@ Index: openssh-8.9p1/session.c session_by_tty(char *tty) { int i; -@@ -2450,6 +2481,32 @@ session_exit_message(struct ssh *ssh, Se +@@ -2429,6 +2496,32 @@ session_exit_message(struct ssh *ssh, Se chan_write_failed(ssh, c); } @@ -1943,7 +2081,7 @@ Index: openssh-8.9p1/session.c +{ + if (s->command != NULL) { + if (s->command_handle != -1) -+ mm_audit_end_command(ssh, s->command_handle, s->command); ++ PRIVSEP(audit_end_command(ssh, s->command_handle, s->command)); + free(s->command); + s->command = NULL; + s->command_handle = -1; @@ -1954,7 +2092,7 @@ Index: openssh-8.9p1/session.c void session_close(struct ssh *ssh, Session *s) { -@@ -2463,6 +2520,10 @@ session_close(struct ssh *ssh, Session * +@@ -2470,6 +2563,10 @@ session_close(struct ssh *ssh, Session * if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1965,7 +2103,7 @@ Index: openssh-8.9p1/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2537,14 +2598,14 @@ session_close_by_channel(struct ssh *ssh +@@ -2544,14 +2641,14 @@ session_close_by_channel(struct ssh *ssh } void @@ -1982,7 +2120,7 @@ Index: openssh-8.9p1/session.c else session_close(ssh, s); } -@@ -2671,6 +2732,15 @@ do_authenticated2(struct ssh *ssh, Authc +@@ -2677,6 +2774,15 @@ do_authenticated2(struct ssh *ssh, Authc server_loop2(ssh, authctxt); } @@ -1998,10 +2136,10 @@ Index: openssh-8.9p1/session.c void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2734,7 +2804,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au +@@ -2740,7 +2846,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au * or if running in monitor. */ - if (mm_is_monitor()) + if (!use_privsep || mm_is_monitor()) - session_destroy_all(ssh, session_pty_cleanup2); + session_destroy_all(ssh, do_cleanup_one_session); } @@ -2042,34 +2180,6 @@ Index: openssh-8.9p1/sshd.c =================================================================== --- openssh-8.9p1.orig/sshd.c +++ openssh-8.9p1/sshd.c -@@ -219,6 +219,15 @@ close_listen_socks(void) - num_listen_socks = 0; - } - -+/* -+ * Is this process listening for clients (i.e. not specific to any specific -+ * client connection?) -+ */ -+int listening_for_clients(void) -+{ -+ return num_listen_socks > 0; -+} -+ - /* Allocate and initialise the children array */ - static void - child_alloc(void) -@@ -897,6 +906,7 @@ server_accept_loop(int *sock_in, int *so - if (received_sigterm) { - logit("Received signal %d; terminating.", - (int) received_sigterm); -+ /* destroy_sensitive_data(ssh, 0); FIXME */ - close_listen_socks(); - if (options.pid_file != NULL) - unlink(options.pid_file); -Index: openssh-8.9p1/sshd-session.c -=================================================================== ---- openssh-8.9p1.orig/sshd-session.c -+++ openssh-8.9p1/sshd-session.c @@ -125,6 +125,7 @@ #include "ssh-gss.h" #endif @@ -2079,18 +2189,34 @@ Index: openssh-8.9p1/sshd-session.c #include "auth-options.h" #include "version.h" @@ -265,8 +266,8 @@ struct sshbuf *loginmsg; - struct sshbuf *loginmsg; + struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ -void destroy_sensitive_data(void); -void demote_sensitive_data(void); -+void destroy_sensitive_data(struct ssh *); ++void destroy_sensitive_data(struct ssh *, int); +void demote_sensitive_data(struct ssh *); static void do_ssh2_kex(struct ssh *); - /* -@@ -382,18 +383,40 @@ grace_alarm_handler(int sig) - _exit(EXIT_LOGIN_GRACE); + static char *listener_proctitle; +@@ -284,6 +285,15 @@ close_listen_socks(void) + num_listen_socks = 0; + } + ++/* ++ * Is this process listening for clients (i.e. not specific to any specific ++ * client connection?) ++ */ ++int listening_for_clients(void) ++{ ++ return num_listen_socks >= 0; ++} ++ + static void + close_startup_pipes(void) + { +@@ -382,18 +392,45 @@ grace_alarm_handler(int sig) + ssh_remote_port(the_active_state)); } -/* Destroy the host and server keys. They will no longer be needed. */ @@ -2100,7 +2226,7 @@ Index: openssh-8.9p1/sshd-session.c + */ void -destroy_sensitive_data(void) -+destroy_sensitive_data(struct ssh *ssh) ++destroy_sensitive_data(struct ssh *ssh, int privsep) { u_int i; +#ifdef SSH_AUDIT_EVENTS @@ -2122,7 +2248,12 @@ Index: openssh-8.9p1/sshd-session.c sensitive_data.host_keys[i] = NULL; + if (fp != NULL) { +#ifdef SSH_AUDIT_EVENTS -+ audit_destroy_sensitive_data(ssh, fp, pid, uid); ++ if (privsep) ++ PRIVSEP(audit_destroy_sensitive_data(ssh, fp, ++ pid, uid)); ++ else ++ audit_destroy_sensitive_data(ssh, fp, ++ pid, uid); +#endif + free(fp); + } @@ -2133,7 +2264,7 @@ Index: openssh-8.9p1/sshd-session.c sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -402,20 +430,38 @@ destroy_sensitive_data(void) +@@ -402,20 +439,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2173,7 +2304,7 @@ Index: openssh-8.9p1/sshd-session.c } /* Certs do not need demotion */ } -@@ -443,7 +489,7 @@ reseed_prngs(void) +@@ -443,7 +498,7 @@ reseed_prngs(void) } static void @@ -2182,7 +2313,7 @@ Index: openssh-8.9p1/sshd-session.c { gid_t gidset[1]; -@@ -458,7 +504,7 @@ privsep_preauth_child(void) +@@ -458,7 +513,7 @@ privsep_preauth_child(void) reseed_prngs(); /* Demote the private keys to public keys. */ @@ -2191,16 +2322,16 @@ Index: openssh-8.9p1/sshd-session.c /* Demote the child */ if (privsep_chroot) { -@@ -493,7 +539,7 @@ privsep_preauth(struct ssh *ssh) - pmonitor->m_pkex = &ssh->kex; +@@ -493,7 +548,7 @@ privsep_preauth(struct ssh *ssh) - box = ssh_sandbox_init(pmonitor); + if (use_privsep == PRIVSEP_ON) + box = ssh_sandbox_init(pmonitor); - pid = fork(); + pmonitor->m_pid = pid = fork(); if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -538,7 +584,7 @@ privsep_preauth(struct ssh *ssh) +@@ -538,7 +593,7 @@ privsep_preauth(struct ssh *ssh) /* Arrange for logging to be sent to the monitor */ set_log_handler(mm_log_handler, pmonitor); @@ -2209,7 +2340,7 @@ Index: openssh-8.9p1/sshd-session.c setproctitle("%s", "[net]"); if (box != NULL) ssh_sandbox_child(box); -@@ -582,7 +628,7 @@ privsep_postauth(struct ssh *ssh, Authct +@@ -582,7 +637,7 @@ privsep_postauth(struct ssh *ssh, Authct pmonitor->m_sendfd = -1; /* Demote the private keys to public keys. */ @@ -2218,17 +2349,43 @@ Index: openssh-8.9p1/sshd-session.c reseed_prngs(); -@@ -2311,6 +2358,9 @@ main(int ac, char **av) +@@ -1136,7 +1191,7 @@ server_listen(void) + * from this function are in a forked subprocess. + */ + static void +-server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) ++server_accept_loop(struct ssh *ssh, int *sock_in, int *sock_out, int *newsock, int *config_s) + { + struct pollfd *pfd = NULL; + int i, j, ret, npfd; +@@ -1179,6 +1234,7 @@ server_accept_loop(int *sock_in, int *so + if (received_sigterm) { + logit("Received signal %d; terminating.", + (int) received_sigterm); ++ destroy_sensitive_data(ssh, 0); + close_listen_socks(); + if (options.pid_file != NULL) + unlink(options.pid_file); +@@ -2088,7 +2144,7 @@ main(int ac, char **av) + #endif + + /* Accept a connection and return in a forked child */ +- server_accept_loop(&sock_in, &sock_out, ++ server_accept_loop(ssh, &sock_in, &sock_out, + &newsock, config_s); + } + +@@ -2311,6 +2367,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ + packet_destroy_all(ssh, 1, 1); -+ destroy_sensitive_data(ssh); ++ destroy_sensitive_data(ssh, 1); + ssh_packet_get_bytes(ssh, &ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2491,6 +2541,15 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2491,6 +2550,15 @@ do_ssh2_kex(struct ssh *ssh) void cleanup_exit(int i) { @@ -2241,17 +2398,24 @@ Index: openssh-8.9p1/sshd-session.c + if (in_cleanup) + _exit(i); + in_cleanup = 1; - extern int auth_attempted; /* monitor.c */ - if (the_active_state != NULL && the_authctxt != NULL) { -@@ -2525,7 +2593,9 @@ cleanup_exit(int i) - _exit(EXIT_AUTH_ATTEMPTED); + do_cleanup(the_active_state, the_authctxt); + if (use_privsep && privsep_is_preauth && +@@ -2503,9 +2571,16 @@ cleanup_exit(int i) + } + } + } ++ is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0; ++ if (sensitive_data.host_keys != NULL && the_active_state != NULL) ++ destroy_sensitive_data(the_active_state, is_privsep_child); ++ if (the_active_state != NULL) ++ packet_destroy_all(the_active_state, 1, is_privsep_child); #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ -- if (the_active_state != NULL && mm_is_monitor()) -+ if (the_active_state != NULL && -+ (the_authctxt == NULL || !the_authctxt->authenticated) && -+ mm_is_monitor()) +- if (the_active_state != NULL && (!use_privsep || mm_is_monitor())) ++ if (the_active_state != NULL && ++ (the_authctxt == NULL || !the_authctxt->authenticated) && ++ (!use_privsep || mm_is_monitor())) audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif _exit(i); diff --git a/openssh-8.4p1-vendordir.patch b/openssh-8.4p1-vendordir.patch index 60644db..3b38457 100644 --- a/openssh-8.4p1-vendordir.patch +++ b/openssh-8.4p1-vendordir.patch @@ -123,21 +123,28 @@ Index: openssh-8.9p1/sshd.c =================================================================== --- openssh-8.9p1.orig/sshd.c +++ openssh-8.9p1/sshd.c -@@ -1201,7 +1201,8 @@ prepare_proctitle(int ac, char **av) +@@ -148,7 +148,7 @@ extern char *__progname; + ServerOptions options; + + /* Name of the server configuration file. */ +-char *config_file_name = _PATH_SERVER_CONFIG_FILE; ++char *config_file_name = NULL; + + /* + * Debug mode flag. This can be set on the command line. If debug +@@ -1591,6 +1591,7 @@ prepare_proctitle(int ac, char **av) + int + main(int ac, char **av) + { ++ struct stat st; + struct ssh *ssh = NULL; extern char *optarg; extern int optind; - int log_stderr = 0, inetd_flag = 0, test_flag = 0, no_daemon_flag = 0; -- char *config_file_name = _PATH_SERVER_CONFIG_FILE; -+ char *config_file_name = NULL; -+ struct stat st; - int r, opt, do_dump_cfg = 0, keytype, already_daemon, have_agent = 0; - int sock_in = -1, sock_out = -1, newsock = -1, rexec_argc = 0; - int devnull, config_s[2] = { -1 , -1 }, have_connection_info = 0; @@ -1806,7 +1807,21 @@ main(int ac, char **av) - /* Fetch our configuration */ - if ((cfg = sshbuf_new()) == NULL) - fatal("sshbuf_new config failed"); -+ if (config_file_name == NULL) { + */ + (void)atomicio(vwrite, startup_pipe, "\0", 1); + } ++ } else if (config_file_name == NULL) { + /* If only the vendor configuration file exists, use that. + * Else use the standard configuration file. + */ @@ -150,12 +157,11 @@ Index: openssh-8.9p1/sshd.c + config_file_name = _PATH_SERVER_CONFIG_FILE; + } + load_server_config(config_file_name, cfg); -- if (strcasecmp(config_file_name, "none") != 0) -+ } else if (strcasecmp(config_file_name, "none") != 0) + } else if (strcasecmp(config_file_name, "none") != 0) + /* load config specified on commandline */ load_server_config(config_file_name, cfg); - parse_server_config(&options, config_file_name, cfg, + parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, Index: openssh-8.9p1/sshd_config.5 =================================================================== --- openssh-8.9p1.orig/sshd_config.5 diff --git a/openssh-9.6p1-crypto-policies-man.patch b/openssh-9.6p1-crypto-policies-man.patch index 9e8ace8..5c386f0 100644 --- a/openssh-9.6p1-crypto-policies-man.patch +++ b/openssh-9.6p1-crypto-policies-man.patch @@ -84,14 +84,13 @@ Index: openssh-9.6p1/ssh_config.5 The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are .Bd -literal -offset 3n -@@ -991,10 +993,8 @@ gss-nistp256-sha256-, +@@ -991,9 +993,8 @@ gss-nistp256-sha256-, gss-curve25519-sha256- .Ed .Pp -The default is --.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, --gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . - This option only applies to connections using GSSAPI. +-.Dq gss-gex-sha1-,gss-group14-sha1- . + This option only applies to protocol version 2 connections using GSSAPI. +.Pp .It Cm HashKnownHosts Indicates that @@ -160,7 +159,7 @@ Index: openssh-9.6p1/ssh_config.5 .It Cm HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key -@@ -1311,36 +1313,30 @@ it may be zero or more of: +@@ -1311,31 +1313,26 @@ it may be zero or more of: and .Cm pam . .It Cm KexAlgorithms @@ -170,12 +169,8 @@ Index: openssh-9.6p1/ssh_config.5 +existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp - Specifies the permitted KEX (Key Exchange) algorithms that will be used and - their preference order. - The selected algorithm will the the first algorithm in this list that - the server also supports. + Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. - .Pp If the specified list begins with a .Sq + -character, then the specified algorithms will be appended to the default set @@ -191,7 +186,6 @@ Index: openssh-9.6p1/ssh_config.5 .Sq ^ character, then the specified algorithms will be placed at the head of the -default set. --.Pp -The default is: -.Bd -literal -offset indent -sntrup761x25519-sha512@openssh.com, @@ -205,7 +199,7 @@ Index: openssh-9.6p1/ssh_config.5 -.Ed +built-in openssh default set. .Pp - The list of supported key exchange algorithms may also be obtained using + The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . @@ -1445,37 +1442,34 @@ function, and all code in the file. @@ -392,7 +386,7 @@ Index: openssh-9.6p1/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -764,53 +760,45 @@ For this to work +@@ -764,52 +760,45 @@ For this to work .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -421,9 +415,8 @@ Index: openssh-9.6p1/sshd_config.5 .Ed -.Pp -The default is --.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, --gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . - This option only applies to connections using GSSAPI. +-.Dq gss-gex-sha1-,gss-group14-sha1- . + This option only applies to protocol version 2 connections using GSSAPI. .It Cm HostbasedAcceptedAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . @@ -499,7 +492,7 @@ Index: openssh-9.6p1/sshd_config.5 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -1027,24 +1006,30 @@ file on logout. +@@ -1027,20 +1006,26 @@ file on logout. The default is .Cm yes . .It Cm KexAlgorithms @@ -509,13 +502,9 @@ Index: openssh-9.6p1/sshd_config.5 +existing policies with sub-policies are present in manual page +.Xr update-crypto-policies 8 . +.Pp - 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 - preference order. + Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. - .Pp - If the specified list begins with a + Alternately if the specified list begins with a .Sq + -character, then the specified algorithms will be appended to the default set -instead of replacing them. @@ -531,9 +520,9 @@ Index: openssh-9.6p1/sshd_config.5 character, then the specified algorithms will be placed at the head of the -default set. +built-in openssh default set. - .Pp The supported algorithms are: .Pp + .Bl -item -compact -offset indent @@ -1072,16 +1057,6 @@ ecdh-sha2-nistp521 sntrup761x25519-sha512@openssh.com .El @@ -548,7 +537,7 @@ Index: openssh-9.6p1/sshd_config.5 -diffie-hellman-group14-sha256,diffie-hellman-group14-sha1 -.Ed -.Pp - The list of supported key exchange algorithms may also be obtained using + The list of available key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress @@ -1167,21 +1142,27 @@ function, and all code in the diff --git a/openssh-9.6p1.tar.gz b/openssh-9.6p1.tar.gz new file mode 100644 index 0000000..d753ff2 --- /dev/null +++ b/openssh-9.6p1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:910211c07255a8c5ad654391b40ee59800710dd8119dd5362de09385aa7a777c +size 1857862 diff --git a/openssh-9.6p1.tar.gz.asc b/openssh-9.6p1.tar.gz.asc new file mode 100644 index 0000000..1b20242 --- /dev/null +++ b/openssh-9.6p1.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmWAXvAACgkQKj9BTnNg +YLrypA/6A1O8e80XnzVWIFhXkbv/biGL10Q5ZMvjQvND6mbkphNWZ4G4QOEh0nBG +rseD3Fce7me9pfeLYVhaNXO9R3OYAXxjbWfQwI7FpBU4QUCnbH53PG32B6ESq7pl +0vlDqdqI7aBAyMpp+8WFD+EvHWUVA77JtfU4MFw7myKJacrVrDUygDaZkJKOhqKf +N1Nurz4YppdQ5zIK1ElL0jlRJXm08flLFRg8fD5/5rwabpUbZIY9b5qZzGKgnR7I +sxUBlDkfLnvKIlKzUXbRvOHazvFAHYH1ltJZGlJUc/+H/ZaPigWf4IR+E1FB9c2O +zxaZhlbwGKyD+p7l08F9n8T21taxpBCW1Uxkx7MLTz8k9huPNpdX5l8VM4Gotmn8 +I4V3Fevyx+M3XJYeKtkspa51h0GqF3gNFPLxW7ERGaIuqwoxuHxIEKwYE+JPmQag +UDma5LDrSrasa8Rw8g5urGE48PeDQ5muPy8Bi9eIGZU5JLqX6TNgz7QDDs/dQsHB +iny4wQOLmdIA78IGttiCo0rqikEvFtFDFR4mCUTC8K0nQKzWwGewO3gRTcHttzyU +xMalxw+wt9cUJ8gb1E9p7OeMUuXdaHMmem8/PcFCar/vKx1mdV/On6evnp3P8yQA +la8WnbcP0+zJg0GGwGszpFlOMjWCDB0kUTBCT+MR+IWbj/pVZVA= +=G9YA +-----END PGP SIGNATURE----- diff --git a/openssh-9.8p1.tar.gz b/openssh-9.8p1.tar.gz deleted file mode 100644 index 01ee7b2..0000000 --- a/openssh-9.8p1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dd8bd002a379b5d499dfb050dd1fa9af8029e80461f4bb6c523c49973f5a39f3 -size 1910393 diff --git a/openssh-9.8p1.tar.gz.asc b/openssh-9.8p1.tar.gz.asc deleted file mode 100644 index c55f019..0000000 --- a/openssh-9.8p1.tar.gz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmaCMn0ACgkQKj9BTnNg -YLrjcBAAgO7xhKUXp8YxdqSZigDbcHu7T37bm1pRTKg2ihPepz+q6pV+DY8AHSRu -eyuOCOHYzjLyArFpiMX3z9iT2NqO+KNBvKQoh8loaxNrECmgRGk2jBEKiibFSP5M -i6CYkF3sET9xnVDkt4P6KievWXY1/Tl93qve3K2a/bvvgT8s2AaBMM8u4BMGNm3D -sc3A6euN0aiXRts2V6I885VyrQDMK++E7+eTHet0ex82KH4I+ceIOwB48hny4wpb -Zaqy9pTFisTmFNOF6d3TB58yMWoLQIbLuVrbbbcr7hFYCWsgj0yN5iYQNOR9pU4E -ooF+aC0kK9M4iUXthzjjgIjnMzsCmPeKisbwblsPSfSgccj/pCMzW8C3CMVL6AvG -slSSLK42qm3f38kx3sg2S8LDW0v+hoyvBmKNFMiBwsF2tWCXIG+oP1PDYpJUpaOJ -RFHG7JEPtY94UJGdo5C4YhqDWr3HOqEwuVIt1gWMMPs9IvDkDRo6emmDd64FFAKH -ss3hHixu6OHqU5iw6JIVVtYiur6s9m6N/Xxt5Ho6wuqnzUZ+Dwj3L6lF9IOJbJxU -Ufb70I1Uko9kXcoje9ONUsqr88wfQY+JZxxVTlzDUDadytCzmO3wXsz+cosMQ5Rw -aOZwXYyvmcoZuUQG8GIqRO1wfOcD7o7pI6IyVJQjOeG/rA0eu/4= -=Gj2n ------END PGP SIGNATURE----- diff --git a/openssh-askpass-gnome.changes b/openssh-askpass-gnome.changes index 93e63a2..edbc3d4 100644 --- a/openssh-askpass-gnome.changes +++ b/openssh-askpass-gnome.changes @@ -1,10 +1,3 @@ -------------------------------------------------------------------- -Thu Aug 1 09:17:11 UTC 2024 - Antonio Larrosa - -- Update to openssh 9.8p1: - * No changes for askpass, see main package changelog for - details. - ------------------------------------------------------------------- Sun Feb 25 18:26:23 UTC 2024 - Hans Petter Jansson diff --git a/openssh-askpass-gnome.spec b/openssh-askpass-gnome.spec index 83f4beb..bf91659 100644 --- a/openssh-askpass-gnome.spec +++ b/openssh-askpass-gnome.spec @@ -1,7 +1,7 @@ # # spec file for package openssh-askpass-gnome # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %define _name openssh Name: openssh-askpass-gnome -Version: 9.8p1 +Version: 9.6p1 Release: 0 Summary: A GNOME-Based Passphrase Dialog for OpenSSH License: BSD-2-Clause diff --git a/openssh-mitigate-lingering-secrets.patch b/openssh-mitigate-lingering-secrets.patch index 44af87e..9422abd 100644 --- a/openssh-mitigate-lingering-secrets.patch +++ b/openssh-mitigate-lingering-secrets.patch @@ -207,9 +207,9 @@ Index: openssh-9.3p2/packet.h --- openssh-9.3p2.orig/packet.h +++ openssh-9.3p2/packet.h @@ -103,6 +103,7 @@ void ssh_packet_close(struct ssh *); - void ssh_packet_close(struct ssh *); void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); void ssh_packet_clear_keys(struct ssh *); + void ssh_packet_clear_keys_noaudit(struct ssh *); +void ssh_clear_curkeys(struct ssh *, int); void ssh_clear_newkeys(struct ssh *, int); @@ -264,12 +264,12 @@ Index: openssh-9.3p2/sshbuf.h /* Macros for decoding/encoding integers */ #define PEEK_U64(p) \ (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \ -Index: openssh-9.3p2/sshd-session.c +Index: openssh-9.3p2/sshd.c =================================================================== ---- openssh-9.3p2.orig/sshd-session.c -+++ openssh-9.3p2/sshd-session.c -@@ -197,6 +197,19 @@ static void do_ssh2_kex(struct ssh *); - static void do_ssh2_kex(struct ssh *); +--- openssh-9.3p2.orig/sshd.c ++++ openssh-9.3p2/sshd.c +@@ -272,6 +272,19 @@ static void do_ssh2_kex(struct ssh *); + static char *listener_proctitle; /* + * Clear some stack space. This is a bit naive, but hopefully helps mitigate @@ -285,10 +285,10 @@ Index: openssh-9.3p2/sshd-session.c +} + +/* - * 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 - * terminal. -@@ -260,6 +260,8 @@ destroy_sensitive_data(struct ssh *ssh, + * Close all listening sockets + */ + static void +@@ -430,6 +443,8 @@ destroy_sensitive_data(struct ssh *ssh, sensitive_data.host_certificates[i] = NULL; } } @@ -297,32 +297,32 @@ Index: openssh-9.3p2/sshd-session.c } /* Demote private to public keys for network child */ -@@ -431,6 +432,8 @@ privsep_preauth(struct ssh *ssh) +@@ -600,6 +615,8 @@ privsep_preauth(struct ssh *ssh) + static void + privsep_postauth(struct ssh *ssh, Authctxt *authctxt) { - int skip_privdrop = 0; - + clobber_stack(); + - /* - * Hack for systems that don't support FD passing: retain privileges - * in the post-auth privsep process so it can allocate PTYs directly. -@@ -1354,6 +1356,7 @@ main(int ac, char **av) - */ - mm_send_keystate(ssh, pmonitor); - ssh_packet_clear_keys(ssh); -+ clobber_stack(); - exit(0); + #ifdef DISABLE_FD_PASSING + if (1) { + #else +@@ -2360,6 +2377,7 @@ main(int ac, char **av) + if (use_privsep) { + mm_send_keystate(ssh, pmonitor); + ssh_packet_clear_keys(ssh); ++ clobber_stack(); + exit(0); + } - authenticated: -@@ -1431,6 +1434,7 @@ main(int ac, char **av) - - mm_terminate(); +@@ -2436,6 +2454,7 @@ main(int ac, char **av) + if (use_privsep) + mm_terminate(); + clobber_stack(); exit(0); } -@@ -1577,8 +1581,10 @@ cleanup_exit(int i) +@@ -2596,8 +2615,10 @@ cleanup_exit(int i) /* cleanup_exit can be called at the very least from the privsep wrappers used for auditing. Make sure we don't recurse indefinitely. */ @@ -332,10 +332,10 @@ Index: openssh-9.3p2/sshd-session.c _exit(i); + } in_cleanup = 1; - extern int auth_attempted; /* monitor.c */ - -@@ -1604,5 +1610,7 @@ cleanup_exit(int i) - mm_is_monitor()) + if (the_active_state != NULL && the_authctxt != NULL) { + do_cleanup(the_active_state, the_authctxt); +@@ -2623,5 +2644,7 @@ cleanup_exit(int i) + (!use_privsep || mm_is_monitor())) audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif + diff --git a/openssh-reenable-dh-group14-sha1-default.patch b/openssh-reenable-dh-group14-sha1-default.patch index ac01baa..8a2293a 100644 --- a/openssh-reenable-dh-group14-sha1-default.patch +++ b/openssh-reenable-dh-group14-sha1-default.patch @@ -25,7 +25,7 @@ Index: openssh-8.9p1/ssh_config.5 +diffie-hellman-group14-sha1 .Ed .Pp - The list of supported key exchange algorithms may also be obtained using + The list of available key exchange algorithms may also be obtained using Index: openssh-8.9p1/sshd_config.5 =================================================================== --- openssh-8.9p1.orig/sshd_config.5 @@ -38,4 +38,4 @@ Index: openssh-8.9p1/sshd_config.5 +diffie-hellman-group14-sha256,diffie-hellman-group14-sha1 .Ed .Pp - The list of supported key exchange algorithms may also be obtained using + The list of available key exchange algorithms may also be obtained using diff --git a/openssh.changes b/openssh.changes index 9920ce7..db6ea98 100644 --- a/openssh.changes +++ b/openssh.changes @@ -1,299 +1,3 @@ -------------------------------------------------------------------- -Mon Aug 12 08:55:38 UTC 2024 - Antonio Larrosa - -- Fix a dbus connection leaked in the logind patch that was - missing a sd_bus_unref call (found by Matthias Gerstner): - * logind_set_tty.patch -- Add a patch that fixes a small memory leak when parsing the - subsystem configuration option: - * fix-memleak-in-process_server_config_line_depth.patch - -------------------------------------------------------------------- -Thu Aug 1 09:17:11 UTC 2024 - Antonio Larrosa - -- Update to openssh 9.8p1: - = Security - * 1) Race condition in sshd(8) (bsc#1226642, CVE-2024-6387). - A critical vulnerability in sshd(8) was present in Portable - OpenSSH versions between 8.5p1 and 9.7p1 (inclusive) that may - allow arbitrary code execution with root privileges. - Successful exploitation has been demonstrated on 32-bit - Linux/glibc systems with ASLR. Under lab conditions, the attack - requires on average 6-8 hours of continuous connections up to - the maximum the server will accept. Exploitation on 64-bit - systems is believed to be possible but has not been - demonstrated at this time. It's likely that these attacks will - be improved upon. - Exploitation on non-glibc systems is conceivable but has not - been examined. Systems that lack ASLR or users of downstream - Linux distributions that have modified OpenSSH to disable - per-connection ASLR re-randomisation (yes - this is a thing, no - - we don't understand why) may potentially have an easier path - to exploitation. OpenBSD is not vulnerable. - We thank the Qualys Security Advisory Team for discovering, - reporting and demonstrating exploitability of this problem, and - for providing detailed feedback on additional mitigation - measures. - * 2) Logic error in ssh(1) ObscureKeystrokeTiming (bsc#1227318, - CVE-2024-39894). - In OpenSSH version 9.5 through 9.7 (inclusive), when connected - to an OpenSSH server version 9.5 or later, a logic error in the - ssh(1) ObscureKeystrokeTiming feature (on by default) rendered - this feature ineffective - a passive observer could still - detect which network packets contained real keystrokes when the - countermeasure was active because both fake and real keystroke - packets were being sent unconditionally. - This bug was found by Philippos Giavridis and also - independently by Jacky Wei En Kung, Daniel Hugenroth and - Alastair Beresford of the University of Cambridge Computer Lab. - Worse, the unconditional sending of both fake and real - keystroke packets broke another long-standing timing attack - mitigation. Since OpenSSH 2.9.9 sshd(8) has sent fake keystoke - echo packets for traffic received on TTYs in echo-off mode, - such as when entering a password into su(8) or sudo(8). This - bug rendered these fake keystroke echoes ineffective and could - allow a passive observer of a SSH session to once again detect - when echo was off and obtain fairly limited timing information - about keystrokes in this situation (20ms granularity by - default). - This additional implication of the bug was identified by - Jacky Wei En Kung, Daniel Hugenroth and Alastair Beresford and - we thank them for their detailed analysis. - This bug does not affect connections when - ObscureKeystrokeTiming was disabled or sessions where no TTY - was requested. - - = Future deprecation notice - * OpenSSH plans to remove support for the DSA signature algorithm - in early 2025. This release disables DSA by default at compile - time. - DSA, as specified in the SSHv2 protocol, is inherently weak - - being limited to a 160 bit private key and use of the SHA1 - digest. Its estimated security level is only 80 bits symmetric - equivalent. - OpenSSH has disabled DSA keys by default since 2015 but has - retained run-time optional support for them. DSA was the only - mandatory-to-implement algorithm in the SSHv2 RFCs, mostly - because alternative algorithms were encumbered by patents when - the SSHv2 protocol was specified. - This has not been the case for decades at this point and better - algorithms are well supported by all actively-maintained SSH - implementations. We do not consider the costs of maintaining - DSA in OpenSSH to be justified and hope that removing it from - OpenSSH can accelerate its wider deprecation in supporting - cryptography libraries. - This release, and its deactivation of DSA by default at - compile-time, marks the second step in our timeline to finally - deprecate DSA. The final step of removing DSA support entirely - is planned for the first OpenSSH release of 2025. - DSA support may be re-enabled in OpenBSD by setting - "DSAKEY=yes" in Makefile.inc. To enable DSA support in - portable OpenSSH, pass the "--enable-dsa-keys" option to - configure. - - = Potentially-incompatible changes - * all: as mentioned above, the DSA signature algorithm is now - disabled at compile time. - * sshd(8): the server will now block client addresses that - repeatedly fail authentication, repeatedly connect without ever - completing authentication or that crash the server. See the - discussion of PerSourcePenalties below for more information. - Operators of servers that accept connections from many users, - or servers that accept connections from addresses behind NAT or - proxies may need to consider these settings. - * sshd(8): the server has been split into a listener binary, - sshd(8), and a per-session binary "sshd-session". This allows - for a much smaller listener binary, as it no longer needs to - support the SSH protocol. As part of this work, support for - disabling privilege separation (which previously required code - changes to disable) and disabling re-execution of sshd(8) has - been removed. Further separation of sshd-session into - additional, minimal binaries is planned for the future. - * sshd(8): several log messages have changed. In particular, some - log messages will be tagged with as originating from a process - named "sshd-session" rather than "sshd". - * ssh-keyscan(1): this tool previously emitted comment lines - containing the hostname and SSH protocol banner to standard - error. This release now emits them to standard output, but adds - a new "-q" flag to silence them altogether. - * sshd(8): (portable OpenSSH only) sshd will no longer use - argv[0] as the PAM service name. A new "PAMServiceName" - sshd_config(5) directive allows selecting the service name at - runtime. This defaults to "sshd". bz2101 - * (portable OpenSSH only) Automatically-generated files, such as - configure, config.h.in, etc will now be checked in to the - portable OpenSSH git release branch (e.g. V_9_8). This should - ensure that the contents of the signed release branch exactly - match the contents of the signed release tarball. - - = New features - * sshd(8): as described above, sshd(8) will now penalise client - addresses that, for various reasons, do not successfully - complete authentication. This feature is controlled by a new - sshd_config(5) PerSourcePenalties option and is on by default. - sshd(8) will now identify situations where the session did not - authenticate as expected. These conditions include when the - client repeatedly attempted authentication unsucessfully - (possibly indicating an attack against one or more accounts, - e.g. password guessing), or when client behaviour caused sshd - to crash (possibly indicating attempts to exploit bugs in - sshd). - When such a condition is observed, sshd will record a penalty - of some duration (e.g. 30 seconds) against the client's - address. If this time is above a minimum configurable - threshold, then all connections from the client address will be - refused (along with any others in the same - PerSourceNetBlockSize CIDR range) until the penalty expire. - Repeated offenses by the same client address will accrue - greater penalties, up to a configurable maximum. Address ranges - may be fully exempted from penalties, e.g. to guarantee access - from a set of trusted management addresses, using the new - sshd_config(5) PerSourcePenaltyExemptList option. - We hope these options will make it significantly more difficult - for attackers to find accounts with weak/guessable passwords or - exploit bugs in sshd(8) itself. This option is enabled by - default. - * ssh(8): allow the HostkeyAlgorithms directive to disable the - implicit fallback from certificate host key to plain host keys. - - = Bugfixes - * misc: fix a number of inaccuracies in the PROTOCOL.* - documentation files. GHPR430 GHPR487 - * all: switch to strtonum(3) for more robust integer parsing in - most places. - * ssh(1), sshd(8): correctly restore sigprocmask around ppoll() - * ssh-keysign(8): stricter validation of messaging socket fd - GHPR492 - * sftp(1): flush stdout after writing "sftp>" prompt when not - using editline. GHPR480 - * sftp-server(8): fix home-directory extension implementation, - it previously always returned the current user's home directory - contrary to the spec. GHPR477 - * ssh-keyscan(1): do not close stdin to prevent error messages - when stdin is read multiple times. E.g. - echo localhost | ssh-keyscan -f - -f - - * regression tests: fix rekey test that was testing the same KEX - algorithm repeatedly instead of testing all of them. bz3692 - * ssh_config(5), sshd_config(5): clarify the KEXAlgorithms - directive documentation, especially around what is supported - vs available. bz3701. - - = Portability - * sshd(8): expose SSH_AUTH_INFO_0 always to PAM auth modules - unconditionally. The previous behaviour was to expose it only - when particular authentication methods were in use. - * build: fix OpenSSL ED25519 support detection. An incorrect - function signature in configure.ac previously prevented - enabling the recently added support for ED25519 private keys in - PEM PKCS8 format. - * ssh(1), ssh-agent(8): allow the presence of the WAYLAND_DISPLAY - environment variable to enable SSH_ASKPASS, similarly to the - X11 DISPLAY environment variable. GHPR479 - * build: improve detection of the -fzero-call-used-regs compiler - flag. bz3673. - * build: relax OpenSSL version check to accept all OpenSSL 3.x - versions. - * sshd(8): add support for notifying systemd on server listen and - reload, using a standalone implementation that doesn't depend - on libsystemd. bz2641 - -- Update to openssh 9.7p1: - - = New features - * ssh(1), sshd(8): add a "global" ChannelTimeout type that - watches all open channels and will close all open channels if - there is no traffic on any of them for the specified interval. - This is in addition to the existing per-channel timeouts added - recently. - This supports situations like having both session and x11 - forwarding channels open where one may be idle for an extended - period but the other is actively used. The global timeout could - close both channels when both have been idle for too long. - * All: make DSA key support compile-time optional, defaulting to - on. - - = Bugfixes - * sshd(8): don't append an unnecessary space to the end of - subsystem arguments (bz3667) - * ssh(1): fix the multiplexing "channel proxy" mode, broken when - keystroke timing obfuscation was added. (GHPR#463) - * ssh(1), sshd(8): fix spurious configuration parsing errors when - options that accept array arguments are overridden (bz3657). - * ssh-agent(1): fix potential spin in signal handler (bz3670) - * Many fixes to manual pages and other documentation, including - GHPR#462, GHPR#454, GHPR#442 and GHPR#441. - * Greatly improve interop testing against PuTTY. - - = Portability - * Improve the error message when the autoconf OpenSSL header - check fails (bz#3668) - * Improve detection of broken toolchain -fzero-call-used-regs - support (bz3645). - * Fix regress/misc/fuzz-harness fuzzers and make them compile - without warnings when using clang16 -- Use gcc-11 in SLE to avoid a "parameter name omitted" error -- Rebase patches: - * logind_set_tty.patch - * openssh-6.6.1p1-selinux-contexts.patch - * openssh-6.6p1-keycat.patch - * openssh-6.6p1-privsep-selinux.patch - * openssh-7.6p1-cleanup-selinux.patch - * openssh-7.7p1-cavstest-ctr.patch - * openssh-7.7p1-cavstest-kdf.patch - * openssh-7.7p1-fips.patch - * openssh-7.7p1-fips_checks.patch - * openssh-7.7p1-ldap.patch - * openssh-7.7p1-pam_check_locks.patch - * openssh-7.7p1-systemd-notify.patch - * openssh-7.8p1-role-mls.patch - * openssh-8.0p1-gssapi-keyex.patch - * openssh-8.1p1-audit.patch - * openssh-8.4p1-vendordir.patch - * openssh-9.6p1-crypto-policies-man.patch - * openssh-mitigate-lingering-secrets.patch - * openssh-reenable-dh-group14-sha1-default.patch - * wtmpdb.patch -- Thanks to Fedora developers for an initial version of the - rebase of the following patches: - * openssh-8.0p1-gssapi-keyex.patch - * openssh-7.8p1-role-mls.patch - * openssh-8.1p1-audit.patch -- Remove patches that are already included in 9.8p1: - * fix-CVE-2024-6387.patch - * 0001-upstream-fix-proxy-multiplexing-mode_-broken-when-keystroke.patch - * 0001-upstream-correctly-restore-sigprocmask-around-ppoll.patch - * 0001-upstream-when-sending-ObscureKeystrokeTiming-chaff-packets_.patch -- Remove patch that is now merged into - openssh-7.7p1-cavstest-ctr.patch and - openssh-7.7p1-cavstest-kdf.patch where it belongs: - * fix-missing-lz.patch - -------------------------------------------------------------------- -Mon Jul 15 17:49:06 UTC 2024 - Antonio Larrosa - -- Add sshd.socket and sshd@.service units as alternative to the - sshd.service that makes systemd listen to the ssh port - and run sshd per incoming connection. To enable this, - disable sshd.service and enable sshd.socket . If you want to - use a non standard sshd port with sshd.socket you can do - "systemctl edit sshd.socket" and add something like: - - [Socket] - ListenStream=8022 - - which listens on port 8022 as well as on port 22. If you want - to reset the list of listened ports and just use 8022, use: - - [Socket] - ListenStream= - ListenStream=8022 -- To enable a vsock listener in sshd (which allows to connect to - libvirt VMs), the systemd-experimental package needs to be - installed in the guest system, the libvirt-ssh-proxy package - needs to be installed in the host and the vm needs to have - vsock support (in virt-manager, click in "Add hardware" and - add "VSOCK VirtIO"). - ------------------------------------------------------------------- Fri Jul 5 17:49:06 UTC 2024 - Antonio Larrosa diff --git a/openssh.spec b/openssh.spec index f52a2a9..e1f899b 100644 --- a/openssh.spec +++ b/openssh.spec @@ -1,7 +1,7 @@ # # spec file for package openssh # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -39,7 +39,7 @@ %define _fillupdir %{_localstatedir}/adm/fillup-templates %endif Name: openssh -Version: 9.8p1 +Version: 9.6p1 Release: 0 Summary: Secure Shell Client and Server (Remote Login Program) License: BSD-2-Clause AND MIT @@ -61,8 +61,6 @@ Source12: cavs_driver-ssh.pl Source13: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc#/openssh.keyring Source14: sysusers-sshd.conf Source15: sshd-sle.pamd -Source16: sshd@.service -Source17: sshd.socket Patch1: openssh-7.7p1-X11_trusted_forwarding.patch Patch3: openssh-7.7p1-enable_PAM_by_default.patch Patch4: openssh-7.7p1-eal3.patch @@ -121,6 +119,7 @@ Patch50: openssh-openssl-3.patch Patch51: wtmpdb.patch Patch52: logind_set_tty.patch Patch54: openssh-mitigate-lingering-secrets.patch +Patch100: fix-missing-lz.patch Patch102: openssh-7.8p1-role-mls.patch Patch103: openssh-6.6p1-privsep-selinux.patch Patch104: openssh-6.6p1-keycat.patch @@ -129,15 +128,19 @@ Patch106: openssh-7.6p1-cleanup-selinux.patch # PATCH-FIX-OPENSUSE bsc#1211301 Add crypto-policies support Patch107: openssh-9.6p1-crypto-policies.patch Patch108: openssh-9.6p1-crypto-policies-man.patch -Patch109: fix-memleak-in-process_server_config_line_depth.patch +# PATCH-FIX-UPSTREAM bsc#1226642 fix CVE-2024-6387 +Patch109: fix-CVE-2024-6387.patch +# PATCH-FIX-UPSTREAM +Patch110: 0001-upstream-fix-proxy-multiplexing-mode_-broken-when-keystroke.patch +# PATCH-FIX-UPSTREAM +Patch111: 0001-upstream-correctly-restore-sigprocmask-around-ppoll.patch +# PATCH-FIX-UPSTREAM bsc#1227318 CVE-2024-39894 +Patch112: 0001-upstream-when-sending-ObscureKeystrokeTiming-chaff-packets_.patch %if 0%{with allow_root_password_login_by_default} Patch1000: openssh-7.7p1-allow_root_password_login.patch %endif BuildRequires: audit-devel BuildRequires: automake -%if 0%{?sle_version} >= 150500 -BuildRequires: gcc11 -%endif BuildRequires: groff BuildRequires: libedit-devel BuildRequires: libselinux-devel @@ -325,9 +328,6 @@ sed -i.libexec 's,@LIBEXECDIR@,%{_libexecdir}/ssh,' \ ) %build -%if 0%{?sle_version} >= 150500 -export CC=gcc-11 -%endif autoreconf -fiv %ifarch s390 s390x %{sparc} PIEFLAGS="-fPIE" @@ -392,8 +392,6 @@ install -d -m 755 %{buildroot}%{_sysconfdir}/slp.reg.d/ install -m 644 %{SOURCE5} %{buildroot}%{_sysconfdir}/slp.reg.d/ %endif install -D -m 0644 %{SOURCE10} %{buildroot}%{_unitdir}/sshd.service -install -D -m 0644 %{SOURCE16} %{buildroot}%{_unitdir}/sshd@.service -install -D -m 0644 %{SOURCE17} %{buildroot}%{_unitdir}/sshd.socket ln -s service %{buildroot}%{_sbindir}/rcsshd install -d -m 755 %{buildroot}%{_fillupdir} install -m 644 %{SOURCE8} %{buildroot}%{_fillupdir} @@ -473,11 +471,11 @@ test -f /etc/pam.d/sshd.rpmsave && mv -v /etc/pam.d/sshd.rpmsave /etc/pam.d/sshd test -f /etc/ssh/sshd_config.rpmsave && mv -v /etc/ssh/sshd_config.rpmsave /etc/ssh/sshd_config.rpmsave.old ||: %endif -%service_add_pre sshd.service sshd.socket +%service_add_pre sshd.service %post server %{fillup_only -n ssh} -%service_add_post sshd.service sshd.socket +%service_add_post sshd.service %if ! %{defined _distconfdir} test -f /etc/ssh/sshd_config && (grep -q "^Include /etc/ssh/sshd_config\.d/\*\.conf" /etc/ssh/sshd_config || ( \ @@ -489,16 +487,16 @@ test -f /etc/ssh/sshd_config && (grep -q "^Include /etc/ssh/sshd_config\.d/\*\.c %endif %preun server -%service_del_preun sshd.service sshd.socket +%service_del_preun sshd.service %postun server # The openssh-fips trigger script for openssh will normally restart sshd once # it gets installed, so only restart the service here if openssh-fips is not # present. if rpm -q openssh-fips >/dev/null 2>/dev/null; then -%service_del_postun_without_restart sshd.service sshd.socket +%service_del_postun_without_restart sshd.service else -%service_del_postun sshd.service sshd.socket +%service_del_postun sshd.service fi %if ! %{defined _distconfdir} @@ -586,14 +584,11 @@ test -f /etc/ssh/ssh_config.rpmsave && mv -v /etc/ssh/ssh_config.rpmsave /etc/ss %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config.d/40-suse-crypto-policies.conf %endif %attr(0644,root,root) %{_unitdir}/sshd.service -%attr(0644,root,root) %{_unitdir}/sshd@.service -%attr(0644,root,root) %{_unitdir}/sshd.socket %attr(0644,root,root) %{_sysusersdir}/sshd.conf %attr(0444,root,root) %{_mandir}/man5/sshd_config* %attr(0444,root,root) %{_mandir}/man8/sftp-server.8* %attr(0444,root,root) %{_mandir}/man8/sshd.8* %attr(0755,root,root) %{_libexecdir}/ssh/sftp-server -%attr(0755,root,root) %{_libexecdir}/ssh/sshd-session %if 0%{?suse_version} < 1600 %dir %{_sysconfdir}/slp.reg.d %config %{_sysconfdir}/slp.reg.d/ssh.reg diff --git a/sshd.socket b/sshd.socket deleted file mode 100644 index 302de42..0000000 --- a/sshd.socket +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=OpenSSH Server Socket -Conflicts=sshd.service - -[Socket] -ListenStream=22 -Accept=yes - -[Install] -WantedBy=sockets.target - diff --git a/sshd@.service b/sshd@.service deleted file mode 100644 index 9f8d816..0000000 --- a/sshd@.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=OpenSSH Per-Connection Server Daemon -Documentation=man:systemd-ssh-generator(8) man:sshd(8) -After=network.target - -[Service] -EnvironmentFile=-/etc/sysconfig/ssh -ExecStartPre=/usr/sbin/sshd-gen-keys-start -ExecStartPre=/usr/sbin/sshd -t $SSHD_OPTS -ExecStart=-/usr/sbin/sshd -i $SSHD_OPTS -StandardInput=socket diff --git a/wtmpdb.patch b/wtmpdb.patch index de6f80c..bf5bca9 100644 --- a/wtmpdb.patch +++ b/wtmpdb.patch @@ -174,16 +174,12 @@ diff -ur openssh-8.9p1.old/Makefile.in openssh-8.9p1/Makefile.in AR=@AR@ AWK=@AWK@ RANLIB=@RANLIB@ -@@ -212,10 +213,10 @@ +@@ -212,7 +213,7 @@ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS) sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) -- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) -+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) $(LIBWTMPDB) - - sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS) -- $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -+ $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) +- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) ++ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)