public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/gsi-openssh] epel10: Based on openssh-9.9p1-32.el10
@ 2026-09-22 19:59 Mattias Ellert
0 siblings, 0 replies; only message in thread
From: Mattias Ellert @ 2026-09-22 19:59 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/gsi-openssh
Branch : epel10
Commit : c69d9b538f65110ba2f26df5e186fa7e933f922e
Author : Mattias Ellert <mattias.ellert@physics.uu.se>
Date : 2026-09-22T20:25:39+02:00
Stats : +770/-179 in 14 file(s)
URL : https://src.fedoraproject.org/rpms/gsi-openssh/c/c69d9b538f65110ba2f26df5e186fa7e933f922e?branch=epel10
Log:
Based on openssh-9.9p1-32.el10
---
diff --git a/gsi-openssh.spec b/gsi-openssh.spec
index b80cf40..52533d4 100644
--- a/gsi-openssh.spec
+++ b/gsi-openssh.spec
@@ -28,7 +28,7 @@
Summary: An implementation of the SSH protocol with GSI authentication
Name: gsi-openssh
Version: %{openssh_ver}
-Release: 6%{?dist}
+Release: 7%{?dist}
Provides: gsissh = %{version}-%{release}
Obsoletes: gsissh < 5.8p2-2
URL: http://www.openssh.com/portable.html
@@ -231,6 +231,26 @@ Patch1043: openssh-9.9p1-authorized-keys-principles-option.patch
# upstream 607bd871ec029e9aa22e632a22547250f3cae223
# upstream 1340d3fa8e4bb122906a82159c4c9b91584d65ce
Patch1044: openssh-9.9p1-proxyjump-username-validity-checks.patch
+# upstream 36480181fa22f98e180b4f9e10203480c0346c78
+Patch1045: openssh-9.9p1-scp-remote-glob.patch
+# upstream e8bdfb151a356d0171fea4194dd205fbb252be23
+Patch1046: openssh-9.9p1-cve-2026-60002.patch
+# upstream 8b05bbeb293c5f777915e37e9ed43a06fb8e7614
+# upstream 5a5e47740b6466d58242aca28b9e584bab4ccf1d
+Patch1047: openssh-9.9p1-copy-data-ext-self-copy.patch
+# upstream 6a57081dc35acf3ee298108d4bc3580489608d5f
+Patch1048: openssh-10.4p1-CVE-2026-59995.patch
+# upstream 8dfe7ed6e2fd988de08df508355a196b956b2753
+# upstream d322f2ccf7da095ce94d1d99cb563246f61487b0
+# combines CVE-2026-59999 and CVE-2026-73283
+# downstream specific fix, drop on rebase
+Patch1049: openssh-10.4p1-CVE-2026-59999.patch
+# upstream 6a57081dc35acf3ee298108d4bc3580489608d5f
+Patch1050: openssh-10.5p1-CVE-2026-73281.patch
+# upstream 9910d5ef53124ce1157d57bc11e222658aa41299
+Patch1051: openssh-10.5p1-CVE-2026-73282.patch
+# upstream d43ba60c91cb323ca921049b7d43b1908c318454
+Patch1052: openssh-9.9p1-CVE-2026-60001.patch
# This is the patch that adds GSI support
# Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream
@@ -425,6 +445,14 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%patch -P 1042 -p1 -b .ecdsa-incomplete-application
%patch -P 1043 -p1 -b .authorized-keys-principles-option
%patch -P 1044 -p1 -b .proxyjump-username-validity-checks
+%patch -P 1045 -p1 -b .scp-remote-glob
+%patch -P 1046 -p1 -b .cve-2026-60002
+%patch -P 1047 -p1 -b .copy-data-ext-self-copy
+%patch -P 1048 -p1 -b .CVE-2026-59995
+%patch -P 1049 -p1 -b .CVE-2026-59999
+%patch -P 1050 -p1 -b .CVE-2026-73281
+%patch -P 1051 -p1 -b .CVE-2026-73282
+%patch -P 1052 -p1 -b .CVE-2026-60001
%patch -P 100 -p1 -b .coverity
@@ -650,6 +678,9 @@ fi
%ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration
%changelog
+* Tue Sep 22 2026 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.9p1-7
+- Based on openssh-9.9p1-32.el10
+
* Fri May 29 2026 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.9p1-6
- Based on openssh-9.9p1-26.el10
diff --git a/openssh-10.4p1-CVE-2026-59995.patch b/openssh-10.4p1-CVE-2026-59995.patch
new file mode 100644
index 0000000..0ba8388
--- /dev/null
+++ b/openssh-10.4p1-CVE-2026-59995.patch
@@ -0,0 +1,20 @@
+diff --git a/sftp.c b/sftp.c
+index 0ab9206c2..0b57e0833 100644
+--- a/sftp.c
++++ b/sftp.c
+@@ -2289,13 +2289,8 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
+ return (-1);
+ }
+ } else {
+- /* XXX this is wrong wrt quoting */
+- snprintf(cmd, sizeof cmd, "get%s %s%s%s",
+- global_aflag ? " -a" : "", dir,
+- file2 == NULL ? "" : " ",
+- file2 == NULL ? "" : file2);
+- err = parse_dispatch_command(conn, cmd,
+- &remote_path, startdir, 1, 0);
++ err = process_get(conn, dir, file2, remote_path, 0, 0,
++ global_aflag, 0);
+ free(dir);
+ free(startdir);
+ free(remote_path);
diff --git a/openssh-10.4p1-CVE-2026-59999.patch b/openssh-10.4p1-CVE-2026-59999.patch
new file mode 100644
index 0000000..b1bf58c
--- /dev/null
+++ b/openssh-10.4p1-CVE-2026-59999.patch
@@ -0,0 +1,78 @@
+diff --git a/auth-options.c b/auth-options.c
+index e15f600ab..c5fc4e59c 100644
+--- a/auth-options.c
++++ b/auth-options.c
+@@ -242,6 +242,7 @@ sshauthopt_new_with_keys_defaults(void)
+ ret->permit_x11_forwarding_flag = 1;
+ ret->permit_pty_flag = 1;
+ ret->permit_user_rc = 1;
++ ret->permit_tun_flag = 1;
+ return ret;
+ }
+
+@@ -345,6 +346,7 @@ sshauthopt_parse(const char *opts, const char **errstrp)
+ ret->permit_x11_forwarding_flag = 0;
+ ret->permit_pty_flag = 0;
+ ret->permit_user_rc = 0;
++ ret->permit_tun_flag = 0;
+ } else if ((r = opt_flag("cert-authority", 0, &opts)) != -1) {
+ ret->cert_authority = r;
+ } else if ((r = opt_flag("port-forwarding", 1, &opts)) != -1) {
+@@ -601,6 +603,7 @@ sshauthopt_merge(const struct sshauthopt *primary,
+ OPTFLAG_AND(permit_x11_forwarding_flag);
+ OPTFLAG_AND(permit_pty_flag);
+ OPTFLAG_AND(permit_user_rc);
++ OPTFLAG_AND(permit_tun_flag);
+ OPTFLAG_AND(no_require_user_presence);
+ /* Restrictive flags are logical-OR (i.e. must be set in either) */
+ OPTFLAG_OR(require_verify);
+@@ -669,6 +672,7 @@ sshauthopt_copy(const struct sshauthopt *orig)
+ OPTSCALAR(permit_x11_forwarding_flag);
+ OPTSCALAR(permit_pty_flag);
+ OPTSCALAR(permit_user_rc);
++ OPTSCALAR(permit_tun_flag);
+ OPTSCALAR(restricted);
+ OPTSCALAR(cert_authority);
+ OPTSCALAR(force_tun_device);
+@@ -804,6 +808,7 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
+ (r = sshbuf_put_u8(m, opts->permit_x11_forwarding_flag)) != 0 ||
+ (r = sshbuf_put_u8(m, opts->permit_pty_flag)) != 0 ||
+ (r = sshbuf_put_u8(m, opts->permit_user_rc)) != 0 ||
++ (r = sshbuf_put_u8(m, opts->permit_tun_flag)) != 0 ||
+ (r = sshbuf_put_u8(m, opts->restricted)) != 0 ||
+ (r = sshbuf_put_u8(m, opts->cert_authority)) != 0 ||
+ (r = sshbuf_put_u8(m, opts->no_require_user_presence)) != 0 ||
+@@ -867,6 +872,7 @@ sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
+ OPT_FLAG(permit_x11_forwarding_flag);
+ OPT_FLAG(permit_pty_flag);
+ OPT_FLAG(permit_user_rc);
++ OPT_FLAG(permit_tun_flag);
+ OPT_FLAG(restricted);
+ OPT_FLAG(cert_authority);
+ OPT_FLAG(no_require_user_presence);
+diff --git a/auth-options.h b/auth-options.h
+index 6e29b727c..191b9b249 100644
+--- a/auth-options.h
++++ b/auth-options.h
+@@ -39,6 +39,7 @@ struct sshauthopt {
+ int permit_x11_forwarding_flag;
+ int permit_pty_flag;
+ int permit_user_rc;
++ int permit_tun_flag;
+
+ /* "restrict" keyword was invoked */
+ int restricted;
+diff --git a/serverloop.c b/serverloop.c
+index 8a6e3db80..cf5243f80 100644
+--- a/serverloop.c
++++ b/serverloop.c
+@@ -523,7 +523,8 @@ server_request_tun(struct ssh *ssh)
+ ssh_packet_send_debug(ssh, "Unsupported tunnel device mode.");
+ return NULL;
+ }
+- if ((options.permit_tun & mode) == 0) {
++ if ((options.permit_tun & mode) == 0 || options.disable_forwarding ||
++ !auth_opts->permit_tun_flag) {
+ ssh_packet_send_debug(ssh, "Server has rejected tunnel device "
+ "forwarding");
+ return NULL;
diff --git a/openssh-10.5p1-CVE-2026-73281.patch b/openssh-10.5p1-CVE-2026-73281.patch
new file mode 100644
index 0000000..b59ec35
--- /dev/null
+++ b/openssh-10.5p1-CVE-2026-73281.patch
@@ -0,0 +1,42 @@
+diff --git a/ssh-agent.c b/ssh-agent.c
+--- a/ssh-agent.c
++++ b/ssh-agent.c
+@@ -1839,8 +1839,17 @@ process_extension(SocketEntry *e)
+ error_fr(r, "parse");
+ goto send;
+ }
++
++ /*
++ * This function can be called while the agent is locked to allow
++ * session binds to be processed for new channels.
++ * Other operations should be refused when locked.
++ */
++
+ if (strcmp(name, "session-bind@openssh.com") == 0)
+ success = process_ext_session_bind(e);
++ else if (locked)
++ debug_f("attempt to use extension \"%s\" while locked", name);
+ else
+ debug_f("unsupported extension \"%s\"", name);
+ free(name);
+@@ -1892,16 +1901,19 @@ process_message(u_int socknum)
+
+ /* check whether agent is locked */
+ if (locked && type != SSH_AGENTC_UNLOCK) {
+- sshbuf_reset(e->request);
+ switch (type) {
+ case SSH2_AGENTC_REQUEST_IDENTITIES:
+ /* send empty lists */
+ no_identities(e);
+ break;
++ case SSH_AGENTC_EXTENSION:
++ process_extension(e);
++ break;
+ default:
+ /* send a fail message for all other request types */
+ send_status(e, 0);
+ }
++ sshbuf_reset(e->request);
+ return 1;
+ }
+
diff --git a/openssh-10.5p1-CVE-2026-73282.patch b/openssh-10.5p1-CVE-2026-73282.patch
new file mode 100644
index 0000000..a4c4973
--- /dev/null
+++ b/openssh-10.5p1-CVE-2026-73282.patch
@@ -0,0 +1,51 @@
+diff --git a/ssh.c b/ssh.c
+--- a/ssh.c
++++ b/ssh.c
+@@ -1862,14 +1862,24 @@
+ }
+ }
+
++struct rfwd_confirm_ctx {
++ int fid;
++};
++
+ /* Callback for remote forward global requests */
+ static void
+ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
+ {
+- struct Forward *rfwd = (struct Forward *)ctxt;
++ struct rfwd_confirm_ctx *rctx = (struct rfwd_confirm_ctx *)ctxt;
++ struct Forward *rfwd;
+ u_int port;
+ int r;
+
++ if (rctx->fid < 0 || rctx->fid >= options.num_remote_forwards)
++ fatal_f("invalid forwarding ID %d", rctx->fid);
++ rfwd = &options.remote_forwards[rctx->fid];
++ freezero(rctx, sizeof(*rctx));
++
+ /* XXX verbose() on failure? */
+ debug("remote forward %s for: listen %s%s%d, connect %s:%d",
+ type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
+@@ -2047,6 +2057,8 @@
+
+ /* Initiate remote TCP/IP port forwardings. */
+ for (i = 0; i < options.num_remote_forwards; i++) {
++ struct rfwd_confirm_ctx *rctx;
++
+ debug("Remote connections from %.200s:%d forwarded to "
+ "local address %.200s:%d",
+ (options.remote_forwards[i].listen_path != NULL) ?
+@@ -2061,9 +2073,10 @@
+ if ((options.remote_forwards[i].handle =
+ channel_request_remote_forwarding(ssh,
+ &options.remote_forwards[i])) >= 0) {
++ rctx = xcalloc(1, sizeof(*rctx));
++ rctx->fid = i;
+ client_register_global_confirm(
+- ssh_confirm_remote_forward,
+- &options.remote_forwards[i]);
++ ssh_confirm_remote_forward, rctx);
+ forward_confirms_pending++;
+ } else if (options.exit_on_forward_failure)
+ fatal("Could not request remote forwarding.");
diff --git a/openssh-7.2p2-x11.patch b/openssh-7.2p2-x11.patch
index 6db16be..a605a41 100644
--- a/openssh-7.2p2-x11.patch
+++ b/openssh-7.2p2-x11.patch
@@ -32,7 +32,7 @@ diff --git a/channels.c b/channels.c
return -1;
}
-@@ -5099,8 +5102,18 @@
+@@ -5099,8 +5102,19 @@
connect_local_xsocket(u_int dnr)
{
char buf[1024];
@@ -41,10 +41,11 @@ diff --git a/channels.c b/channels.c
+ int len, ret;
+ len = snprintf(buf + 1, sizeof (buf) - 1, _PATH_UNIX_X, dnr);
+#ifdef linux
-+ /* try abstract socket first */
-+ buf[0] = '\0';
-+ if ((ret = connect_local_xsocket_path(buf, len + 1)) >= 0)
-+ return ret;
++ if (getenv("SSH_INSECURE_ABSTRACT_SOCKET_ENABLED") != NULL) {
++ buf[0] = '\0';
++ if ((ret = connect_local_xsocket_path(buf, len + 1)) >= 0)
++ return ret;
++ }
+#endif
+ if ((ret = connect_local_xsocket_path(buf + 1, len)) >= 0)
+ return ret;
diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch
index 8d442a4..bc44ef3 100644
--- a/openssh-7.7p1-fips.patch
+++ b/openssh-7.7p1-fips.patch
@@ -106,17 +106,18 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
#include <sys/types.h>
#include <openssl/dh.h>
-@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
+@@ -117,6 +118,11 @@ input_kex_dh_gex_group(int type, u_int32
}
+ p = g = NULL; /* belong to kex->dh now */
+
+ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
- p = g = NULL; /* belong to kex->dh now */
-
++
/* generate and send 'e', client DH public key */
+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
+ goto out;
diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
--- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200
diff --git a/openssh-9.9p1-CVE-2026-60001.patch b/openssh-9.9p1-CVE-2026-60001.patch
new file mode 100644
index 0000000..27eecc8
--- /dev/null
+++ b/openssh-9.9p1-CVE-2026-60001.patch
@@ -0,0 +1,97 @@
+diff --color -ruNp a/auth2.c b/auth2.c
+--- a/auth2.c 2026-09-17 15:21:59.317492134 +0200
++++ b/auth2.c 2026-09-17 15:29:58.698877649 +0200
+@@ -267,6 +267,12 @@ ensure_minimum_time_since(double start,
+ nanosleep(&ts, NULL);
+ }
+
++void
++auth_failure_delay(Authctxt *authctxt, double tstart)
++{
++ ensure_minimum_time_since(tstart, user_specific_delay(authctxt->user));
++}
++
+ static int
+ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
+ {
+@@ -359,8 +365,8 @@ input_userauth_request(int type, u_int32
+ authenticated = m->userauth(ssh, method);
+ }
+ if (!authctxt->authenticated && strcmp(method, "none") != 0)
+- ensure_minimum_time_since(tstart,
+- user_specific_delay(authctxt->user));
++ auth_failure_delay(authctxt, tstart);
++
+ userauth_finish(ssh, authenticated, method, NULL);
+ r = 0;
+ out:
+diff --color -ruNp a/auth2-chall.c b/auth2-chall.c
+--- a/auth2-chall.c 2024-09-20 00:20:48.000000000 +0200
++++ b/auth2-chall.c 2026-09-17 15:24:34.321075436 +0200
+@@ -296,6 +296,7 @@ input_userauth_info_response(int type, u
+ u_int i, nresp;
+ const char *devicename = NULL;
+ char **response = NULL;
++ double tstart = monotime_double();
+
+ if (authctxt == NULL)
+ fatal_f("no authctxt");
+@@ -354,6 +355,9 @@ input_userauth_info_response(int type, u
+ auth2_challenge_start(ssh);
+ }
+ }
++
++ if (!authenticated)
++ auth_failure_delay(authctxt, tstart);
+ userauth_finish(ssh, authenticated, "keyboard-interactive",
+ devicename);
+ return 0;
+diff --color -ruNp a/auth2-gss.c b/auth2-gss.c
+--- a/auth2-gss.c 2026-09-17 15:21:59.236281062 +0200
++++ b/auth2-gss.c 2026-09-17 15:27:33.902644227 +0200
+@@ -298,6 +298,7 @@ input_gssapi_exchange_complete(int type,
+ {
+ Authctxt *authctxt = ssh->authctxt;
+ int r, authenticated;
++ double tstart = monotime_double();
+
+ if (authctxt == NULL)
+ fatal("No authentication or GSSAPI context");
+@@ -311,6 +312,8 @@ input_gssapi_exchange_complete(int type,
+ fatal_fr(r, "parse packet");
+
+ authenticated = mm_ssh_gssapi_userok(authctxt->user, authctxt->pw, 1);
++ if (!authenticated)
++ auth_failure_delay(authctxt, tstart);
+
+ authctxt->postponed = 0;
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+@@ -332,6 +335,7 @@ input_gssapi_mic(int type, u_int32_t ple
+ gss_buffer_desc mic, gssbuf;
+ u_char *p;
+ size_t len;
++ double tstart = monotime_double();
+
+ if (authctxt == NULL)
+ fatal("No authentication or GSSAPI context");
+@@ -367,6 +371,9 @@ input_gssapi_mic(int type, u_int32_t ple
+ free(micuser);
+ free(mic.value);
+
++ if (!authenticated)
++ auth_failure_delay(authctxt, tstart);
++
+ authctxt->postponed = 0;
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+diff --color -ruNp a/auth.h b/auth.h
+--- a/auth.h 2026-09-17 15:21:59.318365032 +0200
++++ b/auth.h 2026-09-17 15:23:03.388812848 +0200
+@@ -179,6 +179,7 @@ void auth_log(struct ssh *, int, int, co
+ void auth_maxtries_exceeded(struct ssh *) __attribute__((noreturn));
+ void userauth_finish(struct ssh *, int, const char *, const char *);
+ int auth_root_allowed(struct ssh *, const char *);
++void auth_failure_delay(Authctxt *, double);
+
+ char *auth2_read_banner(void);
+ int auth2_methods_valid(const char *, int);
diff --git a/openssh-9.9p1-copy-data-ext-self-copy.patch b/openssh-9.9p1-copy-data-ext-self-copy.patch
new file mode 100644
index 0000000..1fa43fc
--- /dev/null
+++ b/openssh-9.9p1-copy-data-ext-self-copy.patch
@@ -0,0 +1,51 @@
+diff --color -ruNp a/sftp-server.c b/sftp-server.c
+--- a/sftp-server.c 2026-07-17 16:23:12.293427062 +0200
++++ b/sftp-server.c 2026-07-17 16:29:01.480535500 +0200
+@@ -1625,6 +1625,7 @@ process_extended_copy_data(u_int32_t id)
+ u_int64_t len, read_off, read_len, write_off;
+ int r, copy_until_eof, status = SSH2_FX_OP_UNSUPPORTED;
+ size_t ret;
++ struct stat st_read, st_write;
+
+ if ((r = get_handle(iqueue, &read_handle)) != 0 ||
+ (r = sshbuf_get_u64(iqueue, &read_off)) != 0 ||
+@@ -1647,12 +1648,35 @@ process_extended_copy_data(u_int32_t id)
+ } else
+ copy_until_eof = 0;
+
++ /* Disallow reading & writing to the same handle, path or inode */
+ read_fd = handle_to_fd(read_handle);
+ write_fd = handle_to_fd(write_handle);
+-
+- /* Disallow reading & writing to the same handle or same path or dirs */
+- if (read_handle == write_handle || read_fd < 0 || write_fd < 0 ||
+- !strcmp(handle_to_name(read_handle), handle_to_name(write_handle))) {
++ if (read_fd < 0 || write_fd < 0) {
++ error_f("bad read or write fd");
++ status = errno_to_portable(EBADF);
++ goto out;
++ }
++ if (fstat(read_fd, &st_read) != 0) {
++ status = errno_to_portable(errno);
++ error_f("fstat read_fd failed: %s", strerror(errno));
++ goto out;
++ }
++ if (fstat(write_fd, &st_write) != 0) {
++ status = errno_to_portable(errno);
++ error_f("fstat write_fd failed: %s", strerror(errno));
++ goto out;
++ }
++ if (read_handle == write_handle ||
++ !strcmp(handle_to_name(read_handle), handle_to_name(write_handle)) ||
++ (st_read.st_dev != 0 && st_read.st_ino != 0 &&
++ st_read.st_dev == st_write.st_dev &&
++ st_read.st_ino == st_write.st_ino)) {
++ error_f("refusing to read/write same file: "
++ "read \"%s\" dev %lu ino %lu, write \"%s\" dev %lu ino %lu",
++ handle_to_name(read_handle),
++ (u_long)st_read.st_dev, (u_long)st_read.st_ino,
++ handle_to_name(write_handle),
++ (u_long)st_write.st_dev, (u_long)st_write.st_ino);
+ status = SSH2_FX_FAILURE;
+ goto out;
+ }
diff --git a/openssh-9.9p1-cve-2026-60002.patch b/openssh-9.9p1-cve-2026-60002.patch
new file mode 100644
index 0000000..ab16479
--- /dev/null
+++ b/openssh-9.9p1-cve-2026-60002.patch
@@ -0,0 +1,191 @@
+diff --color -ruNp a/ssh.c b/ssh.c
+--- a/ssh.c 2026-07-14 11:58:09.036496915 +0200
++++ b/ssh.c 2026-07-14 12:00:55.044542741 +0200
+@@ -619,26 +619,6 @@ set_addrinfo_port(struct addrinfo *addrs
+ }
+ }
+
+-static void
+-ssh_conn_info_free(struct ssh_conn_info *cinfo)
+-{
+- if (cinfo == NULL)
+- return;
+- free(cinfo->conn_hash_hex);
+- free(cinfo->shorthost);
+- free(cinfo->uidstr);
+- free(cinfo->keyalias);
+- free(cinfo->thishost);
+- free(cinfo->host_arg);
+- free(cinfo->portstr);
+- free(cinfo->remhost);
+- free(cinfo->remuser);
+- free(cinfo->homedir);
+- free(cinfo->locuser);
+- free(cinfo->jmphost);
+- free(cinfo);
+-}
+-
+ /*
+ * Main program for the ssh client.
+ */
+@@ -1765,8 +1745,8 @@ main(int ac, char **av)
+ ssh_signal(SIGCHLD, main_sigchld_handler);
+
+ /* Log into the remote system. Never returns if the login fails. */
+- ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
+- options.port, pw, timeout_ms, cinfo);
++ ssh_login(ssh, &sensitive_data, host, &hostaddr, options.port,
++ pw, timeout_ms, cinfo);
+
+ /* We no longer need the private host keys. Clear them now. */
+ if (sensitive_data.nkeys != 0) {
+diff --color -ruNp a/sshconnect2.c b/sshconnect2.c
+--- a/sshconnect2.c 2026-07-14 11:58:09.031477028 +0200
++++ b/sshconnect2.c 2026-07-14 12:01:56.374803123 +0200
+@@ -89,7 +89,7 @@ extern Options options;
+ */
+
+ static char *xxx_host;
+-static struct sockaddr *xxx_hostaddr;
++static struct sockaddr_storage xxx_hostaddr;
+ static const struct ssh_conn_info *xxx_conn_info;
+ static int key_type_allowed(struct sshkey *, const char *);
+
+@@ -105,7 +105,7 @@ verify_host_key_callback(struct sshkey *
+ fatal("Server host key %s not in HostKeyAlgorithms",
+ sshkey_ssh_name(hostkey));
+ }
+- if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,
++ if (verify_host_key(xxx_host, (struct sockaddr *)&xxx_hostaddr, hostkey,
+ xxx_conn_info) != 0)
+ fatal("Host key verification failed.");
+ return 0;
+@@ -222,8 +222,8 @@ order_hostkeyalgs(char *host, struct soc
+ }
+
+ void
+-ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
+- const struct ssh_conn_info *cinfo)
++ssh_kex2(struct ssh *ssh, char *host, struct sockaddr_storage *hostaddr,
++ u_short port, const struct ssh_conn_info *cinfo)
+ {
+ char *myproposal[PROPOSAL_MAX];
+ char *all_key, *hkalgs = NULL, *filtered_algs = NULL;
+@@ -234,9 +234,9 @@ ssh_kex2(struct ssh *ssh, char *host, st
+ char *gss_host = NULL;
+ #endif
+
+- xxx_host = host;
+- xxx_hostaddr = hostaddr;
+- xxx_conn_info = cinfo;
++ xxx_host = xstrdup(host);
++ xxx_hostaddr = *hostaddr;
++ xxx_conn_info = ssh_conn_info_dup(cinfo);
+
+ if (options.rekey_limit || options.rekey_interval)
+ ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
+@@ -259,8 +259,10 @@ ssh_kex2(struct ssh *ssh, char *host, st
+ fatal_fr(r, "kex_assemble_namelist");
+ free(all_key);
+
+- if (use_known_hosts_order)
+- hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);
++ if (use_known_hosts_order) {
++ hkalgs = order_hostkeyalgs(host, (struct sockaddr *)hostaddr,
++ port, cinfo);
++ }
+
+ filtered_algs = hkalgs ? match_filter_allowlist(hkalgs, options.pubkey_accepted_algos)
+ : match_filter_allowlist(options.hostkeyalgorithms,
+diff --color -ruNp a/sshconnect.c b/sshconnect.c
+--- a/sshconnect.c 2026-07-14 11:58:08.892659011 +0200
++++ b/sshconnect.c 2026-07-14 12:00:55.045767462 +0200
+@@ -84,6 +84,49 @@ extern char *__progname;
+ static int show_other_keys(struct hostkeys *, struct sshkey *);
+ static void warn_changed_key(struct sshkey *);
+
++void
++ssh_conn_info_free(struct ssh_conn_info *cinfo)
++{
++ if (cinfo == NULL)
++ return;
++ free(cinfo->conn_hash_hex);
++ free(cinfo->shorthost);
++ free(cinfo->uidstr);
++ free(cinfo->keyalias);
++ free(cinfo->thishost);
++ free(cinfo->host_arg);
++ free(cinfo->portstr);
++ free(cinfo->remhost);
++ free(cinfo->remuser);
++ free(cinfo->homedir);
++ free(cinfo->locuser);
++ free(cinfo->jmphost);
++ freezero(cinfo, sizeof(*cinfo));
++}
++
++struct ssh_conn_info *
++ssh_conn_info_dup(const struct ssh_conn_info *cinfo)
++{
++ struct ssh_conn_info *ret;
++
++ if (cinfo == NULL)
++ return NULL;
++ ret = xcalloc(1, sizeof(*ret));
++ ret->conn_hash_hex = xstrdup(cinfo->conn_hash_hex);
++ ret->shorthost = xstrdup(cinfo->shorthost);
++ ret->uidstr = xstrdup(cinfo->uidstr);
++ ret->keyalias = xstrdup(cinfo->keyalias);
++ ret->thishost = xstrdup(cinfo->thishost);
++ ret->host_arg = xstrdup(cinfo->host_arg);
++ ret->portstr = xstrdup(cinfo->portstr);
++ ret->remhost = xstrdup(cinfo->remhost);
++ ret->remuser = xstrdup(cinfo->remuser);
++ ret->homedir = xstrdup(cinfo->homedir);
++ ret->locuser = xstrdup(cinfo->locuser);
++ ret->jmphost = xstrdup(cinfo->jmphost);
++ return ret;
++}
++
+ /* Expand a proxy command */
+ static char *
+ expand_proxy_command(const char *proxy_command, const char *user,
+@@ -1589,8 +1632,8 @@ out:
+ */
+ void
+ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
+- struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms,
+- const struct ssh_conn_info *cinfo)
++ struct sockaddr_storage *hostaddr, u_short port, struct passwd *pw,
++ int timeout_ms, const struct ssh_conn_info *cinfo)
+ {
+ char *host;
+ char *server_user, *local_user;
+diff --color -ruNp a/sshconnect.h b/sshconnect.h
+--- a/sshconnect.h 2024-09-20 00:20:48.000000000 +0200
++++ b/sshconnect.h 2026-07-14 12:00:55.045948953 +0200
+@@ -73,7 +73,7 @@ int ssh_connect(struct ssh *, const cha
+ void ssh_kill_proxy_command(void);
+
+ void ssh_login(struct ssh *, Sensitive *, const char *,
+- struct sockaddr *, u_short, struct passwd *, int,
++ struct sockaddr_storage *, u_short, struct passwd *, int,
+ const struct ssh_conn_info *);
+
+ int verify_host_key(char *, struct sockaddr *, struct sshkey *,
+@@ -82,7 +82,7 @@ int verify_host_key(char *, struct sock
+ void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short,
+ char **, char **);
+
+-void ssh_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short,
++void ssh_kex2(struct ssh *ssh, char *, struct sockaddr_storage *, u_short,
+ const struct ssh_conn_info *);
+
+ void ssh_userauth2(struct ssh *ssh, const char *, const char *,
+@@ -98,3 +98,6 @@ void load_hostkeys_command(struct hostk
+ const struct sshkey *, const char *);
+
+ int hostkey_accepted_by_hostkeyalgs(const struct sshkey *);
++
++void ssh_conn_info_free(struct ssh_conn_info *);
++struct ssh_conn_info *ssh_conn_info_dup(const struct ssh_conn_info *);
diff --git a/openssh-9.9p1-gsissh.patch b/openssh-9.9p1-gsissh.patch
index 8abb9e8..24f5c02 100644
--- a/openssh-9.9p1-gsissh.patch
+++ b/openssh-9.9p1-gsissh.patch
@@ -1,7 +1,7 @@
diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c
---- openssh-9.9p1.orig/auth2.c 2026-03-25 09:33:50.361694147 +0100
-+++ openssh-9.9p1/auth2.c 2026-03-25 09:34:38.081444879 +0100
-@@ -286,7 +286,28 @@
+--- openssh-9.9p1.orig/auth2.c 2026-09-22 11:11:59.980257631 +0200
++++ openssh-9.9p1/auth2.c 2026-09-22 11:12:32.492921127 +0200
+@@ -292,7 +292,28 @@
(r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &method, NULL)) != 0)
goto out;
@@ -31,7 +31,7 @@ diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
#ifdef WITH_SELINUX
-@@ -299,11 +320,33 @@
+@@ -305,11 +326,33 @@
if (authctxt->attempt >= 1024)
auth_maxtries_exceeded(ssh);
@@ -69,7 +69,7 @@ diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c
authctxt->valid = 1;
debug2_f("setting up authctxt for %s", user);
} else {
-@@ -311,6 +354,9 @@
+@@ -317,6 +360,9 @@
/* Invalid user, fake password information */
authctxt->pw = fakepw();
}
@@ -79,7 +79,7 @@ diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c
#ifdef USE_PAM
if (options.use_pam)
mm_start_pam(ssh);
-@@ -318,6 +364,7 @@
+@@ -324,6 +370,7 @@
ssh_packet_set_log_preamble(ssh, "%suser %s",
authctxt->valid ? "authenticating " : "invalid ", user);
setproctitle("%s [net]", authctxt->valid ? user : "unknown");
@@ -87,7 +87,7 @@ diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c
authctxt->service = xstrdup(service);
authctxt->style = style ? xstrdup(style) : NULL;
#ifdef WITH_SELINUX
-@@ -333,9 +380,10 @@
+@@ -339,9 +386,10 @@
if (auth2_setup_methods_lists(authctxt) != 0)
ssh_packet_disconnect(ssh,
"no authentication methods enabled");
@@ -102,8 +102,8 @@ diff -Nur openssh-9.9p1.orig/auth2.c openssh-9.9p1/auth2.c
authctxt->user, authctxt->service, user, service);
}
diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c
---- openssh-9.9p1.orig/auth2-gss.c 2026-03-25 09:33:50.247721032 +0100
-+++ openssh-9.9p1/auth2-gss.c 2026-03-25 09:34:38.082271174 +0100
+--- openssh-9.9p1.orig/auth2-gss.c 2026-09-22 11:11:59.981302698 +0200
++++ openssh-9.9p1/auth2-gss.c 2026-09-22 11:22:00.615962500 +0200
@@ -54,6 +54,7 @@
extern struct authmethod_cfg methodcfg_gsskeyex;
extern struct authmethod_cfg methodcfg_gssapi;
@@ -228,12 +228,13 @@ diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c
/*
* This is called when the client thinks we've completed authentication.
* It should only be enabled in the dispatch handler by the function above,
-@@ -297,11 +347,13 @@
+@@ -297,12 +347,14 @@
input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
- int r, authenticated;
+ int r, authenticated = 0;
+ double tstart = monotime_double();
if (authctxt == NULL)
fatal("No authentication or GSSAPI context");
@@ -243,7 +244,7 @@ diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c
/*
* We don't need to check the status, because we're only enabled in
* the dispatcher once the exchange is complete
-@@ -310,7 +362,11 @@
+@@ -311,7 +363,11 @@
if ((r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
@@ -253,10 +254,10 @@ diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c
+ authenticated = mm_ssh_gssapi_userok(authctxt->user,
+ authctxt->pw, 1);
+ }
+ if (!authenticated)
+ auth_failure_delay(authctxt, tstart);
- authctxt->postponed = 0;
- ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-@@ -357,10 +413,16 @@
+@@ -361,10 +417,16 @@
fatal_f("sshbuf_mutable_ptr failed");
gssbuf.length = sshbuf_len(b);
@@ -276,7 +277,7 @@ diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c
sshbuf_free(b);
if (micuser != authctxt->user)
-@@ -376,6 +438,26 @@
+@@ -383,6 +445,26 @@
return 0;
}
@@ -304,8 +305,8 @@ diff -Nur openssh-9.9p1.orig/auth2-gss.c openssh-9.9p1/auth2-gss.c
&methodcfg_gsskeyex,
userauth_gsskeyex,
diff -Nur openssh-9.9p1.orig/auth.c openssh-9.9p1/auth.c
---- openssh-9.9p1.orig/auth.c 2026-03-25 09:33:50.448829611 +0100
-+++ openssh-9.9p1/auth.c 2026-03-25 09:34:38.082867201 +0100
+--- openssh-9.9p1.orig/auth.c 2026-09-22 11:11:59.920534332 +0200
++++ openssh-9.9p1/auth.c 2026-09-22 11:12:32.495347014 +0200
@@ -298,7 +298,8 @@
method,
submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
@@ -337,8 +338,8 @@ diff -Nur openssh-9.9p1.orig/auth.c openssh-9.9p1/auth.c
record_failed_login(ssh, user,
auth_get_canonical_hostname(ssh, options.use_dns), "ssh");
diff -Nur openssh-9.9p1.orig/auth.h openssh-9.9p1/auth.h
---- openssh-9.9p1.orig/auth.h 2026-03-25 09:33:50.363107669 +0100
-+++ openssh-9.9p1/auth.h 2026-03-25 09:34:38.083836881 +0100
+--- openssh-9.9p1.orig/auth.h 2026-09-22 11:11:59.981590619 +0200
++++ openssh-9.9p1/auth.h 2026-09-22 11:12:32.496447136 +0200
@@ -85,6 +85,8 @@
krb5_principal krb5_user;
char *krb5_ticket_file;
@@ -349,8 +350,8 @@ diff -Nur openssh-9.9p1.orig/auth.h openssh-9.9p1/auth.h
#endif
struct sshbuf *loginmsg;
diff -Nur openssh-9.9p1.orig/auth-pam.c openssh-9.9p1/auth-pam.c
---- openssh-9.9p1.orig/auth-pam.c 2026-03-25 09:33:50.403888480 +0100
-+++ openssh-9.9p1/auth-pam.c 2026-03-25 09:34:38.084567702 +0100
+--- openssh-9.9p1.orig/auth-pam.c 2026-09-22 11:11:59.871925590 +0200
++++ openssh-9.9p1/auth-pam.c 2026-09-22 11:12:32.497276479 +0200
@@ -248,6 +248,7 @@
static const char *sshpam_password = NULL;
static char *sshpam_rhost = NULL;
@@ -512,8 +513,8 @@ diff -Nur openssh-9.9p1.orig/auth-pam.c openssh-9.9p1/auth-pam.c
free(fake);
if (sshpam_err == PAM_MAXTRIES)
diff -Nur openssh-9.9p1.orig/auth-pam.h openssh-9.9p1/auth-pam.h
---- openssh-9.9p1.orig/auth-pam.h 2026-03-25 09:33:50.214552807 +0100
-+++ openssh-9.9p1/auth-pam.h 2026-03-25 09:34:38.085447286 +0100
+--- openssh-9.9p1.orig/auth-pam.h 2026-09-22 11:11:59.682913412 +0200
++++ openssh-9.9p1/auth-pam.h 2026-09-22 11:12:32.498665667 +0200
@@ -43,5 +43,6 @@
int sshpam_get_maxtries_reached(void);
void sshpam_set_maxtries_reached(int);
@@ -522,8 +523,8 @@ diff -Nur openssh-9.9p1.orig/auth-pam.h openssh-9.9p1/auth-pam.h
#endif /* USE_PAM */
diff -Nur openssh-9.9p1.orig/canohost.c openssh-9.9p1/canohost.c
---- openssh-9.9p1.orig/canohost.c 2026-03-25 09:33:50.249000599 +0100
-+++ openssh-9.9p1/canohost.c 2026-03-25 09:34:38.085680697 +0100
+--- openssh-9.9p1.orig/canohost.c 2026-09-22 11:11:59.719484447 +0200
++++ openssh-9.9p1/canohost.c 2026-09-22 11:12:32.499010251 +0200
@@ -17,6 +17,7 @@
#include <sys/types.h>
#include <sys/socket.h>
@@ -567,8 +568,8 @@ diff -Nur openssh-9.9p1.orig/canohost.c openssh-9.9p1/canohost.c
+ }
+}
diff -Nur openssh-9.9p1.orig/canohost.h openssh-9.9p1/canohost.h
---- openssh-9.9p1.orig/canohost.h 2026-03-25 09:33:50.249246231 +0100
-+++ openssh-9.9p1/canohost.h 2026-03-25 09:34:38.086742916 +0100
+--- openssh-9.9p1.orig/canohost.h 2026-09-22 11:11:59.719668822 +0200
++++ openssh-9.9p1/canohost.h 2026-09-22 11:12:32.499482192 +0200
@@ -26,4 +26,6 @@
#endif /* _CANOHOST_H */
@@ -577,8 +578,8 @@ diff -Nur openssh-9.9p1.orig/canohost.h openssh-9.9p1/canohost.h
+
void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac
---- openssh-9.9p1.orig/configure.ac 2026-03-25 09:33:50.437117119 +0100
-+++ openssh-9.9p1/configure.ac 2026-03-25 09:34:38.087853187 +0100
+--- openssh-9.9p1.orig/configure.ac 2026-09-22 11:11:59.908925585 +0200
++++ openssh-9.9p1/configure.ac 2026-09-22 11:12:32.500161138 +0200
@@ -4920,6 +4920,14 @@
AC_CHECK_HEADER([gssapi_krb5.h], ,
[ CPPFLAGS="$oldCPP" ])
@@ -636,8 +637,8 @@ diff -Nur openssh-9.9p1.orig/configure.ac openssh-9.9p1/configure.ac
PRIVSEP_PATH=/var/empty
diff -Nur openssh-9.9p1.orig/gss-genr.c openssh-9.9p1/gss-genr.c
---- openssh-9.9p1.orig/gss-genr.c 2026-03-25 09:33:50.470463510 +0100
-+++ openssh-9.9p1/gss-genr.c 2026-03-25 09:34:38.089271110 +0100
+--- openssh-9.9p1.orig/gss-genr.c 2026-09-22 11:11:59.983990516 +0200
++++ openssh-9.9p1/gss-genr.c 2026-09-22 11:12:32.502916899 +0200
@@ -41,6 +41,7 @@
#include "ssherr.h"
#include "sshbuf.h"
@@ -675,8 +676,8 @@ diff -Nur openssh-9.9p1.orig/gss-genr.c openssh-9.9p1/gss-genr.c
return (ctx->major);
}
diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
---- openssh-9.9p1.orig/gss-serv.c 2026-03-25 09:33:50.463850077 +0100
-+++ openssh-9.9p1/gss-serv.c 2026-03-25 09:34:38.090680651 +0100
+--- openssh-9.9p1.orig/gss-serv.c 2026-09-22 11:11:59.935043523 +0200
++++ openssh-9.9p1/gss-serv.c 2026-09-22 11:12:32.503802139 +0200
@@ -50,10 +50,12 @@
#include "monitor_wrap.h"
@@ -759,15 +760,15 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
/* Extract authentication indicators from the Kerberos ticket. Authentication
* indicators are GSSAPI name attributes for the name "auth-indicators".
* Multiple indicators might be present in the ticket.
-@@ -379,6 +412,7 @@
- (void) gss_release_buffer_set(&ctx->minor, &attrs);
- return (ctx->major);
+@@ -387,6 +420,7 @@
+ gss_release_buffer_set(&ctx->minor, &attrs);
+ return ctx->major;
}
+#endif
/* Extract the client details from a given context. This can only reliably
* be called once for a context */
-@@ -394,21 +428,24 @@
+@@ -401,21 +435,24 @@
gss_buffer_desc ename = GSS_C_EMPTY_BUFFER;
if (options.gss_store_rekey && client->used && ctx->client_creds) {
@@ -797,7 +798,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
new_name, &equal);
if (GSS_ERROR(ctx->major)) {
-@@ -423,9 +460,9 @@
+@@ -430,9 +467,9 @@
debug("Marking rekeyed credentials for export");
@@ -809,7 +810,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
client->creds = ctx->client_creds;
ctx->client_creds = GSS_C_NO_CREDENTIAL;
client->updated = 1;
-@@ -442,12 +479,17 @@
+@@ -449,12 +486,17 @@
i++;
}
@@ -829,7 +830,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
ssh_gssapi_error(ctx);
return (ctx->major);
}
-@@ -464,22 +506,33 @@
+@@ -471,22 +513,33 @@
return (ctx->major);
}
@@ -864,7 +865,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
return (ctx->major);
}
-@@ -487,6 +540,7 @@
+@@ -494,6 +547,7 @@
void
ssh_gssapi_cleanup_creds(void)
{
@@ -872,7 +873,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
krb5_ccache ccache = NULL;
krb5_error_code problem;
-@@ -502,6 +556,14 @@
+@@ -509,6 +563,14 @@
gssapi_client.store.data = NULL;
}
}
@@ -887,7 +888,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
}
/* As user */
-@@ -514,6 +576,11 @@
+@@ -521,6 +583,11 @@
}
if (gssapi_client.mech && gssapi_client.mech->storecreds) {
@@ -899,7 +900,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
return (*gssapi_client.mech->storecreds)(&gssapi_client);
} else
debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
-@@ -547,11 +614,13 @@
+@@ -554,11 +621,13 @@
(void) kex; /* used in privilege separation */
@@ -916,7 +917,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
if (gssapi_client.mech && gssapi_client.mech->userok)
if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
gssapi_client.used = 1;
-@@ -562,6 +631,7 @@
+@@ -569,6 +638,7 @@
gss_release_buffer(&lmin, &gssapi_client.displayname);
gss_release_buffer(&lmin, &gssapi_client.exportedname);
gss_release_cred(&lmin, &gssapi_client.creds);
@@ -924,7 +925,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
if (gssapi_client.indicators != NULL) {
for (i = 0; gssapi_client.indicators[i] != NULL; i++)
-@@ -579,6 +649,24 @@
+@@ -584,6 +654,24 @@
return (0);
}
@@ -949,7 +950,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
/* These bits are only used for rekeying. The unpriviledged child is running
* as the user, the monitor is root.
*
-@@ -605,9 +693,11 @@
+@@ -610,9 +698,11 @@
pam_handle_t *pamh = NULL;
struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL};
char *envstr;
@@ -962,7 +963,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
return;
ok = mm_ssh_gssapi_update_creds(&gssapi_client.store);
-@@ -627,6 +717,18 @@
+@@ -632,6 +722,18 @@
if (ret)
return;
@@ -983,7 +984,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv.c openssh-9.9p1/gss-serv.c
diff -Nur openssh-9.9p1.orig/gss-serv-gsi.c openssh-9.9p1/gss-serv-gsi.c
--- openssh-9.9p1.orig/gss-serv-gsi.c 1970-01-01 01:00:00.000000000 +0100
-+++ openssh-9.9p1/gss-serv-gsi.c 2026-03-25 09:34:38.091695448 +0100
++++ openssh-9.9p1/gss-serv-gsi.c 2026-09-22 11:12:32.505018045 +0200
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -1314,9 +1315,9 @@ diff -Nur openssh-9.9p1.orig/gss-serv-gsi.c openssh-9.9p1/gss-serv-gsi.c
+#endif /* GSI */
+#endif /* GSSAPI */
diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c
---- openssh-9.9p1.orig/gss-serv-krb5.c 2026-03-25 09:33:50.438643924 +0100
-+++ openssh-9.9p1/gss-serv-krb5.c 2026-03-25 09:34:38.111350877 +0100
-@@ -431,6 +431,34 @@
+--- openssh-9.9p1.orig/gss-serv-krb5.c 2026-09-22 11:11:59.910840837 +0200
++++ openssh-9.9p1/gss-serv-krb5.c 2026-09-22 11:12:32.505209951 +0200
+@@ -459,6 +459,34 @@
return found_principal;
}
@@ -1351,7 +1352,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c
/* This writes out any forwarded credentials from the structure populated
* during userauth. Called after we have setuid to the user */
-@@ -525,7 +553,7 @@
+@@ -553,7 +581,7 @@
return set_env;
}
@@ -1360,7 +1361,7 @@ diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c
ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store,
ssh_gssapi_client *client)
{
-@@ -596,7 +624,7 @@
+@@ -624,7 +652,7 @@
{9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
NULL,
&ssh_gssapi_krb5_userok,
@@ -1370,8 +1371,8 @@ diff -Nur openssh-9.9p1.orig/gss-serv-krb5.c openssh-9.9p1/gss-serv-krb5.c
&ssh_gssapi_krb5_updatecreds
};
diff -Nur openssh-9.9p1.orig/kexgsss.c openssh-9.9p1/kexgsss.c
---- openssh-9.9p1.orig/kexgsss.c 2026-03-25 09:33:50.255131427 +0100
-+++ openssh-9.9p1/kexgsss.c 2026-03-25 09:34:38.111862186 +0100
+--- openssh-9.9p1.orig/kexgsss.c 2026-09-22 11:11:59.724068583 +0200
++++ openssh-9.9p1/kexgsss.c 2026-09-22 11:12:32.505708198 +0200
@@ -48,6 +48,7 @@
#include "digest.h"
#include "ssherr.h"
@@ -1408,7 +1409,7 @@ diff -Nur openssh-9.9p1.orig/kexgsss.c openssh-9.9p1/kexgsss.c
}
if (!(*ret_flags & GSS_C_MUTUAL_FLAG))
-@@ -598,4 +602,26 @@
+@@ -600,4 +604,26 @@
return kexgssgex_final(ssh, &send_tok, &ret_flags);
}
@@ -1436,8 +1437,8 @@ diff -Nur openssh-9.9p1.orig/kexgsss.c openssh-9.9p1/kexgsss.c
+
#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */
diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in
---- openssh-9.9p1.orig/Makefile.in 2026-03-25 09:33:50.411229243 +0100
-+++ openssh-9.9p1/Makefile.in 2026-03-25 09:34:38.112504938 +0100
+--- openssh-9.9p1.orig/Makefile.in 2026-09-22 11:11:59.880188178 +0200
++++ openssh-9.9p1/Makefile.in 2026-09-22 11:12:32.506133264 +0200
@@ -138,6 +138,7 @@
auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \
monitor.o monitor_wrap.o auth-krb5.o kexgsss.o \
@@ -1447,8 +1448,8 @@ diff -Nur openssh-9.9p1.orig/Makefile.in openssh-9.9p1/Makefile.in
sftp-server.o sftp-common.o \
sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c
---- openssh-9.9p1.orig/misc.c 2026-03-25 09:33:50.471827794 +0100
-+++ openssh-9.9p1/misc.c 2026-03-25 09:34:38.112680450 +0100
+--- openssh-9.9p1.orig/misc.c 2026-09-22 11:11:59.985342483 +0200
++++ openssh-9.9p1/misc.c 2026-09-22 11:12:32.507145652 +0200
@@ -440,11 +440,14 @@
#define WHITESPACE " \t\r\n"
#define QUOTE "\""
@@ -1509,8 +1510,8 @@ diff -Nur openssh-9.9p1.orig/misc.c openssh-9.9p1/misc.c
* Convert ASCII string to TCP/IP port number.
* Port must be >=0 and <=65535.
diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h
---- openssh-9.9p1.orig/misc.h 2026-03-25 09:33:50.417416573 +0100
-+++ openssh-9.9p1/misc.h 2026-03-25 09:34:38.113574002 +0100
+--- openssh-9.9p1.orig/misc.h 2026-09-22 11:11:59.887294245 +0200
++++ openssh-9.9p1/misc.h 2026-09-22 11:12:32.508664728 +0200
@@ -112,6 +112,7 @@
void sock_set_v6only(int);
@@ -1520,8 +1521,8 @@ diff -Nur openssh-9.9p1.orig/misc.h openssh-9.9p1/misc.h
typedef void privdrop_fn(struct passwd *);
diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c
---- openssh-9.9p1.orig/monitor.c 2026-03-25 09:33:50.472404405 +0100
-+++ openssh-9.9p1/monitor.c 2026-03-25 09:34:38.114300004 +0100
+--- openssh-9.9p1.orig/monitor.c 2026-09-22 11:11:59.985894361 +0200
++++ openssh-9.9p1/monitor.c 2026-09-22 11:12:32.508921125 +0200
@@ -148,6 +148,9 @@
int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *);
int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *);
@@ -1692,8 +1693,8 @@ diff -Nur openssh-9.9p1.orig/monitor.c openssh-9.9p1/monitor.c
{
gss_buffer_desc data;
diff -Nur openssh-9.9p1.orig/monitor.h openssh-9.9p1/monitor.h
---- openssh-9.9p1.orig/monitor.h 2026-03-25 09:33:50.366536539 +0100
-+++ openssh-9.9p1/monitor.h 2026-03-25 09:34:38.115101925 +0100
+--- openssh-9.9p1.orig/monitor.h 2026-09-22 11:11:59.835960175 +0200
++++ openssh-9.9p1/monitor.h 2026-09-22 11:12:32.510720435 +0200
@@ -75,6 +75,10 @@
MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151,
@@ -1706,8 +1707,8 @@ diff -Nur openssh-9.9p1.orig/monitor.h openssh-9.9p1/monitor.h
struct ssh;
diff -Nur openssh-9.9p1.orig/monitor_wrap.c openssh-9.9p1/monitor_wrap.c
---- openssh-9.9p1.orig/monitor_wrap.c 2026-03-25 09:33:50.372322000 +0100
-+++ openssh-9.9p1/monitor_wrap.c 2026-03-25 09:34:38.115448828 +0100
+--- openssh-9.9p1.orig/monitor_wrap.c 2026-09-22 11:11:59.842260271 +0200
++++ openssh-9.9p1/monitor_wrap.c 2026-09-22 11:12:32.510921124 +0200
@@ -1139,6 +1139,94 @@
return (authenticated);
}
@@ -1804,8 +1805,8 @@ diff -Nur openssh-9.9p1.orig/monitor_wrap.c openssh-9.9p1/monitor_wrap.c
mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
{
diff -Nur openssh-9.9p1.orig/monitor_wrap.h openssh-9.9p1/monitor_wrap.h
---- openssh-9.9p1.orig/monitor_wrap.h 2026-03-25 09:33:50.374854035 +0100
-+++ openssh-9.9p1/monitor_wrap.h 2026-03-25 09:34:38.115832467 +0100
+--- openssh-9.9p1.orig/monitor_wrap.h 2026-09-22 11:11:59.842639260 +0200
++++ openssh-9.9p1/monitor_wrap.h 2026-09-22 11:12:32.511921124 +0200
@@ -72,6 +72,10 @@
int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex);
OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
@@ -1818,9 +1819,9 @@ diff -Nur openssh-9.9p1.orig/monitor_wrap.h openssh-9.9p1/monitor_wrap.h
#endif
diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c
---- openssh-9.9p1.orig/readconf.c 2026-03-25 09:33:50.473798512 +0100
-+++ openssh-9.9p1/readconf.c 2026-03-25 09:34:38.116680413 +0100
-@@ -2812,11 +2812,11 @@
+--- openssh-9.9p1.orig/readconf.c 2026-09-22 11:11:59.987164427 +0200
++++ openssh-9.9p1/readconf.c 2026-09-22 11:12:32.513050248 +0200
+@@ -2810,11 +2810,11 @@
if (options->pubkey_authentication == -1)
options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL;
if (options->gss_authentication == -1)
@@ -1836,8 +1837,8 @@ diff -Nur openssh-9.9p1.orig/readconf.c openssh-9.9p1/readconf.c
options->gss_trust_dns = 0;
if (options->gss_renewal_rekey == -1)
diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h
---- openssh-9.9p1.orig/readconf.h 2026-03-25 09:33:50.259743691 +0100
-+++ openssh-9.9p1/readconf.h 2026-03-25 09:34:38.117292644 +0100
+--- openssh-9.9p1.orig/readconf.h 2026-09-22 11:11:59.960094972 +0200
++++ openssh-9.9p1/readconf.h 2026-09-22 11:12:32.513985509 +0200
@@ -80,6 +80,8 @@
char *host_key_alias; /* hostname alias for .ssh/known_hosts */
char *proxy_command; /* Proxy command for connecting the host. */
@@ -1848,8 +1849,8 @@ diff -Nur openssh-9.9p1.orig/readconf.h openssh-9.9p1/readconf.h
u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */
diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
---- openssh-9.9p1.orig/servconf.c 2026-03-25 09:33:50.474757506 +0100
-+++ openssh-9.9p1/servconf.c 2026-03-25 10:25:51.442170347 +0100
+--- openssh-9.9p1.orig/servconf.c 2026-09-22 11:11:59.987925574 +0200
++++ openssh-9.9p1/servconf.c 2026-09-22 11:12:32.514843394 +0200
@@ -95,6 +95,7 @@
/* Portable-specific options */
options->use_pam = -1;
@@ -1895,7 +1896,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
if (options->gss_store_rekey == -1)
options->gss_store_rekey = 0;
#ifdef GSSAPI
-@@ -580,7 +586,7 @@
+@@ -581,7 +587,7 @@
typedef enum {
sBadOption, /* == unknown option */
/* Portable-specific options */
@@ -1904,7 +1905,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
/* Standard Options */
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
-@@ -602,6 +608,8 @@
+@@ -603,6 +609,8 @@
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sGssDelegateCreds,
sGssEnablek5users, sGssStrictAcceptor,
@@ -1913,7 +1914,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
sGssKeyEx, sGssIndicators, sGssKexAlgorithms, sGssStoreRekey,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
-@@ -636,9 +644,11 @@
+@@ -637,9 +645,11 @@
#ifdef USE_PAM
{ "usepam", sUsePAM, SSHCFG_GLOBAL },
{ "pamservicename", sPAMServiceName, SSHCFG_ALL },
@@ -1925,7 +1926,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
#endif
{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
/* Standard Options */
-@@ -694,6 +704,12 @@
+@@ -695,6 +705,12 @@
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
{ "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
{ "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_GLOBAL },
@@ -1938,7 +1939,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
-@@ -705,6 +721,8 @@
+@@ -706,6 +722,8 @@
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
{ "gssapidelegatecredentials", sUnsupported, SSHCFG_GLOBAL },
@@ -1947,7 +1948,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
-@@ -779,6 +797,8 @@
+@@ -780,6 +798,8 @@
{ "permitlisten", sPermitListen, SSHCFG_ALL },
{ "forcecommand", sForceCommand, SSHCFG_ALL },
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
@@ -1956,7 +1957,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
-@@ -1449,6 +1469,10 @@
+@@ -1451,6 +1471,10 @@
*charptr = xstrdup(arg);
break;
@@ -1967,7 +1968,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
/* Standard Options */
case sBadOption:
goto out;
-@@ -1712,6 +1736,10 @@
+@@ -1714,6 +1738,10 @@
intptr = &options->gss_deleg_creds;
goto parse_flag;
@@ -1978,7 +1979,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
case sGssStrictAcceptor:
intptr = &options->gss_strict_acceptor;
goto parse_flag;
-@@ -1741,6 +1769,12 @@
+@@ -1743,6 +1771,12 @@
options->gss_indicators = xstrdup(arg);
break;
@@ -1991,7 +1992,7 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
case sPasswordAuthentication:
intptr = &options->password_authentication;
goto parse_flag;
-@@ -3010,6 +3044,7 @@
+@@ -3014,6 +3048,7 @@
M_CP_INTOPT(password_authentication);
M_CP_INTOPT(gss_authentication);
@@ -2000,8 +2001,8 @@ diff -Nur openssh-9.9p1.orig/servconf.c openssh-9.9p1/servconf.c
M_CP_INTOPT(pubkey_auth_options);
M_CP_INTOPT(kerberos_authentication);
diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h
---- openssh-9.9p1.orig/servconf.h 2026-03-25 09:33:50.464980881 +0100
-+++ openssh-9.9p1/servconf.h 2026-03-25 09:46:47.987930866 +0100
+--- openssh-9.9p1.orig/servconf.h 2026-09-22 11:11:59.936404684 +0200
++++ openssh-9.9p1/servconf.h 2026-09-22 11:12:32.515626582 +0200
@@ -155,10 +155,12 @@
* be stored in per-session ccache */
int use_kuserok;
@@ -2024,8 +2025,8 @@ diff -Nur openssh-9.9p1.orig/servconf.h openssh-9.9p1/servconf.h
int permit_tun;
diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1
---- openssh-9.9p1.orig/ssh.1 2026-03-25 09:33:50.389637598 +0100
-+++ openssh-9.9p1/ssh.1 2026-03-25 09:34:38.120502979 +0100
+--- openssh-9.9p1.orig/ssh.1 2026-09-22 11:11:59.857734886 +0200
++++ openssh-9.9p1/ssh.1 2026-09-22 11:12:32.516173126 +0200
@@ -1523,6 +1523,18 @@
on to new connections).
.It Ev USER
@@ -2046,8 +2047,8 @@ diff -Nur openssh-9.9p1.orig/ssh.1 openssh-9.9p1/ssh.1
.Pp
Additionally,
diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c
---- openssh-9.9p1.orig/ssh.c 2026-03-25 09:33:50.460316864 +0100
-+++ openssh-9.9p1/ssh.c 2026-03-25 09:34:38.120680376 +0100
+--- openssh-9.9p1.orig/ssh.c 2026-09-22 11:11:59.978010980 +0200
++++ openssh-9.9p1/ssh.c 2026-09-22 11:12:32.517284751 +0200
@@ -585,6 +585,38 @@
fatal("Can't open user config file %.100s: "
"%.100s", config, strerror(errno));
@@ -2087,7 +2088,7 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c
r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
_PATH_SSH_USER_CONFFILE);
if (r > 0 && (size_t)r < sizeof(buf))
-@@ -1318,8 +1350,12 @@
+@@ -1266,8 +1298,12 @@
if (fill_default_options(&options) != 0)
cleanup_exit(255);
@@ -2102,8 +2103,8 @@ diff -Nur openssh-9.9p1.orig/ssh.c openssh-9.9p1/ssh.c
/*
* If ProxyJump option specified, then construct a ProxyCommand now.
diff -Nur openssh-9.9p1.orig/ssh_config openssh-9.9p1/ssh_config
---- openssh-9.9p1.orig/ssh_config 2026-03-25 09:33:50.262532812 +0100
-+++ openssh-9.9p1/ssh_config 2026-03-25 09:34:38.121528811 +0100
+--- openssh-9.9p1.orig/ssh_config 2026-09-22 11:11:59.730208494 +0200
++++ openssh-9.9p1/ssh_config 2026-09-22 11:12:32.517828512 +0200
@@ -22,9 +22,9 @@
# ForwardX11 no
# PasswordAuthentication yes
@@ -2118,8 +2119,8 @@ diff -Nur openssh-9.9p1.orig/ssh_config openssh-9.9p1/ssh_config
# BatchMode no
# CheckHostIP no
diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5
---- openssh-9.9p1.orig/ssh_config.5 2026-03-25 09:33:50.405557553 +0100
-+++ openssh-9.9p1/ssh_config.5 2026-03-25 09:34:38.122152007 +0100
+--- openssh-9.9p1.orig/ssh_config.5 2026-09-22 11:11:59.873925590 +0200
++++ openssh-9.9p1/ssh_config.5 2026-09-22 11:12:32.518246391 +0200
@@ -52,6 +52,12 @@
user's configuration file
.Pq Pa ~/.ssh/config
@@ -2167,9 +2168,9 @@ diff -Nur openssh-9.9p1.orig/ssh_config.5 openssh-9.9p1/ssh_config.5
.Ed
.It Cm ProxyCommand
diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c
---- openssh-9.9p1.orig/sshconnect2.c 2026-03-25 09:33:50.456077275 +0100
-+++ openssh-9.9p1/sshconnect2.c 2026-03-25 09:34:38.122746009 +0100
-@@ -860,6 +860,11 @@
+--- openssh-9.9p1.orig/sshconnect2.c 2026-09-22 11:11:59.965745669 +0200
++++ openssh-9.9p1/sshconnect2.c 2026-09-22 11:12:32.519597227 +0200
+@@ -867,6 +867,11 @@
gss_OID mech = NULL;
char *gss_host = NULL;
@@ -2181,7 +2182,7 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c
if (options.gss_server_identity) {
gss_host = xstrdup(options.gss_server_identity);
} else if (options.gss_trust_dns) {
-@@ -968,7 +973,8 @@
+@@ -975,7 +980,8 @@
if (status == GSS_S_COMPLETE) {
/* send either complete or MIC, depending on mechanism */
@@ -2191,7 +2192,7 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c
if ((r = sshpkt_start(ssh,
SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
-@@ -1135,6 +1141,20 @@
+@@ -1142,6 +1148,20 @@
return r;
}
@@ -2212,7 +2213,7 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c
int
userauth_gsskeyex(struct ssh *ssh)
{
-@@ -1157,6 +1177,12 @@
+@@ -1164,6 +1184,12 @@
if ((b = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
@@ -2225,7 +2226,7 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c
ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service,
"gssapi-keyex", ssh->kex->session_id);
-@@ -1170,7 +1196,9 @@
+@@ -1177,7 +1203,9 @@
}
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
@@ -2237,8 +2238,8 @@ diff -Nur openssh-9.9p1.orig/sshconnect2.c openssh-9.9p1/sshconnect2.c
(r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
(r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 ||
diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8
---- openssh-9.9p1.orig/sshd.8 2026-03-25 09:33:50.278816152 +0100
-+++ openssh-9.9p1/sshd.8 2026-03-25 09:34:38.123594583 +0100
+--- openssh-9.9p1.orig/sshd.8 2026-09-22 11:11:59.745058855 +0200
++++ openssh-9.9p1/sshd.8 2026-09-22 11:12:32.520228070 +0200
@@ -840,6 +840,29 @@
# A CA key, accepted for any host in *.mydomain.com or *.mydomain.org
@cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W...
@@ -2270,8 +2271,8 @@ diff -Nur openssh-9.9p1.orig/sshd.8 openssh-9.9p1/sshd.8
.Bl -tag -width Ds -compact
.It Pa ~/.hushlogin
diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config
---- openssh-9.9p1.orig/sshd_config 2026-03-25 09:33:50.303016028 +0100
-+++ openssh-9.9p1/sshd_config 2026-03-25 09:34:38.124023480 +0100
+--- openssh-9.9p1.orig/sshd_config 2026-09-22 11:11:59.767232271 +0200
++++ openssh-9.9p1/sshd_config 2026-09-22 11:12:32.520966150 +0200
@@ -76,10 +76,11 @@
#KerberosUseKuserok yes
@@ -2298,8 +2299,8 @@ diff -Nur openssh-9.9p1.orig/sshd_config openssh-9.9p1/sshd_config
#AllowTcpForwarding yes
#GatewayPorts no
diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5
---- openssh-9.9p1.orig/sshd_config.5 2026-03-25 09:33:50.465574045 +0100
-+++ openssh-9.9p1/sshd_config.5 2026-03-25 09:56:30.278555815 +0100
+--- openssh-9.9p1.orig/sshd_config.5 2026-09-22 11:11:59.937230921 +0200
++++ openssh-9.9p1/sshd_config.5 2026-09-22 11:12:32.521439640 +0200
@@ -724,15 +724,30 @@
to allow the client to select the address to which the forwarding is bound.
The default is
@@ -2331,7 +2332,7 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5
+Currently only implemented for the GSI mechanism.
.It Cm GSSAPIDelegateCredentials
Accept delegated credentials on the server side. The default is
- .CM yes .
+ .Cm yes .
@@ -746,7 +761,7 @@
Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange
doesn't rely on ssh keys to verify host identity.
@@ -2341,7 +2342,7 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5
.It Cm GSSAPIStrictAcceptorCheck
Determines whether to be strict about the identity of the GSSAPI acceptor
a client authenticates against.
-@@ -2096,6 +2111,12 @@
+@@ -2098,6 +2113,12 @@
as a non-root user.
The default is
.Cm no .
@@ -2355,8 +2356,8 @@ diff -Nur openssh-9.9p1.orig/sshd_config.5 openssh-9.9p1/sshd_config.5
Optionally specifies additional text to append to the SSH protocol banner
sent by the server upon connection.
diff -Nur openssh-9.9p1.orig/sshd_config_redhat openssh-9.9p1/sshd_config_redhat
---- openssh-9.9p1.orig/sshd_config_redhat 2026-03-25 09:33:50.242937866 +0100
-+++ openssh-9.9p1/sshd_config_redhat 2026-03-25 09:34:38.125435117 +0100
+--- openssh-9.9p1.orig/sshd_config_redhat 2026-09-22 11:11:59.713996868 +0200
++++ openssh-9.9p1/sshd_config_redhat 2026-09-22 11:12:32.521959472 +0200
@@ -2,9 +2,6 @@
ChallengeResponseAuthentication no
@@ -2368,8 +2369,8 @@ diff -Nur openssh-9.9p1.orig/sshd_config_redhat openssh-9.9p1/sshd_config_redhat
X11Forwarding yes
diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c
---- openssh-9.9p1.orig/sshd-session.c 2026-03-25 09:33:50.476356457 +0100
-+++ openssh-9.9p1/sshd-session.c 2026-03-25 09:34:38.126169151 +0100
+--- openssh-9.9p1.orig/sshd-session.c 2026-09-22 11:11:59.989485280 +0200
++++ openssh-9.9p1/sshd-session.c 2026-09-22 11:12:32.522274647 +0200
@@ -1486,7 +1486,7 @@
#endif
@@ -2380,8 +2381,8 @@ diff -Nur openssh-9.9p1.orig/sshd-session.c openssh-9.9p1/sshd-session.c
authctxt->krb5_set_env = ssh_gssapi_storecreds();
restore_uid();
diff -Nur openssh-9.9p1.orig/ssh-gss.h openssh-9.9p1/ssh-gss.h
---- openssh-9.9p1.orig/ssh-gss.h 2026-03-25 09:33:50.440761798 +0100
-+++ openssh-9.9p1/ssh-gss.h 2026-03-25 09:34:38.126851573 +0100
+--- openssh-9.9p1.orig/ssh-gss.h 2026-09-22 11:11:59.912508776 +0200
++++ openssh-9.9p1/ssh-gss.h 2026-09-22 11:12:32.523171631 +0200
@@ -110,12 +110,14 @@
} ssh_gssapi_ccache;
@@ -2419,7 +2420,7 @@ diff -Nur openssh-9.9p1.orig/ssh-gss.h openssh-9.9p1/ssh-gss.h
const char *);
diff -Nur openssh-9.9p1.orig/version.h openssh-9.9p1/version.h
--- openssh-9.9p1.orig/version.h 2024-09-20 00:20:48.000000000 +0200
-+++ openssh-9.9p1/version.h 2026-03-25 09:34:38.127196380 +0100
++++ openssh-9.9p1/version.h 2026-09-22 11:12:32.523669865 +0200
@@ -2,5 +2,19 @@
#define SSH_VERSION "OpenSSH_9.9"
diff --git a/openssh-9.9p1-scp-remote-glob.patch b/openssh-9.9p1-scp-remote-glob.patch
new file mode 100644
index 0000000..c08101e
--- /dev/null
+++ b/openssh-9.9p1-scp-remote-glob.patch
@@ -0,0 +1,14 @@
+diff --color -ruNp a/scp.c b/scp.c
+--- a/scp.c 2026-07-14 11:40:47.754600847 +0200
++++ b/scp.c 2026-07-14 11:43:04.077524517 +0200
+@@ -2070,6 +2070,10 @@ throughlocal_sftp(struct sftp_conn *from
+ goto out;
+ }
+
++ /* Special handling for source of '..' */
++ if (strcmp(filename, "..") == 0)
++ filename = "."; /* Download to dest, not dest/.. */
++
+ if (targetisdir)
+ abs_dst = sftp_path_append(target, filename);
+ else
diff --git a/openssh-9.9p1-sshd-no-delegate-credentials.patch b/openssh-9.9p1-sshd-no-delegate-credentials.patch
index 59d0120..7132c9b 100644
--- a/openssh-9.9p1-sshd-no-delegate-credentials.patch
+++ b/openssh-9.9p1-sshd-no-delegate-credentials.patch
@@ -111,7 +111,7 @@ diff --color -ruNp a/sshd_config.5 b/sshd_config.5
.Cm yes .
+.It Cm GSSAPIDelegateCredentials
+Accept delegated credentials on the server side. The default is
-+.CM yes .
++.Cm yes .
.It Cm GSSAPIEnablek5users
Specifies whether to look at .k5users file for GSSAPI authentication
access control. Further details are described in
diff --git a/openssh-9.9p1-support-authentication-indicators-in-GSSAPI.patch b/openssh-9.9p1-support-authentication-indicators-in-GSSAPI.patch
index 6c55a66..ef70379 100644
--- a/openssh-9.9p1-support-authentication-indicators-in-GSSAPI.patch
+++ b/openssh-9.9p1-support-authentication-indicators-in-GSSAPI.patch
@@ -10,8 +10,8 @@ diff --color -ruNp a/configure.ac b/configure.ac
AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1],
[Define this if you want to use libkafs' AFS support])])
diff --color -ruNp a/gss-serv.c b/gss-serv.c
---- a/gss-serv.c 2026-03-10 12:43:36.802443034 +0100
-+++ b/gss-serv.c 2026-03-12 10:04:37.520993330 +0100
+--- a/gss-serv.c 2026-06-16 15:38:26.590728235 +0200
++++ b/gss-serv.c 2026-06-16 15:41:13.717696103 +0200
@@ -53,7 +53,7 @@ extern ServerOptions options;
static ssh_gssapi_client gssapi_client =
@@ -21,7 +21,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c
ssh_gssapi_mech gssapi_null_mech =
{ NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL};
-@@ -295,6 +295,95 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss
+@@ -295,6 +295,99 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss
return GSS_S_COMPLETE;
}
@@ -44,63 +44,67 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c
+ int is_mechname, authenticated, complete, more;
+ size_t count, i;
+
++ /* always initialize client->indicators */
++ client->indicators = NULL;
++
+ ctx->major = gss_inquire_name(&ctx->minor, gss_name,
+ &is_mechname, NULL, &attrs);
-+ if (ctx->major != GSS_S_COMPLETE) {
-+ return (ctx->major);
-+ }
++ if (ctx->major != GSS_S_COMPLETE)
++ return ctx->major;
+
+ if (attrs == GSS_C_NO_BUFFER_SET) {
-+ /* No indicators in the ticket */
-+ return (0);
++ /* no indicators in the ticket */
++ return GSS_S_COMPLETE;
+ }
+
-+ client->indicators = NULL;
++ /* client->indicators is NULL terminated */
+ count = 0;
++ client->indicators = xcalloc(count + 1, sizeof(char *));
++
+ for (i = 0; i < attrs->count; i++) {
+ authenticated = 0;
+ complete = 0;
+ more = -1;
++
+ /* skip anything but auth-indicators */
+ if (((sizeof(AUTH_INDICATORS_TAG) - 1) != attrs->elements[i].length) ||
-+ memcmp(AUTH_INDICATORS_TAG,
-+ attrs->elements[i].value,
++ memcmp(AUTH_INDICATORS_TAG, attrs->elements[i].value,
+ sizeof(AUTH_INDICATORS_TAG) - 1) != 0)
+ continue;
++
+ /* retrieve all indicators */
+ while (more != 0) {
+ value.value = NULL;
+ display_value.value = NULL;
++
+ ctx->major = gss_get_name_attribute(&ctx->minor, gss_name,
-+ &attrs->elements[i], &authenticated,
-+ &complete, &value, &display_value, &more);
++ &attrs->elements[i],
++ &authenticated, &complete,
++ &value, &display_value, &more);
+ if (ctx->major != GSS_S_COMPLETE)
+ goto out;
+
-+ if ((value.value != NULL) && authenticated) {
-+ if (count >= SSH_GSSAPI_MAX_INDICATORS) {
-+ logit("ssh_gssapi_getindicators: too many "
-+ "indicators, truncating at %d",
-+ SSH_GSSAPI_MAX_INDICATORS);
-+ /* value/display_value released at out: */
-+ goto done;
-+ }
++ if (value.value == NULL || !authenticated)
++ continue;
+
-+ client->indicators = xrecallocarray(client->indicators, count, count + 1, sizeof(char*));
-+ if (client->indicators == NULL) {
-+ fatal("ssh_gssapi_getindicators failed to allocate memory");
-+ }
-+ client->indicators[count] = xmalloc(value.length + 1);
-+ memcpy(client->indicators[count], value.value, value.length);
-+ client->indicators[count][value.length] = '\0';
-+ count++;
++ if (count >= SSH_GSSAPI_MAX_INDICATORS) {
++ logit("ssh_gssapi_getindicators:"
++ " too many indicators, truncating at %d",
++ SSH_GSSAPI_MAX_INDICATORS);
++ goto out;
+ }
++
++ client->indicators[count] = xmalloc(value.length + 1);
++ memcpy(client->indicators[count], value.value, value.length);
++ client->indicators[count][value.length] = '\0';
++ count++;
++
++ /* add NULL terminator */
++ client->indicators = xrecallocarray(client->indicators, count,
++ count + 1, sizeof(char *));
+ }
+ }
+
-+done:
-+ /* slot [count] is zeroed by recallocarray, serves as NULL sentinel */
-+
+out:
+ if (ctx->major != GSS_S_COMPLETE && client->indicators != NULL) {
+ for (i = 0; i < count; i++)
@@ -108,16 +112,16 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c
+ free(client->indicators);
+ client->indicators = NULL;
+ }
-+ (void) gss_release_buffer(&ctx->minor, &value);
-+ (void) gss_release_buffer(&ctx->minor, &display_value);
-+ (void) gss_release_buffer_set(&ctx->minor, &attrs);
-+ return (ctx->major);
++ gss_release_buffer(&ctx->minor, &value);
++ gss_release_buffer(&ctx->minor, &display_value);
++ gss_release_buffer_set(&ctx->minor, &attrs);
++ return ctx->major;
+}
+
/* Extract the client details from a given context. This can only reliably
* be called once for a context */
-@@ -384,6 +473,12 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g
+@@ -384,6 +477,12 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g
}
gss_release_buffer(&ctx->minor, &ename);
@@ -130,7 +134,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c
/* We can't copy this structure, so we just move the pointer to it */
client->creds = ctx->client_creds;
-@@ -446,6 +541,7 @@ int
+@@ -446,6 +545,7 @@ int
ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
{
OM_uint32 lmin;
@@ -138,7 +142,7 @@ diff --color -ruNp a/gss-serv.c b/gss-serv.c
(void) kex; /* used in privilege separation */
-@@ -464,8 +560,14 @@ ssh_gssapi_userok(char *user, struct pas
+@@ -464,8 +564,14 @@ ssh_gssapi_userok(char *user, struct pas
gss_release_buffer(&lmin, &gssapi_client.displayname);
gss_release_buffer(&lmin, &gssapi_client.exportedname);
gss_release_cred(&lmin, &gssapi_client.creds);
@@ -166,7 +170,7 @@ diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c
#include "ssh-gss.h"
-@@ -87,6 +88,33 @@ ssh_gssapi_krb5_init(void)
+@@ -87,6 +88,42 @@ ssh_gssapi_krb5_init(void)
return 1;
}
@@ -174,6 +178,10 @@ diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c
+ * one of indicators in the list of allowed/denied rules.
+ * In case of the match, apply the decision from the rule.
+ * In case of no indicator from the ticket matching the rule, deny
++ *
++ * Returns -1 on any negative match
++ * Returns 1 on positive match and no negative matches
++ * Returns 0 when no matches occurred
+ */
+
+static int
@@ -183,18 +191,23 @@ diff --color -ruNp a/gss-serv-krb5.c b/gss-serv-krb5.c
+ u_int i;
+ *matched = -1;
+
-+ /* Check indicators */
+ for (i = 0; client->indicators[i] != NULL; i++) {
+ ret = match_pattern_list(client->indicators[i],
+ options.gss_indicators, 1);
-+ /* negative or positive match */
-+ if (ret != 0) {
++
++ /* record first positive match */
++ if (ret == 1 && *matched == -1)
++ *matched = i;
++
++ /* deny rule matched, return negative */
++ if (ret == -1) {
+ *matched = i;
-+ return ret;
++ return -1;
+ }
+ }
-+ /* No rule matched */
-+ return 0;
++ /* if there was a match, it was positive,
++ * otherwise no match */
++ return *matched != -1;
+}
+
/* Check if this user is OK to login. This only works with krb5 - other
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-22 19:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-22 19:59 [rpms/gsi-openssh] epel10: Based on openssh-9.9p1-32.el10 Mattias Ellert
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox