Skip to content

Commit a8a5e4e

Browse files
Lucas RAVAGNIERrzr
authored andcommitted
Import fix from Alma openssh-9.9p1-30
Version 9.9p1-30 does not yet have an src rpm to my knowledge, so I retrieved the fixes from their git, and I also integrated the fixes for CVE-2026-60000 and CVE-2026-60001. But as a result they correct the following CVE: - CVE-2026-59995 - CVE-2026-59999 - CVE-2026-73281 - CVE-2026-73282 - CVE-2026-73283 Knowing that CVE-2026-5996 and CVE-2026-60002 have already been corrected in the previous import. CVE-2026-59998 appears to be a documentation mistake. Only CVE-2026-59997 is not yet corrected, it is deferred on major distros, and as a result it requires highly improbable actions. Signed-off-by: Lucas RAVAGNIER <lucas.ravagnier@vates.tech>
1 parent 6d0b279 commit a8a5e4e

8 files changed

Lines changed: 568 additions & 0 deletions
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
diff --git a/sftp.c b/sftp.c
2+
index 0ab9206c2..0b57e0833 100644
3+
--- a/sftp.c
4+
+++ b/sftp.c
5+
@@ -2289,13 +2289,8 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
6+
return (-1);
7+
}
8+
} else {
9+
- /* XXX this is wrong wrt quoting */
10+
- snprintf(cmd, sizeof cmd, "get%s %s%s%s",
11+
- global_aflag ? " -a" : "", dir,
12+
- file2 == NULL ? "" : " ",
13+
- file2 == NULL ? "" : file2);
14+
- err = parse_dispatch_command(conn, cmd,
15+
- &remote_path, startdir, 1, 0);
16+
+ err = process_get(conn, dir, file2, remote_path, 0, 0,
17+
+ global_aflag, 0);
18+
free(dir);
19+
free(startdir);
20+
free(remote_path);
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
diff --git a/auth-options.c b/auth-options.c
2+
index e15f600ab..c5fc4e59c 100644
3+
--- a/auth-options.c
4+
+++ b/auth-options.c
5+
@@ -242,6 +242,7 @@ sshauthopt_new_with_keys_defaults(void)
6+
ret->permit_x11_forwarding_flag = 1;
7+
ret->permit_pty_flag = 1;
8+
ret->permit_user_rc = 1;
9+
+ ret->permit_tun_flag = 1;
10+
return ret;
11+
}
12+
13+
@@ -345,6 +346,7 @@ sshauthopt_parse(const char *opts, const char **errstrp)
14+
ret->permit_x11_forwarding_flag = 0;
15+
ret->permit_pty_flag = 0;
16+
ret->permit_user_rc = 0;
17+
+ ret->permit_tun_flag = 0;
18+
} else if ((r = opt_flag("cert-authority", 0, &opts)) != -1) {
19+
ret->cert_authority = r;
20+
} else if ((r = opt_flag("port-forwarding", 1, &opts)) != -1) {
21+
@@ -601,6 +603,7 @@ sshauthopt_merge(const struct sshauthopt *primary,
22+
OPTFLAG_AND(permit_x11_forwarding_flag);
23+
OPTFLAG_AND(permit_pty_flag);
24+
OPTFLAG_AND(permit_user_rc);
25+
+ OPTFLAG_AND(permit_tun_flag);
26+
OPTFLAG_AND(no_require_user_presence);
27+
/* Restrictive flags are logical-OR (i.e. must be set in either) */
28+
OPTFLAG_OR(require_verify);
29+
@@ -669,6 +672,7 @@ sshauthopt_copy(const struct sshauthopt *orig)
30+
OPTSCALAR(permit_x11_forwarding_flag);
31+
OPTSCALAR(permit_pty_flag);
32+
OPTSCALAR(permit_user_rc);
33+
+ OPTSCALAR(permit_tun_flag);
34+
OPTSCALAR(restricted);
35+
OPTSCALAR(cert_authority);
36+
OPTSCALAR(force_tun_device);
37+
@@ -804,6 +808,7 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
38+
(r = sshbuf_put_u8(m, opts->permit_x11_forwarding_flag)) != 0 ||
39+
(r = sshbuf_put_u8(m, opts->permit_pty_flag)) != 0 ||
40+
(r = sshbuf_put_u8(m, opts->permit_user_rc)) != 0 ||
41+
+ (r = sshbuf_put_u8(m, opts->permit_tun_flag)) != 0 ||
42+
(r = sshbuf_put_u8(m, opts->restricted)) != 0 ||
43+
(r = sshbuf_put_u8(m, opts->cert_authority)) != 0 ||
44+
(r = sshbuf_put_u8(m, opts->no_require_user_presence)) != 0 ||
45+
@@ -867,6 +872,7 @@ sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
46+
OPT_FLAG(permit_x11_forwarding_flag);
47+
OPT_FLAG(permit_pty_flag);
48+
OPT_FLAG(permit_user_rc);
49+
+ OPT_FLAG(permit_tun_flag);
50+
OPT_FLAG(restricted);
51+
OPT_FLAG(cert_authority);
52+
OPT_FLAG(no_require_user_presence);
53+
diff --git a/auth-options.h b/auth-options.h
54+
index 6e29b727c..191b9b249 100644
55+
--- a/auth-options.h
56+
+++ b/auth-options.h
57+
@@ -39,6 +39,7 @@ struct sshauthopt {
58+
int permit_x11_forwarding_flag;
59+
int permit_pty_flag;
60+
int permit_user_rc;
61+
+ int permit_tun_flag;
62+
63+
/* "restrict" keyword was invoked */
64+
int restricted;
65+
diff --git a/serverloop.c b/serverloop.c
66+
index 8a6e3db80..cf5243f80 100644
67+
--- a/serverloop.c
68+
+++ b/serverloop.c
69+
@@ -523,7 +523,8 @@ server_request_tun(struct ssh *ssh)
70+
ssh_packet_send_debug(ssh, "Unsupported tunnel device mode.");
71+
return NULL;
72+
}
73+
- if ((options.permit_tun & mode) == 0) {
74+
+ if ((options.permit_tun & mode) == 0 || options.disable_forwarding ||
75+
+ !auth_opts->permit_tun_flag) {
76+
ssh_packet_send_debug(ssh, "Server has rejected tunnel device "
77+
"forwarding");
78+
return NULL;
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
Origin: upstream, https://github.com/openssh/openssh-portable/commit/5d04ca6af739b82fd30d84d2783ca802ebfa1192
2+
Backport notes:
3+
- Only the "version identifier/RCS ID" in the header has been updated
4+
to reflect our current base file.
5+
6+
From 5d04ca6af739b82fd30d84d2783ca802ebfa1192 Mon Sep 17 00:00:00 2001
7+
From: "djm@openbsd.org" <djm@openbsd.org>
8+
Date: Mon, 6 Jul 2026 07:53:30 +0000
9+
Subject: [PATCH] upstream: Fix multiple RFC 4462 (GSSAPIAuthentication)
10+
compliance
11+
12+
problems
13+
14+
1) Remove an early failure return for GSSAPI authentication attempts
15+
made for invalid accounts that yielded different behaviour for
16+
valid vs invalid accounts.
17+
18+
2) Fix a situation where some GSSAPI requestes were not correctly
19+
subjected to MaxAuthTries.
20+
21+
3) Fix a moderate pre-authentication resource DoS related to #2.
22+
23+
Add missing logging for error cases.
24+
25+
Report and fixes from Manfred Kaiser, milCERT AT
26+
27+
OpenBSD-Commit-ID: ca0acdd64eea435d6f89534538a9eb404a5629d3
28+
Backported-by: Lucas Ravagnier <lucas.ravagnier@vates.tech>
29+
---
30+
auth2-gss.c | 53 ++++++++++++++++++++++++-----------------------------
31+
1 file changed, 24 insertions(+), 29 deletions(-)
32+
33+
diff --git a/auth2-gss.c b/auth2-gss.c
34+
index 901ba52..9c25ab2 100644
35+
--- a/auth2-gss.c
36+
+++ b/auth2-gss.c
37+
@@ -154,12 +154,6 @@ userauth_gssapi(struct ssh *ssh, const char *method)
38+
return (0);
39+
}
40+
41+
- if (!authctxt->valid || authctxt->user == NULL) {
42+
- debug2_f("disabled because of invalid user");
43+
- free(doid);
44+
- return (0);
45+
- }
46+
-
47+
if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, &goid))) {
48+
if (ctxt != NULL)
49+
ssh_gssapi_delete_ctx(&ctxt);
50+
@@ -221,8 +215,14 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
51+
(r = sshpkt_send(ssh)) != 0)
52+
fatal_fr(r, "send ERRTOK packet");
53+
}
54+
+ logit("Failed gssapi-with-mic for %s%.100s "
55+
+ "from %.200s port %d ssh2",
56+
+ authctxt->valid ? "" : "invalid user ",
57+
+ authctxt->user,
58+
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
59+
authctxt->postponed = 0;
60+
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
61+
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
62+
userauth_finish(ssh, 0, "gssapi-with-mic", NULL);
63+
} else {
64+
if (send_tok.length != 0) {
65+
@@ -234,14 +234,18 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
66+
fatal_fr(r, "send TOKEN packet");
67+
}
68+
if (maj_status == GSS_S_COMPLETE) {
69+
- ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
70+
- if (flags & GSS_C_INTEG_FLAG)
71+
- ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC,
72+
+ ssh_dispatch_set(ssh,
73+
+ SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
74+
+ /* note: keep ERRTOK handler as per RFC 4462 s3.4 */
75+
+ if (flags & GSS_C_INTEG_FLAG) {
76+
+ ssh_dispatch_set(ssh,
77+
+ SSH2_MSG_USERAUTH_GSSAPI_MIC,
78+
&input_gssapi_mic);
79+
- else
80+
+ } else {
81+
ssh_dispatch_set(ssh,
82+
SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
83+
&input_gssapi_exchange_complete);
84+
+ }
85+
}
86+
}
87+
88+
@@ -253,10 +257,6 @@ static int
89+
input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
90+
{
91+
Authctxt *authctxt = ssh->authctxt;
92+
- Gssctxt *gssctxt;
93+
- gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
94+
- gss_buffer_desc recv_tok;
95+
- OM_uint32 maj_status;
96+
int r;
97+
u_char *p;
98+
size_t len;
99+
@@ -264,26 +264,21 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
100+
if (authctxt == NULL)
101+
fatal("No authentication or GSSAPI context");
102+
103+
- gssctxt = authctxt->methoddata;
104+
- if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
105+
+ /* Minimal error handling - just cancel auth and return FAILURE */
106+
+ if ((r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0 ||
107+
(r = sshpkt_get_end(ssh)) != 0)
108+
fatal_fr(r, "parse packet");
109+
- recv_tok.value = p;
110+
- recv_tok.length = len;
111+
-
112+
- /* Push the error token into GSSAPI to see what it says */
113+
- maj_status = mm_ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
114+
- &send_tok, NULL);
115+
-
116+
- free(recv_tok.value);
117+
118+
- /* We can't return anything to the client, even if we wanted to */
119+
+ logit("Failed gssapi-with-mic for %s%.100s from %.200s port %d ssh2",
120+
+ authctxt->valid ? "" : "invalid user ",
121+
+ authctxt->user,
122+
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
123+
+ authctxt->postponed = 0;
124+
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
125+
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
126+
-
127+
- /* The client will have already moved on to the next auth */
128+
-
129+
- gss_release_buffer(&maj_status, &send_tok);
130+
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
131+
+ ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
132+
+ userauth_finish(ssh, 0, "gssapi-with-mic", NULL);
133+
return 0;
134+
}
135+
136+
--
137+
2.54.0
138+
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
Origin: upstream, https://github.com/openssh/openssh-portable/commit/d43ba60c91cb323ca921049b7d43b1908c318454
2+
Backport notes:
3+
- Only the "version identifier/RCS ID" in the header has been updated
4+
to reflect our current base file.
5+
6+
From d43ba60c91cb323ca921049b7d43b1908c318454 Mon Sep 17 00:00:00 2001
7+
From: "djm@openbsd.org" <djm@openbsd.org>
8+
Date: Mon, 6 Jul 2026 07:44:48 +0000
9+
Subject: [PATCH] upstream: Fix cases in GSSAPI and keyboard-interactive
10+
11+
authentication where the minimum per-attempt delay was not being enforced.
12+
13+
Reported by Orange Cyberdefense Vulnerability Team
14+
15+
OpenBSD-Commit-ID: c40bd35cc2428fcaccad7a141703c28baa6da01e
16+
Backported-by: Lucas Ravagnier <lucas.ravagnier@vates.tech>
17+
---
18+
auth.h | 1 +
19+
auth2-chall.c | 4 ++++
20+
auth2-gss.c | 7 +++++++
21+
auth2.c | 10 ++++++++--
22+
4 files changed, 20 insertions(+), 2 deletions(-)
23+
24+
diff --git a/auth.h b/auth.h
25+
index 6be52d7..d6f2083 100644
26+
--- a/auth.h
27+
+++ b/auth.h
28+
@@ -179,6 +179,7 @@ void auth_log(struct ssh *, int, int, const char *, const char *);
29+
void auth_maxtries_exceeded(struct ssh *) __attribute__((noreturn));
30+
void userauth_finish(struct ssh *, int, const char *, const char *);
31+
int auth_root_allowed(struct ssh *, const char *);
32+
+void auth_failure_delay(Authctxt *, double);
33+
34+
char *auth2_read_banner(void);
35+
int auth2_methods_valid(const char *, int);
36+
diff --git a/auth2-chall.c b/auth2-chall.c
37+
index 021df82..20e70d2 100644
38+
--- a/auth2-chall.c
39+
+++ b/auth2-chall.c
40+
@@ -296,6 +296,7 @@ input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
41+
u_int i, nresp;
42+
const char *devicename = NULL;
43+
char **response = NULL;
44+
+ double tstart = monotime_double();
45+
46+
if (authctxt == NULL)
47+
fatal_f("no authctxt");
48+
@@ -354,6 +355,9 @@ input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
49+
auth2_challenge_start(ssh);
50+
}
51+
}
52+
+
53+
+ if (!authenticated)
54+
+ auth_failure_delay(authctxt, tstart);
55+
userauth_finish(ssh, authenticated, "keyboard-interactive",
56+
devicename);
57+
return 0;
58+
diff --git a/auth2-gss.c b/auth2-gss.c
59+
index 5b1b9cd..901ba52 100644
60+
--- a/auth2-gss.c
61+
+++ b/auth2-gss.c
62+
@@ -298,6 +298,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
63+
{
64+
Authctxt *authctxt = ssh->authctxt;
65+
int r, authenticated;
66+
+ double tstart = monotime_double();
67+
68+
if (authctxt == NULL)
69+
fatal("No authentication or GSSAPI context");
70+
@@ -311,6 +312,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
71+
fatal_fr(r, "parse packet");
72+
73+
authenticated = mm_ssh_gssapi_userok(authctxt->user, authctxt->pw, 1);
74+
+ if (!authenticated)
75+
+ auth_failure_delay(authctxt, tstart);
76+
77+
authctxt->postponed = 0;
78+
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
79+
@@ -332,6 +335,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
80+
gss_buffer_desc mic, gssbuf;
81+
u_char *p;
82+
size_t len;
83+
+ double tstart = monotime_double();
84+
85+
if (authctxt == NULL)
86+
fatal("No authentication or GSSAPI context");
87+
@@ -367,6 +371,9 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
88+
free(micuser);
89+
free(mic.value);
90+
91+
+ if (!authenticated)
92+
+ auth_failure_delay(authctxt, tstart);
93+
+
94+
authctxt->postponed = 0;
95+
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
96+
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
97+
diff --git a/auth2.c b/auth2.c
98+
index d81887d..5c98097 100644
99+
--- a/auth2.c
100+
+++ b/auth2.c
101+
@@ -267,6 +267,12 @@ ensure_minimum_time_since(double start, double seconds)
102+
nanosleep(&ts, NULL);
103+
}
104+
105+
+void
106+
+auth_failure_delay(Authctxt *authctxt, double tstart)
107+
+{
108+
+ ensure_minimum_time_since(tstart, user_specific_delay(authctxt->user));
109+
+}
110+
+
111+
static int
112+
input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
113+
{
114+
@@ -359,8 +365,8 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
115+
authenticated = m->userauth(ssh, method);
116+
}
117+
if (!authctxt->authenticated && strcmp(method, "none") != 0)
118+
- ensure_minimum_time_since(tstart,
119+
- user_specific_delay(authctxt->user));
120+
+ auth_failure_delay(authctxt, tstart);
121+
+
122+
userauth_finish(ssh, authenticated, method, NULL);
123+
r = 0;
124+
out:
125+
--
126+
2.54.0
127+

0 commit comments

Comments
 (0)