Compare commits

...
Sign in to create a new pull request.

77 commits

Author SHA1 Message Date
Dmitry Belyavskiy
be36f8dbd6 Rebase to OpenSSH 10.2p1 2025-12-17 15:38:20 +01:00
Pavol Žáčik
84bc3aa057
Do not fail sshd-auth with gssapi-keyex and no hostkeys
With GSSAPI key exchange enabled, sshd must support
the "null" host key algorithm. This update make sure
that the server does not abort the connection if
no host key is provided.
2025-12-10 13:14:24 +01:00
Dmitry Belyavskiy
c3d6c51bfc Remove redundant SELinux patches 2025-12-02 14:05:50 +01:00
Dmitry Belyavskiy
ef51fad482 Implement mlkem768nistp256-sha256 and mlkem1024nistp384-sha384 KEX methods 2025-11-03 13:44:22 +01:00
Dmitry Belyavskiy
fa07fe987f Minor cleanup 2025-09-15 15:45:42 +02:00
Dmitry Belyavskiy
6fcc31aa4a Enable GSS KEX in FIPS mode 2025-08-28 14:07:02 +02:00
Fedora Release Engineering
f6e9920c49 Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild 2025-07-24 23:40:26 +00:00
Dmitry Belyavskiy
8476fdfee5 OpenSSH part of support of ephemeral authorized keys
Needs a SELinux counterpart
2025-06-27 10:39:00 +02:00
Allison Karlitskaya
555ff68c37 Update sshd@.service to follow upstream
In particular, this adds in the support for ephemeral ssh keys provided
by credentials (passed from container managers or VM hypervisors).  This
was introduced upstream by 071155a1fbac ("ssh-generator: support
ssh.ephemeral-key.all-users").

This change alone isn't enough to get this working.  We now get this
SELinux denial:

type=AVC msg=audit(1750939616.931:111): avc:  denied  { read } for  pid=1159 comm="sshd-session" name="ssh.ephemeral-authorized_keys-all" dev="tmpfs" ino=2 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:init_var_run_t:s0 tclass=file permissive=0

I have tested this with `setenforce 0`, however, and it works.

Resolves: rhbz#2374928
2025-06-26 14:22:07 +02:00
Dmitry Belyavskiy
f42621e54e Support authentication indicators in GSSAPI 2025-06-09 15:17:04 +02:00
Dmitry Belyavskiy
4d148ba0d3 Apply patches forgot at the previous respin 2025-06-09 15:15:42 +02:00
Dmitry Belyavskiy
e0b2e06f74 Switch to systemd-socket activation for ssh-agent
Resolves: rhbz#2181353
2025-05-19 10:28:13 +02:00
Dmitry Belyavskiy
367846c9c6 Ignore too short hostkeys in known_hosts file
(https://github.com/openssh/openssh-portable/pull/567)
2025-05-19 10:16:23 +02:00
Dmitry Belyavskiy
b5114ee608 Provide better diagnostics for non-supported private keys
(https://github.com/openssh/openssh-portable/pull/564)
2025-05-19 10:15:02 +02:00
Dmitry Belyavskiy
6330768ca8 Rebasing to 10.0p1 2025-05-16 16:00:40 +02:00
Dmitry Belyavskiy
dd7f8b6993 Require OpenSSL 3.5 to support PQ crypto
Also suppress systemd warning on restart sshd
2025-04-17 12:07:36 +02:00
Zbigniew Jędrzejewski-Szmek
9ef6367bc1 Drop /usr/local/sbin from the default path too
On systems with merged sbin, both /usr/local/sbin and /usr/sbin are symlinks,
so /usr/local/sbin should be dropped from the default path too.
2025-03-18 21:32:06 +01:00
Dmitry Belyavskiy
db6cd22c3f Usability adjustments
- Remove /usr/sbin from the default path
  Resolves: rhbz#2352387
- Export and accept COLORTERM
  Resolves: rhbz#2352653
2025-03-18 16:28:02 +01:00
Dmitry Belyavskiy
691ab72ad8 Update ssh-keysign permission for RPM linter 2025-03-06 12:15:40 +01:00
Dmitry Belyavskiy
300222035e Use OpenSSL ML-KEM implementation instead of the native one 2025-03-05 15:04:36 +01:00
Dmitry Belyavskiy
ea9f68c171 Some minor fixes from Rocky Linux
https://www.openwall.com/lists/oss-security/2025/02/22/1
2025-02-25 12:34:18 +01:00
Dmitry Belyavskiy
03a941c079 Fixes for CVE-2025-26465, CVE-2025-26466
and also some minor regressions
2025-02-18 15:05:43 +01:00
Björn Esser
d195a5f6f7
Add explicit BR: libxcrypt-devel
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
2025-02-01 19:56:17 +01:00
FeRD (Frank Dana)
4329e4cd9e Update redhat sshd config
The ChallengeResponseAuthentication setting was deprecated in
favor of KbdInteractiveAuthentication, in OpenSSH 8.7.
2025-01-29 04:41:26 -05:00
Dmitry Belyavskiy
4446a8fec2 Fix regression of Match directive processing
Resolves: rhbz#2341769
2025-01-27 13:44:40 +01:00
Dmitry Belyavskiy
18a4ac4c5c Fix regression of Match directive processing
Resolves: rhbz#2341769
2025-01-27 13:42:31 +01:00
Dmitry Belyavskiy
50fa131d40 Remove pam-ssh-agent subcomponent
Resolves: rhbz#2338440
2025-01-27 11:10:48 +01:00
Fedora Release Engineering
7551e56471 Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild 2025-01-17 21:50:57 +00:00
Dmitry Belyavskiy
9bab787a28 Fix MLKEM for BE platforms 2024-10-28 17:41:21 +01:00
Dmitry Belyavskiy
5f1bef2988 Memory management improvements 2024-10-16 15:14:16 +02:00
Zoltan Fridrich
0fd6584c66 Gssapi-keyex: fix issues found by static analysis
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
2024-10-15 14:38:14 +02:00
Nils Kattenbeck
7f540abac3 Avoid warning when OPTIONS var is not set by environment file 2024-10-14 17:01:30 +00:00
Nils Kattenbeck
10c69e8578 Avoid warning when OPTIONS var is not set by environment file 2024-10-14 17:01:01 +00:00
Nils Kattenbeck
e0b8822dc8 Avoid warning when OPTIONS var is not set by environment file 2024-10-14 16:58:19 +00:00
Dmitry Belyavskiy
2c05d86713 Use FIPS KEX defaults in FIPS mode 2024-10-11 15:07:02 +02:00
Dmitry Belyavskiy
b3639c9616 Separate ssh-keysign to a dedicated package 2024-10-11 15:07:02 +02:00
Dmitry Belyavskiy
2b8473c18a Update version of pam_ssh_agent_auth 2024-10-10 15:55:43 +02:00
Dmitry Belyavskiy
ddef24ba7e Rebasing to OpenSSH 9.9p1 2024-10-10 11:36:06 +02:00
Zoltan Fridrich
64631599fc Merge gssapi-keyex patches
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
2024-09-16 12:28:25 +02:00
Dmitry Belyavskiy
adab98c5ba Synchronize patches from Red Hat 2024-09-03 16:12:58 +02:00
Dmitry Belyavskiy
28a28238b3 Sshd now proposes to enter password again when a non-existing user is specified 2024-08-05 12:49:38 +02:00
Dmitry Belyavskiy
dd27043411 Change default key type in FIPS mode 2024-07-26 17:01:14 +02:00
Dmitry Belyavskiy
0943a793b6 Minor stuff 2024-07-24 14:31:43 +02:00
Dmitry Belyavskiy
ff8756ae7b Make test pass again 2024-07-24 13:57:59 +02:00
Dmitry Belyavskiy
207f4964a4 proper struct for gss_keyex authmethod 2024-07-24 13:57:59 +02:00
Dmitry Belyavskiy
b46d13eb96 listening_for_clients - comment out 2024-07-24 13:57:59 +02:00
Dmitry Belyavskiy
1f22cfd0dd Eliminate reexec_flag 2024-07-24 13:57:59 +02:00
Dmitry Belyavskiy
cae81de8e8 Eliminating PRIVSEP because of OpenSSH architecture changes 2024-07-24 13:57:59 +02:00
Dmitry Belyavskiy
b38789c6ac Rebase to OpenSSH 9.8p1 2024-07-24 13:57:59 +02:00
Gordon Messmer
1b1292d3a5 DSA keys are no longer supported, due to the use of SHA1. 2024-07-22 13:43:22 -07:00
Gordon Messmer
b7ff239418 Rate limit service restarts to prevent intermittent test failures. 2024-07-22 09:24:02 -07:00
Gordon Messmer
2d59c1dbf2 Collect all logs after pam_ssh_agent_auth and port-forward tests 2024-07-22 09:24:02 -07:00
Gordon Messmer
787ce2c24d Collect logs after sudo attempt in pam_ssh_agent_auth 2024-07-22 09:24:02 -07:00
Cristian Le
80da2c7159 Remove unused rhts-environment.sh
Looking at the source, there doesn't seem to be any functions/variables used from there
https://github.com/beaker-project/rhts/blob/master/bin/rhts-environment.sh

Signed-off-by: Cristian Le <cristian.le@mpsd.mpg.de>
2024-07-22 09:24:02 -07:00
Cristian Le
f8918df60f Migrate sti tests to tmt 2024-07-22 09:24:02 -07:00
Gordon Messmer
31a40d987f Temporary fix for https://pagure.io/releng/issue/12187 2024-07-22 09:24:02 -07:00
Fedora Release Engineering
fe837a3014 Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild 2024-07-18 21:00:36 +00:00
Zoltan Fridrich
2b3c43fd47 Rewriting OpenSSH GSS KEX to use new packet API
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
2024-07-02 16:30:07 +02:00
Dmitry Belyavskiy
c58fea86cd Version bump 2024-07-02 11:12:42 +02:00
Gordon Messmer
dcbca7b947 Patch 9.6p1 for CVE-2024-6387 2024-07-02 00:48:16 -07:00
Gordon Messmer
69c52aa299 Shorten paths used for parallel tests to fix BZ#2295117 2024-07-01 20:51:01 -07:00
Zoltan Fridrich
b77eafa86b Make default key sizes configurable in sshd-keygen
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
2024-05-10 10:27:51 +02:00
Zoltan Fridrich
dc8423673e Correctly audit hostname and IP address
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
2024-05-09 16:29:32 +02:00
Dmitry Belyavskiy
53eafa2b19 Use OpenSSL SSH KDF implementation - s390x fixup 2024-04-24 15:13:42 +02:00
Dmitry Belyavskiy
855a9d9c41 Use OpenSSL SSH KDF implementation 2024-04-24 12:00:24 +02:00
Dmitry Belyavskiy
80ba97c338 Bump spec 2024-04-17 10:44:40 +02:00
Zbigniew Jędrzejewski-Szmek
b001382b22 Drop %attr for a symlink
This removes the following warning:
RPM build warnings:
    Explicit %attr() mode not applicable to symlink: /builddir/build/BUILDROOT/openssh-9.6p1-1.fc41.6.x86_64/usr/libexec/openssh/ssh-askpass
2024-04-17 08:37:17 +00:00
Zbigniew Jędrzejewski-Szmek
665f4ad35f Allow %check to run on systems without selinux
chcon will fail in builds where selinux is disabled, but this
is just a workaround that is needed with selinux, so ignore the
result.
2024-04-17 08:37:17 +00:00
Daan De Meyer
8fb8f02a0d Only set PAM_RHOST if the remote host is not "UNKNOWN"
When using sshd's -i option with stdio that is not a AF_INET/AF_INET6
socket, auth_get_canonical_hostname() returns "UNKNOWN" which is then
set as the value of PAM_RHOST, causing pam to try to do a reverse DNS
query of "UNKNOWN", which times out multiple times, causing a
substantial slowdown when logging in.

To fix this, let's only set PAM_RHOST if the hostname is not "UNKNOWN".

The upstream PR (https://github.com/openssh/openssh-portable/pull/388)
has gone unreviewed for more than a year, even after multiple pings on
the PR and the mailing list.

This greatly improves the experience of using systemd's new ssh-generator
(https://github.com/systemd/systemd/pull/30777) which allows connecting
to VMs via VSOCK.
2024-04-15 15:13:27 +02:00
Dmitry Belyavskiy
055c4e2de7 Rebuild 2024-04-04 20:56:51 +02:00
Dmitry Belyavskiy
56e678546d Bump pam_ssh_agent version 2024-04-04 20:36:51 +02:00
Gordon Messmer
031b4c6f36 Build OpenSSH without libsystemd dependency, using reference implementation 2024-04-03 00:57:56 -07:00
Dmitry Belyavskiy
176421c4e4 Run tests on building OpenSSH 2024-03-13 17:50:31 +01:00
Dmitry Belyavskiy
086e6f64e1 Disable openssl engine support in openssh 2024-03-13 13:39:46 +01:00
Fedora Release Engineering
2f41ca7cd3 Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-25 11:29:57 +00:00
Fedora Release Engineering
d089d5f71b Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-21 11:22:01 +00:00
Dmitry Belyavskiy
f238307bdf Applying patches to rebase to OpenSSH 9.6p1
Based on Damien Milnes' PR
https://src.fedoraproject.org/rpms/openssh/pull-request/63

Also rebasing openssh-8.0p1-pkcs11-uri.patch to 9.6 by Dmitry Belyavskiy
2024-01-12 16:04:03 +01:00
109 changed files with 10709 additions and 10604 deletions

1
.fmf/version Normal file
View file

@ -0,0 +1 @@
1

10
.gitignore vendored
View file

@ -58,3 +58,13 @@ pam_ssh_agent_auth-0.9.2.tar.bz2
/openssh-9.0p1.tar.gz.asc
/openssh-9.3p1.tar.gz
/openssh-9.3p1.tar.gz.asc
/openssh-9.6p1.tar.gz
/openssh-9.6p1.tar.gz.asc
/openssh-9.8p1.tar.gz
/openssh-9.8p1.tar.gz.asc
/openssh-9.9p1.tar.gz
/openssh-9.9p1.tar.gz.asc
/openssh-10.0p1.tar.gz
/openssh-10.0p1.tar.gz.asc
/openssh-10.2p1.tar.gz
/openssh-10.2p1.tar.gz.asc

View file

@ -1,57 +1,83 @@
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
Authctxt *authctxt = ssh->authctxt;
Authmethod *m = NULL;
char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
From b6875ceaca4be9e0de0d6d260d8fcff1772f5fb5 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 01/53] openssh-7.8p1-role-mls
---
auth-pam.c | 2 +-
auth-pam.h | 2 +-
auth.h | 3 +
auth2-gss.c | 11 +-
auth2-hostbased.c | 9 +
auth2-pubkey.c | 11 +-
auth2.c | 14 ++
misc.c | 8 +
monitor.c | 37 ++-
monitor.h | 4 +
monitor_wrap.c | 21 ++
monitor_wrap.h | 3 +
openbsd-compat/Makefile.in | 3 +-
openbsd-compat/port-linux-sshd.c | 420 +++++++++++++++++++++++++++++++
openbsd-compat/port-linux.c | 37 +--
openbsd-compat/port-linux.h | 3 +-
platform.c | 2 +-
sshd-session.c | 3 +
18 files changed, 551 insertions(+), 42 deletions(-)
create mode 100644 openbsd-compat/port-linux-sshd.c
diff --git a/auth-pam.c b/auth-pam.c
index 5591f094e..70bcae83a 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -1261,7 +1261,7 @@ is_pam_session_open(void)
* during the ssh authentication process.
*/
int
-do_pam_putenv(char *name, char *value)
+do_pam_putenv(char *name, const char *value)
{
int ret = 1;
char *compound;
diff --git a/auth-pam.h b/auth-pam.h
index 8d801c689..9dd7ae078 100644
--- a/auth-pam.h
+++ b/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_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 --git a/auth.h b/auth.h
index 98bb23d4c..83d07ae8b 100644
--- a/auth.h
+++ b/auth.h
@@ -65,6 +65,9 @@ struct Authctxt {
char *service;
struct passwd *pw; /* set if 'valid' */
char *style;
+#ifdef WITH_SELINUX
+ char *role = NULL;
+ char *role;
+#endif
int r, authenticated = 0;
double tstart = monotime_double();
@@ -268,6 +271,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);
+#ifdef WITH_SELINUX
+ if ((role = strchr(user, '/')) != NULL)
+ *role++ = 0;
+#endif
+
if ((style = strchr(user, ':')) != NULL)
*style++ = 0;
@@ -296,8 +304,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
+ if (use_privsep) {
mm_inform_authserv(service, style);
+#ifdef WITH_SELINUX
+ mm_inform_authrole(role);
+#endif
+ }
userauth_banner(ssh);
if (auth2_setup_methods_lists(authctxt) != 0)
ssh_packet_disconnect(ssh,
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
/* Method lists for multiple authentication */
char **auth_methods; /* modified from server config */
diff --git a/auth2-gss.c b/auth2-gss.c
index 75eb4e3a3..f7898ab3e 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -284,6 +284,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
int r, authenticated = 0;
+ char *micuser;
struct sshbuf *b;
gss_buffer_desc mic, gssbuf;
const char *displayname;
@@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple
u_char *p;
@@ -300,7 +301,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
fatal_f("sshbuf_new failed");
mic.value = p;
mic.length = len;
@ -66,7 +92,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
@@ -313,6 +320,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
logit("GSSAPI MIC check failed");
sshbuf_free(b);
@ -74,11 +100,12 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
+ free(micuser);
free(mic.value);
if ((!use_privsep || mm_is_monitor()) &&
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)
authctxt->postponed = 0;
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 9d8b860eb..976484fc5 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -129,7 +129,16 @@ userauth_hostbased(struct ssh *ssh, const char *method)
/* reconstruct packet */
if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
@ -95,10 +122,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)
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 15ad3000c..c326a69ba 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -204,9 +204,16 @@ userauth_pubkey(struct ssh *ssh, const char *method)
goto done;
}
/* reconstruct packet */
@ -117,47 +145,51 @@ 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
@@ -65,6 +65,9 @@ struct Authctxt {
char *service;
struct passwd *pw; /* set if 'valid' */
char *style;
diff --git a/auth2.c b/auth2.c
index b9bb46f59..1345d3257 100644
--- a/auth2.c
+++ b/auth2.c
@@ -271,6 +271,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
Authctxt *authctxt = ssh->authctxt;
Authmethod *m = NULL;
char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
+#ifdef WITH_SELINUX
+ char *role;
+ char *role = NULL;
+#endif
int r, authenticated = 0;
double tstart = monotime_double();
/* 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)
* during the ssh authentication process.
*/
int
-do_pam_putenv(char *name, char *value)
+do_pam_putenv(char *name, const char *value)
{
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
@@ -33,7 +33,7 @@ u_int do_pam_account(void);
void do_pam_session(struct ssh *);
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 *
@@ -284,6 +287,11 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
debug("userauth-request for user %s service %s method %s", user, service, method);
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+#ifdef WITH_SELINUX
+ if ((role = strchr(user, '/')) != NULL)
+ *role++ = 0;
+#endif
+
if ((style = strchr(user, ':')) != NULL)
*style++ = 0;
@@ -313,7 +321,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
setproctitle("%s [net]", authctxt->valid ? user : "unknown");
authctxt->service = xstrdup(service);
authctxt->style = style ? xstrdup(style) : NULL;
+#ifdef WITH_SELINUX
+ authctxt->role = role ? xstrdup(role) : NULL;
+#endif
mm_inform_authserv(service, style);
+#ifdef WITH_SELINUX
+ 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 --git a/misc.c b/misc.c
index ce77ec943..5bed34735 100644
--- a/misc.c
+++ b/misc.c
@@ -822,6 +822,7 @@ char *
colon(char *cp)
{
int flag = 0;
@ -165,7 +197,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)
@@ -837,6 +838,13 @@ colon(char *cp)
return (cp);
if (*cp == '/')
return NULL;
@ -179,10 +211,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
diff --git a/monitor.c b/monitor.c
index a9e854bec..85dc1b1b7 100644
--- a/monitor.c
+++ b/monitor.c
@@ -110,6 +110,9 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *);
int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *);
int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *);
int mm_answer_authserv(struct ssh *, int, struct sshbuf *);
@ -192,7 +225,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[]
@@ -184,6 +187,9 @@ struct mon_table mon_dispatch_proto20[] = {
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
@ -202,7 +235,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
@@ -919,6 +925,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
/* Allow service/style information on the auth context */
monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
@ -212,7 +245,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,
@@ -993,6 +1002,26 @@ key_base_type_match(const char *method, const struct sshkey *key,
return found;
}
@ -239,16 +272,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,
@@ -1364,7 +1393,7 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen)
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,
@@ -1395,6 +1424,8 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen)
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
fatal_fr(r, "parse userstyle");
@ -257,7 +290,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
@@ -1445,7 +1476,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
{
struct sshbuf *b;
const u_char *p;
@ -266,7 +299,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
@@ -1466,6 +1497,8 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
fatal_fr(r, "parse userstyle");
@ -275,12 +308,13 @@ 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
@@ -55,6 +55,10 @@ enum monitor_reqtype {
MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49,
diff --git a/monitor.h b/monitor.h
index 3f8a9bea3..9dcd9c293 100644
--- a/monitor.h
+++ b/monitor.h
@@ -56,6 +56,10 @@ enum monitor_reqtype {
MONITOR_REQ_TERM = 50,
MONITOR_REQ_STATE = 51, MONITOR_ANS_STATE = 52,
+#ifdef WITH_SELINUX
+ MONITOR_REQ_AUTHROLE = 80,
@ -289,10 +323,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 *
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 33494b73f..347eb6870 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -453,6 +453,27 @@ mm_inform_authserv(char *service, char *style)
sshbuf_free(m);
}
@ -320,10 +355,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);
diff --git a/monitor_wrap.h b/monitor_wrap.h
index c87295388..9b42ddbcb 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -50,6 +50,9 @@ int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *,
const u_char *, size_t, const char *, const char *,
const char *, u_int compat);
void mm_inform_authserv(char *, char *);
@ -333,10 +369,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 \
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index 53c87db6d..39531ae77 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -102,7 +102,8 @@ PORTS= port-aix.o \
port-prngd.o \
port-solaris.o \
port-net.o \
@ -346,79 +383,12 @@ 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)
return sc;
}
-/* Set the execution context to the default for the specified user */
-void
-ssh_selinux_setup_exec_context(char *pwname)
-{
- char *user_ctx = NULL;
-
- if (!ssh_selinux_enabled())
- return;
-
- debug3("%s: setting execution context", __func__);
-
- user_ctx = ssh_selinux_getctxbyname(pwname);
- if (setexeccon(user_ctx) != 0) {
- switch (security_getenforce()) {
- case -1:
- fatal("%s: security_getenforce() failed", __func__);
- case 0:
- error("%s: Failed to set SELinux execution "
- "context for %s", __func__, pwname);
- break;
- default:
- fatal("%s: Failed to set SELinux execution context "
- "for %s (in enforcing mode)", __func__, pwname);
- }
- }
- if (user_ctx != NULL)
- freecon(user_ctx);
-
- debug3("%s: done", __func__);
-}
-
/* 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
debug3("%s: setting TTY context on %s", __func__, tty);
- user_ctx = ssh_selinux_getctxbyname(pwname);
+ if (getexeccon(&user_ctx) != 0) {
+ error_f("getexeccon: %s", strerror(errno));
+ goto out;
+ }
+
/* 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
@@ -20,9 +20,10 @@
#ifdef WITH_SELINUX
int ssh_selinux_enabled(void);
void ssh_selinux_setup_pty(char *, const char *);
-void ssh_selinux_setup_exec_context(char *);
void ssh_selinux_change_context(const char *);
void ssh_selinux_setfscreatecon(const char *);
+
+void sshd_selinux_setup_exec_context(char *);
#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,421 @@
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
new file mode 100644
index 000000000..b9fbe38b7
--- /dev/null
+++ b/openbsd-compat/port-linux-sshd.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
+ * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com>
@ -472,7 +442,6 @@ 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
@ -678,7 +647,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 && !rexeced_flag) {
+ if (inetd_flag) {
+ security_context_t sshdsc=NULL;
+
+ if (getcon_raw(&sshdsc) < 0)
@ -752,7 +721,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 && !rexeced_flag) {
+ if (inetd_flag) {
+ use_current = "1";
+ } else {
+ use_current = "";
@ -840,10 +809,82 @@ 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
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index c1d54f38d..7426f6f79 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -109,37 +109,6 @@ ssh_selinux_getctxbyname(char *pwname)
return sc;
}
-/* Set the execution context to the default for the specified user */
-void
-ssh_selinux_setup_exec_context(char *pwname)
-{
- char *user_ctx = NULL;
-
- if (!ssh_selinux_enabled())
- return;
-
- debug3("%s: setting execution context", __func__);
-
- user_ctx = ssh_selinux_getctxbyname(pwname);
- if (setexeccon(user_ctx) != 0) {
- switch (security_getenforce()) {
- case -1:
- fatal("%s: security_getenforce() failed", __func__);
- case 0:
- error("%s: Failed to set SELinux execution "
- "context for %s", __func__, pwname);
- break;
- default:
- fatal("%s: Failed to set SELinux execution context "
- "for %s (in enforcing mode)", __func__, pwname);
- }
- }
- if (user_ctx != NULL)
- freecon(user_ctx);
-
- debug3("%s: done", __func__);
-}
-
/* Set the TTY context for the specified user */
void
ssh_selinux_setup_pty(char *pwname, const char *tty)
@@ -152,7 +121,11 @@ ssh_selinux_setup_pty(char *pwname, const char *tty)
debug3("%s: setting TTY context on %s", __func__, tty);
- user_ctx = ssh_selinux_getctxbyname(pwname);
+ if (getexeccon(&user_ctx) != 0) {
+ error_f("getexeccon: %s", strerror(errno));
+ goto out;
+ }
+
/* XXX: should these calls fatal() upon failure in enforcing mode? */
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 959430de1..055c825e4 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -20,9 +20,10 @@
#ifdef WITH_SELINUX
int ssh_selinux_enabled(void);
void ssh_selinux_setup_pty(char *, const char *);
-void ssh_selinux_setup_exec_context(char *);
void ssh_selinux_change_context(const char *);
void ssh_selinux_setfscreatecon(const char *);
+
+void sshd_selinux_setup_exec_context(char *);
#endif
#ifdef LINUX_OOM_ADJUST
diff --git a/platform.c b/platform.c
index fd1a7a7c2..bcf1b0491 100644
--- a/platform.c
+++ b/platform.c
@@ -140,7 +140,7 @@ platform_setusercontext_post_groups(struct passwd *pw)
}
#endif /* HAVE_SETPCRED */
#ifdef WITH_SELINUX
@ -852,10 +893,11 @@ diff -up openssh/platform.c.role-mls openssh/platform.c
#endif
}
diff -up openssh/sshd.c.role-mls openssh/sshd.c
--- openssh/sshd.c.role-mls 2018-08-20 07:57:29.000000000 +0200
+++ openssh/sshd.c 2018-08-22 11:14:56.820430957 +0200
@@ -2186,6 +2186,9 @@ main(int ac, char **av)
diff --git a/sshd-session.c b/sshd-session.c
index 8979f743b..cb4b0523d 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1306,6 +1306,9 @@ main(int ac, char **av)
restore_uid();
}
#endif
@ -864,4 +906,7 @@ diff -up openssh/sshd.c.role-mls openssh/sshd.c
+#endif
#ifdef USE_PAM
if (options.use_pam) {
do_pam_setcred(1);
do_pam_setcred();
--
2.52.0

View file

@ -1,23 +1,26 @@
diff -up openssh/misc.c.keycat openssh/misc.c
--- openssh/misc.c.keycat 2015-06-24 10:57:50.158849606 +0200
+++ openssh/misc.c 2015-06-24 11:04:23.989868638 +0200
@@ -966,6 +966,13 @@ subprocess(const char *tag, struct passw
error("%s: dup2: %s", tag, strerror(errno));
_exit(1);
}
+#ifdef WITH_SELINUX
+ if (sshd_selinux_setup_env_variables() < 0) {
+ error ("failed to copy environment: %s",
+ strerror(errno));
+ _exit(127);
+ }
+#endif
if (env != NULL)
execve(av[0], av, env);
else
diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat
--- openssh/HOWTO.ssh-keycat.keycat 2015-06-24 10:57:50.157849608 +0200
+++ openssh/HOWTO.ssh-keycat 2015-06-24 10:57:50.157849608 +0200
From 5f16fff915643a515adbbd2e0cd12717938e3570 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 02/53] openssh-6.6p1-keycat
---
HOWTO.ssh-keycat | 12 ++
Makefile.in | 8 +-
configure.ac | 6 +
misc.c | 7 +
openbsd-compat/port-linux-sshd.c | 42 +++++-
openbsd-compat/port-linux.h | 1 +
platform.c | 2 +-
ssh-keycat.c | 241 +++++++++++++++++++++++++++++++
8 files changed, 312 insertions(+), 7 deletions(-)
create mode 100644 HOWTO.ssh-keycat
create mode 100644 ssh-keycat.c
diff --git a/HOWTO.ssh-keycat b/HOWTO.ssh-keycat
new file mode 100644
index 000000000..630ec628c
--- /dev/null
+++ b/HOWTO.ssh-keycat
@@ -0,0 +1,12 @@
+The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys
+of an user in any environment. This includes environments with
@ -31,35 +34,36 @@ diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat
+ PubkeyAuthentication yes
+
+
diff -up openssh/Makefile.in.keycat openssh/Makefile.in
--- openssh/Makefile.in.keycat 2015-06-24 10:57:50.152849621 +0200
+++ openssh/Makefile.in 2015-06-24 10:57:50.157849608 +0200
@@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server
diff --git a/Makefile.in b/Makefile.in
index ba17a79f0..a3a495c1b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -23,6 +23,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
SSHD_AUTH=$(libexecdir)/sshd-auth
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper
PRIVSEP_PATH=@PRIVSEP_PATH@
@@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@
@@ -58,6 +59,7 @@ CHANNELLIBS=@CHANNELLIBS@
K5LIBS=@K5LIBS@
GSSLIBS=@GSSLIBS@
SSHDLIBS=@SSHDLIBS@
+KEYCATLIBS=@KEYCATLIBS@
LIBEDIT=@LIBEDIT@
LIBFIDO2=@LIBFIDO2@
AR=@AR@
@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@
LIBWTMPDB=@LIBWTMPDB@
@@ -75,7 +77,7 @@ MKDIR_P=@MKDIR_P@
.SUFFIXES: .lo
-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=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE)
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) $(SK_STANDALONE)
XMSS_OBJS=\
ssh-xmss.o \
@@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
LIBOPENSSH_OBJS=\
ssh_api.o \
@@ -252,6 +254,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS)
ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)
@ -69,7 +73,7 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)
@@ -321,6 +325,7 @@ install-files:
@@ -439,6 +444,7 @@ install-files:
$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT)
@ -77,26 +81,69 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
diff -up openssh/openbsd-compat/port-linux.h.keycat openssh/openbsd-compat/port-linux.h
--- openssh/openbsd-compat/port-linux.h.keycat 2015-06-24 10:57:50.150849626 +0200
+++ openssh/openbsd-compat/port-linux.h 2015-06-24 10:57:50.160849601 +0200
@@ -25,8 +25,10 @@ void ssh_selinux_setup_pty(char *, const
void ssh_selinux_change_context(const char *);
void ssh_selinux_setfscreatecon(const char *);
diff --git a/configure.ac b/configure.ac
index db5211013..fd632a5a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3648,6 +3648,7 @@ AC_ARG_WITH([pam],
PAM_MSG="yes"
+int sshd_selinux_enabled(void);
void sshd_selinux_copy_context(void);
void sshd_selinux_setup_exec_context(char *);
+int sshd_selinux_setup_env_variables(void);
#endif
SSHDLIBS="$SSHDLIBS -lpam"
+ KEYCATLIBS="$KEYCATLIBS -lpam"
AC_DEFINE([USE_PAM], [1],
[Define if you want to enable PAM support])
#ifdef LINUX_OOM_ADJUST
diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/port-linux-sshd.c
--- openssh/openbsd-compat/port-linux-sshd.c.keycat 2015-06-24 10:57:50.150849626 +0200
+++ openssh/openbsd-compat/port-linux-sshd.c 2015-06-24 10:57:50.159849603 +0200
@@ -54,6 +54,20 @@ extern Authctxt *the_authctxt;
@@ -3658,6 +3659,7 @@ AC_ARG_WITH([pam],
;;
*)
SSHDLIBS="$SSHDLIBS -ldl"
+ KEYCATLIBS="$KEYCATLIBS -ldl"
;;
esac
fi
@@ -4883,6 +4885,7 @@ AC_ARG_WITH([selinux],
fi ]
)
AC_SUBST([SSHDLIBS])
+AC_SUBST([KEYCATLIBS])
# Check whether user wants Kerberos 5 support
KRB5_MSG="no"
@@ -5894,6 +5897,9 @@ fi
if test ! -z "${SSHDLIBS}"; then
echo " +for sshd: ${SSHDLIBS}"
fi
+if test ! -z "${KEYCATLIBS}"; then
+echo " +for ssh-keycat: ${KEYCATLIBS}"
+fi
echo ""
diff --git a/misc.c b/misc.c
index 5bed34735..7e27a38d1 100644
--- a/misc.c
+++ b/misc.c
@@ -2921,6 +2921,13 @@ subprocess(const char *tag, const char *command,
error("%s: dup2: %s", tag, strerror(errno));
_exit(1);
}
+#ifdef WITH_SELINUX
+ if (sshd_selinux_setup_env_variables() < 0) {
+ error ("failed to copy environment: %s",
+ strerror(errno));
+ _exit(127);
+ }
+#endif
if (env != NULL)
execve(av[0], av, env);
else
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
index b9fbe38b7..4d56745f7 100644
--- a/openbsd-compat/port-linux-sshd.c
+++ b/openbsd-compat/port-linux-sshd.c
@@ -52,6 +52,20 @@ 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
@ -115,7 +162,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/
/* Send audit message */
static int
sshd_selinux_send_audit_message(int success, security_context_t default_context,
@@ -308,7 +322,7 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -317,7 +331,7 @@ sshd_selinux_getctxbyname(char *pwname,
/* Setup environment variables for pam_selinux */
static int
@ -124,14 +171,14 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/
{
const char *reqlvl;
char *role;
@@ -319,16 +333,16 @@ sshd_selinux_setup_pam_variables(void)
@@ -328,16 +342,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 && !rexeced_flag) {
if (inetd_flag) {
use_current = "1";
} else {
use_current = "";
@ -144,7 +191,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/
if (role != NULL)
free(role);
@@ -336,6 +350,24 @@ sshd_selinux_setup_pam_variables(void)
@@ -345,6 +359,24 @@ sshd_selinux_setup_pam_variables(void)
return rv;
}
@ -169,7 +216,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/
/* Set the execution context to the default for the specified user */
void
sshd_selinux_setup_exec_context(char *pwname)
@@ -344,7 +376,7 @@ sshd_selinux_setup_exec_context(char *pw
@@ -353,7 +385,7 @@ sshd_selinux_setup_exec_context(char *pwname)
int r = 0;
security_context_t default_ctx = NULL;
@ -178,19 +225,23 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/
return;
if (options.use_pam) {
@@ -415,7 +447,7 @@ sshd_selinux_copy_context(void)
{
security_context_t *ctx;
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 055c825e4..c004071d1 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -24,6 +24,7 @@ void ssh_selinux_change_context(const char *);
void ssh_selinux_setfscreatecon(const char *);
- if (!ssh_selinux_enabled())
+ if (!sshd_selinux_enabled())
return;
void sshd_selinux_setup_exec_context(char *);
+int sshd_selinux_setup_env_variables(void);
#endif
if (getexeccon((security_context_t *)&ctx) != 0) {
diff -up openssh/platform.c.keycat openssh/platform.c
--- openssh/platform.c.keycat 2015-06-24 10:57:50.147849633 +0200
+++ openssh/platform.c 2015-06-24 10:57:50.160849601 +0200
@@ -103,7 +103,7 @@ platform_setusercontext(struct passwd *p
#ifdef LINUX_OOM_ADJUST
diff --git a/platform.c b/platform.c
index bcf1b0491..c92a0cba6 100644
--- a/platform.c
+++ b/platform.c
@@ -55,7 +55,7 @@ platform_setusercontext(struct passwd *pw)
{
#ifdef WITH_SELINUX
/* Cache selinux status for later use */
@ -199,9 +250,11 @@ diff -up openssh/platform.c.keycat openssh/platform.c
#endif
#ifdef USE_SOLARIS_PROJECTS
diff -up openssh/ssh-keycat.c.keycat openssh/ssh-keycat.c
--- openssh/ssh-keycat.c.keycat 2015-06-24 10:57:50.161849599 +0200
+++ openssh/ssh-keycat.c 2015-06-24 10:57:50.161849599 +0200
diff --git a/ssh-keycat.c b/ssh-keycat.c
new file mode 100644
index 000000000..5678be079
--- /dev/null
+++ b/ssh-keycat.c
@@ -0,0 +1,241 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
@ -444,41 +497,6 @@ diff -up openssh/ssh-keycat.c.keycat openssh/ssh-keycat.c
+ }
+ return ev;
+}
diff --git a/configure.ac b/configure.ac
index 3bbccfd..6481f1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2952,6 +2952,7 @@ AC_ARG_WITH([pam],
PAM_MSG="yes"
SSHDLIBS="$SSHDLIBS -lpam"
+ KEYCATLIBS="$KEYCATLIBS -lpam"
AC_DEFINE([USE_PAM], [1],
[Define if you want to enable PAM support])
@@ -3105,6 +3106,7 @@
;;
*)
SSHDLIBS="$SSHDLIBS -ldl"
+ KEYCATLIBS="$KEYCATLIBS -ldl"
;;
esac
fi
@@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux],
fi ]
)
AC_SUBST([SSHDLIBS])
+AC_SUBST([KEYCATLIBS])
# Check whether user wants Kerberos 5 support
KRB5_MSG="no"
@@ -5031,6 +5034,9 @@ fi
if test ! -z "${SSHDLIBS}"; then
echo " +for sshd: ${SSHDLIBS}"
fi
+if test ! -z "${KEYCATLIBS}"; then
+echo " +for ssh-keycat: ${KEYCATLIBS}"
+fi
echo ""
--
2.52.0

View file

@ -1,7 +1,17 @@
diff -up openssh/sshd.c.ip-opts openssh/sshd.c
--- openssh/sshd.c.ip-opts 2016-07-25 13:58:48.998507834 +0200
+++ openssh/sshd.c 2016-07-25 14:01:28.346469878 +0200
@@ -1507,12 +1507,32 @@ check_ip_options(struct ssh *ssh)
From 7ffeef7e8218c544b6f4a09c5d43e9b748de5a5f Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 03/53] openssh-6.6p1-allow-ip-opts
---
sshd-session.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/sshd-session.c b/sshd-session.c
index cb4b0523d..1c72e664a 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -754,12 +754,32 @@ check_ip_options(struct ssh *ssh)
if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts,
&option_size) >= 0 && option_size != 0) {
@ -38,5 +48,8 @@ diff -up openssh/sshd.c.ip-opts openssh/sshd.c
+ }
+ } while (i < option_size);
}
return;
#endif /* IP_OPTIONS */
}
--
2.52.0

View file

@ -1,7 +1,18 @@
diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1
--- openssh-5.9p0/ssh.1.ipv6man 2011-08-05 22:17:32.000000000 +0200
+++ openssh-5.9p0/ssh.1 2011-08-31 13:08:34.880024485 +0200
@@ -1400,6 +1400,8 @@ manual page for more information.
From f653eed40e15c4c521ce683a604b46ed81cade6a Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 04/53] openssh-5.9p1-ipv6man
---
ssh.1 | 2 ++
sshd.8 | 2 ++
2 files changed, 4 insertions(+)
diff --git a/ssh.1 b/ssh.1
index 697f4e42a..db92ac9af 100644
--- a/ssh.1
+++ b/ssh.1
@@ -1663,6 +1663,8 @@ manual page for more information.
.Nm
exits with the exit status of the remote command or with 255
if an error occurred.
@ -10,10 +21,11 @@ diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1
.Sh SEE ALSO
.Xr scp 1 ,
.Xr sftp 1 ,
diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8
--- openssh-5.9p0/sshd.8.ipv6man 2011-08-05 22:17:32.000000000 +0200
+++ openssh-5.9p0/sshd.8 2011-08-31 13:10:34.129039094 +0200
@@ -940,6 +940,8 @@ concurrently for different ports, this c
diff --git a/sshd.8 b/sshd.8
index 7fbca776a..0226a8303 100644
--- a/sshd.8
+++ b/sshd.8
@@ -1018,6 +1018,8 @@ concurrently for different ports, this contains the process ID of the one
started last).
The content of this file is not sensitive; it can be world-readable.
.El
@ -22,3 +34,6 @@ diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8
.Sh SEE ALSO
.Xr scp 1 ,
.Xr sftp 1 ,
--
2.52.0

View file

@ -0,0 +1,26 @@
From 6ac14fb92cf0d0676f19282f30b9e427025be31b Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 05/53] openssh-5.8p2-sigpipe
---
ssh-keyscan.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index f9788114d..11618ae8a 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -776,6 +776,9 @@ main(int argc, char **argv)
if (maxfd > fdlim_get(0))
fdlim_set(maxfd);
fdcon = xcalloc(maxfd, sizeof(con));
+
+ signal(SIGPIPE, SIG_IGN);
+
read_wait = xcalloc(maxfd, sizeof(struct pollfd));
for (j = 0; j < maxfd; j++)
read_wait[j].fd = -1;
--
2.52.0

View file

@ -1,7 +1,17 @@
diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c
--- openssh-7.2p2/channels.c.x11 2016-03-09 19:04:48.000000000 +0100
+++ openssh-7.2p2/channels.c 2016-06-03 10:42:04.775164520 +0200
@@ -3990,21 +3990,24 @@ x11_create_display_inet(int x11_display_
From d6dc5be6e969ecffe30b9972706b3c92d930d81f Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 06/53] openssh-7.2p2-x11
---
channels.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/channels.c b/channels.c
index 80014ff34..5ce6bd400 100644
--- a/channels.c
+++ b/channels.c
@@ -5169,11 +5169,13 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
}
static int
@ -14,8 +24,10 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c
+ if (len <= 0)
+ return -1;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1)
if (sock == -1) {
error("socket: %.100s", strerror(errno));
@@ -5181,11 +5183,12 @@ connect_local_xsocket_path(const char *pathname)
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
- strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
@ -30,7 +42,7 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c
return -1;
}
@@ -4012,8 +4015,18 @@ static int
@@ -5193,8 +5196,18 @@ static int
connect_local_xsocket(u_int dnr)
{
char buf[1024];
@ -51,3 +63,6 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c
}
#ifdef __APPLE__
--
2.52.0

View file

@ -1,7 +1,17 @@
diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contrib/gnome-ssh-askpass2.c
--- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:16.545211926 +0100
@@ -53,6 +53,7 @@
From c62cd7ce2539c1eac6d0133c07441c617cbc7bc3 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 07/53] openssh-5.1p1-askpass-progress
---
contrib/gnome-ssh-askpass2.c | 39 +++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c
index a62f98152..cb7152dc8 100644
--- a/contrib/gnome-ssh-askpass2.c
+++ b/contrib/gnome-ssh-askpass2.c
@@ -58,6 +58,7 @@
#include <unistd.h>
#include <X11/Xlib.h>
@ -9,7 +19,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
@@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia
@@ -146,6 +147,17 @@ parse_env_hex_color(const char *env, GdkColor *c)
return 1;
}
@ -27,7 +37,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr
static int
passphrase_dialog(char *message, int prompt_type)
{
const char *failed;
@@ -153,7 +165,7 @@ passphrase_dialog(char *message, int prompt_type)
char *passphrase, *local;
int result, grab_tries, grab_server, grab_pointer;
int buttons, default_response;
@ -36,7 +46,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr
GdkGrabStatus status;
GdkColor fg, bg;
int fg_set = 0, bg_set = 0;
@@ -104,14 +116,19 @@ passphrase_dialog(char *message)
@@ -199,14 +211,19 @@ passphrase_dialog(char *message, int prompt_type)
gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg);
if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) {
@ -45,12 +55,12 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr
+ FALSE, 0);
+ gtk_widget_show(hbox);
+
entry = gtk_entry_new();
if (fg_set)
gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg);
if (bg_set)
gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg);
gtk_box_pack_start(
entry = gtk_entry_new();
if (fg_set)
gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg);
if (bg_set)
gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg);
gtk_box_pack_start(
- GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
- entry, FALSE, FALSE, 0);
+ GTK_BOX(hbox), entry, TRUE, FALSE, 0);
@ -58,7 +68,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
gtk_widget_grab_focus(entry);
if (prompt_type == PROMPT_ENTRY) {
@@ -130,6 +145,22 @@ passphrase_dialog(char *message)
@@ -225,6 +242,22 @@ passphrase_dialog(char *message, int prompt_type)
g_signal_connect(G_OBJECT(entry), "key_press_event",
G_CALLBACK(check_none), dialog);
}
@ -81,3 +91,6 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr
}
/* Grab focus */
--
2.52.0

View file

@ -1,7 +1,17 @@
diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/contrib/gnome-ssh-askpass2.c
--- openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info 2021-04-19 13:57:11.720113536 +0200
+++ openssh-8.6p1/contrib/gnome-ssh-askpass2.c 2021-04-19 13:59:29.842163204 +0200
@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_wi
From d124ab0f6eea910dc5f03cdd808f6fa792bf2b7a Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 08/53] openssh-4.3p2-askpass-grab-info
---
contrib/gnome-ssh-askpass2.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c
index cb7152dc8..bbe93d838 100644
--- a/contrib/gnome-ssh-askpass2.c
+++ b/contrib/gnome-ssh-askpass2.c
@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_window, const char *what)
err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
@ -16,3 +26,6 @@ diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/cont
gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
gtk_dialog_run(GTK_DIALOG(err));
--
2.52.0

View file

@ -1,6 +1,25 @@
diff -up openssh/ssh_config.redhat openssh/ssh_config
--- openssh/ssh_config.redhat 2020-02-11 23:28:35.000000000 +0100
+++ openssh/ssh_config 2020-02-13 18:13:39.180641839 +0100
From c76607384ff077ba1c45759e749562cccaeaa335 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 09/53] openssh-8.7p1-redhat
---
ssh_config | 7 +++++++
ssh_config_redhat | 18 ++++++++++++++++++
sshd_config | 8 ++++++++
sshd_config.0 | 6 +++---
sshd_config.5 | 2 +-
sshd_config_redhat | 18 ++++++++++++++++++
sshd_config_redhat_cp | 7 +++++++
7 files changed, 62 insertions(+), 4 deletions(-)
create mode 100644 ssh_config_redhat
create mode 100644 sshd_config_redhat
create mode 100644 sshd_config_redhat_cp
diff --git a/ssh_config b/ssh_config
index 238a0c5e3..d9324c957 100644
--- a/ssh_config
+++ b/ssh_config
@@ -43,3 +43,10 @@
# ProxyCommand ssh -q -W %h:%p gateway.example.com
# RekeyLimit 1G 1h
@ -12,10 +31,12 @@ diff -up openssh/ssh_config.redhat openssh/ssh_config
+# included below. For more information, see manual page for
+# update-crypto-policies(8) and ssh_config(5).
+Include /etc/ssh/ssh_config.d/*.conf
diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat
--- openssh/ssh_config_redhat.redhat 2020-02-13 18:13:39.180641839 +0100
+++ openssh/ssh_config_redhat 2020-02-13 18:13:39.180641839 +0100
@@ -0,0 +1,15 @@
diff --git a/ssh_config_redhat b/ssh_config_redhat
new file mode 100644
index 000000000..8b1b59021
--- /dev/null
+++ b/ssh_config_redhat
@@ -0,0 +1,18 @@
+# The options here are in the "Match final block" to be applied as the last
+# options and could be potentially overwritten by the user configuration
+Match final all
@ -29,12 +50,35 @@ diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat
+# mode correctly we set this to yes.
+ ForwardX11Trusted yes
+
+# rhbz#2352653 - export COLORTERM
+ SendEnv COLORTERM
+
+# Uncomment this if you want to use .local domain
+# Host *.local
diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0
--- openssh/sshd_config.0.redhat 2020-02-12 14:30:04.000000000 +0100
+++ openssh/sshd_config.0 2020-02-13 18:13:39.181641855 +0100
@@ -970,9 +970,9 @@ DESCRIPTION
diff --git a/sshd_config b/sshd_config
index 0f4a3a724..608203e4b 100644
--- a/sshd_config
+++ b/sshd_config
@@ -10,6 +10,14 @@
# possible, but leave them commented. Uncommented options override the
# default value.
+# To modify the system-wide sshd configuration, create a *.conf file under
+# /etc/ssh/sshd_config.d/ which will be automatically included below
+Include /etc/ssh/sshd_config.d/*.conf
+
+# If you want to change the port on a SELinux system, you have to tell
+# SELinux about this change.
+# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
+#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
diff --git a/sshd_config.0 b/sshd_config.0
index c63d729a9..8c5217c0b 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -1219,9 +1219,9 @@ DESCRIPTION
SyslogFacility
Gives the facility code that is used when logging messages from
@ -47,10 +91,11 @@ diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0
TCPKeepAlive
Specifies whether the system should send TCP keepalive messages
diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5
--- openssh/sshd_config.5.redhat 2020-02-11 23:28:35.000000000 +0100
+++ openssh/sshd_config.5 2020-02-13 18:13:39.181641855 +0100
@@ -1614,7 +1614,7 @@ By default no subsystems are defined.
diff --git a/sshd_config.5 b/sshd_config.5
index 6ae606f1e..aa9f0af76 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1941,7 +1941,7 @@ By default no subsystems are defined.
.It Cm SyslogFacility
Gives the facility code that is used when logging messages from
.Xr sshd 8 .
@ -59,31 +104,15 @@ diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
The default is AUTH.
.It Cm TCPKeepAlive
diff -up openssh/sshd_config.redhat openssh/sshd_config
--- openssh/sshd_config.redhat 2020-02-11 23:28:35.000000000 +0100
+++ openssh/sshd_config 2020-02-13 18:20:16.349913681 +0100
@@ -10,6 +10,14 @@
# possible, but leave them commented. Uncommented options override the
# default value.
+# To modify the system-wide sshd configuration, create a *.conf file under
+# /etc/ssh/sshd_config.d/ which will be automatically included below
+Include /etc/ssh/sshd_config.d/*.conf
+
+# If you want to change the port on a SELinux system, you have to tell
+# SELinux about this change.
+# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
+#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
--- openssh/sshd_config_redhat.redhat 2020-02-13 18:14:02.268006439 +0100
+++ openssh/sshd_config_redhat 2020-02-13 18:19:20.765035947 +0100
@@ -0,0 +1,15 @@
diff --git a/sshd_config_redhat b/sshd_config_redhat
new file mode 100644
index 000000000..993a28d52
--- /dev/null
+++ b/sshd_config_redhat
@@ -0,0 +1,18 @@
+SyslogFacility AUTHPRIV
+
+ChallengeResponseAuthentication no
+KbdInteractiveAuthentication no
+
+GSSAPIAuthentication yes
+GSSAPICleanupCredentials no
@ -92,13 +121,18 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
+
+X11Forwarding yes
+
+# rhbz#2352653 - accept COLORTERM
+ AcceptEnv COLORTERM
+
+# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd,
+# as it is more configurable and versatile than the built-in version.
+PrintMotd no
+
diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
--- openssh/sshd_config_redhat_cp.redhat 2020-02-13 18:14:02.268006439 +0100
+++ openssh/sshd_config_redhat_cp 2020-02-13 18:19:20.765035947 +0100
diff --git a/sshd_config_redhat_cp b/sshd_config_redhat_cp
new file mode 100644
index 000000000..1d592d13f
--- /dev/null
+++ b/sshd_config_redhat_cp
@@ -0,0 +1,7 @@
+# This system is following system-wide crypto policy. The changes to
+# crypto properties (Ciphers, MACs, ...) will not have any effect in
@ -107,3 +141,6 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
+# Please, see manual pages for update-crypto-policies(8) and sshd_config(5).
+Include /etc/crypto-policies/back-ends/opensshserver.config
+
--
2.52.0

View file

@ -0,0 +1,41 @@
From 5f6dbc98a184ce485aef90321ae9fc1ba45293f8 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 10/53] openssh-7.8p1-UsePAM-warning
---
sshd-session.c | 4 ++++
sshd_config | 2 ++
2 files changed, 6 insertions(+)
diff --git a/sshd-session.c b/sshd-session.c
index 1c72e664a..9804dc334 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1103,6 +1103,10 @@ main(int ac, char **av)
"enabled authentication methods");
}
+ /* 'UsePAM no' is not supported in our builds */
+ if (! options.use_pam)
+ logit("WARNING: 'UsePAM no' is not supported in this build and may cause several problems.");
+
#ifdef WITH_OPENSSL
if (options.moduli_file != NULL)
dh_set_moduli_file(options.moduli_file);
diff --git a/sshd_config b/sshd_config
index 608203e4b..48af6321b 100644
--- a/sshd_config
+++ b/sshd_config
@@ -89,6 +89,8 @@ AuthorizedKeysFile .ssh/authorized_keys
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
+# WARNING: 'UsePAM no' is not supported in this build and may cause several
+# problems.
#UsePAM no
#AllowAgentForwarding yes
--
2.52.0

View file

@ -1,5 +1,17 @@
From 577b0fea53270292bd0b4979eb5369619b2f5adb Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 12/53] openssh-6.6p1-force_krb
---
gss-serv-krb5.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++-
session.c | 23 +++++++
ssh-gss.h | 4 ++
sshd.8 | 7 +++
4 files changed, 189 insertions(+), 1 deletion(-)
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index 413b845..54dd383 100644
index 8d2b677f7..14502c5a6 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -32,7 +32,9 @@
@ -12,7 +24,7 @@ index 413b845..54dd383 100644
#include "xmalloc.h"
#include "sshkey.h"
@@ -45,6 +47,7 @@
@@ -44,6 +46,7 @@
#include "ssh-gss.h"
@ -20,7 +32,7 @@ index 413b845..54dd383 100644
extern ServerOptions options;
#ifdef HEIMDAL
@@ -56,6 +59,13 @@ extern ServerOptions options;
@@ -55,6 +58,13 @@ extern ServerOptions options;
# include <gssapi/gssapi_krb5.h>
#endif
@ -34,7 +46,7 @@ index 413b845..54dd383 100644
static krb5_context krb_context = NULL;
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
@@ -88,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
@@ -87,6 +97,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
krb5_principal princ;
int retval;
const char *errmsg;
@ -42,7 +54,7 @@ index 413b845..54dd383 100644
if (ssh_gssapi_krb5_init() == 0)
return 0;
@@ -99,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
@@ -98,10 +109,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
krb5_free_error_message(krb_context, errmsg);
return 0;
}
@ -66,7 +78,7 @@ index 413b845..54dd383 100644
} else
retval = 0;
@@ -110,6 +133,137 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
@@ -109,6 +132,137 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
return retval;
}
@ -205,10 +217,10 @@ index 413b845..54dd383 100644
/* This writes out any forwarded credentials from the structure populated
* during userauth. Called after we have setuid to the user */
diff --git a/session.c b/session.c
index 28659ec..9c94d8e 100644
index b8f0c1a58..3eae5bdf3 100644
--- a/session.c
+++ b/session.c
@@ -789,6 +789,29 @@ do_exec(Session *s, const char *command)
@@ -642,6 +642,29 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
command = auth_opts->force_command;
forced = "(key-option)";
}
@ -239,7 +251,7 @@ index 28659ec..9c94d8e 100644
if (forced != NULL) {
s->forced = 1;
diff --git a/ssh-gss.h b/ssh-gss.h
index 0374c88..509109a 100644
index 8ec451926..db34d77f4 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -49,6 +49,10 @@
@ -254,10 +266,10 @@ index 0374c88..509109a 100644
/* draft-ietf-secsh-gsskeyex-06 */
diff --git a/sshd.8 b/sshd.8
index adcaaf9..824163b 100644
index 0226a8303..e2d8ff003 100644
--- a/sshd.8
+++ b/sshd.8
@@ -324,6 +324,7 @@ Finally, the server and the client enter an authentication dialog.
@@ -286,6 +286,7 @@ Finally, the server and the client enter an authentication dialog.
The client tries to authenticate itself using
host-based authentication,
public key authentication,
@ -265,7 +277,7 @@ index adcaaf9..824163b 100644
challenge-response authentication,
or password authentication.
.Pp
@@ -800,6 +801,12 @@ This file is used in exactly the same way as
@@ -874,6 +875,12 @@ This file is used in exactly the same way as
but allows host-based authentication without permitting login with
rlogin/rsh.
.Pp
@ -278,3 +290,6 @@ index adcaaf9..824163b 100644
.It Pa ~/.ssh/
This directory is the default location for all user-specific configuration
and authentication information.
--
2.52.0

View file

@ -1,26 +1,25 @@
diff -up openssh-8.6p1/auth.h.ccache_name openssh-8.6p1/auth.h
--- openssh-8.6p1/auth.h.ccache_name 2021-04-19 14:05:10.820744325 +0200
+++ openssh-8.6p1/auth.h 2021-04-19 14:05:10.853744569 +0200
@@ -83,6 +83,7 @@ struct Authctxt {
krb5_principal krb5_user;
char *krb5_ticket_file;
char *krb5_ccname;
+ int krb5_set_env;
#endif
struct sshbuf *loginmsg;
@@ -231,7 +232,7 @@ struct passwd *fakepw(void);
int sys_auth_passwd(struct ssh *, const char *);
#if defined(KRB5) && !defined(HEIMDAL)
-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
#endif
#endif /* AUTH_H */
diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
--- openssh-8.6p1/auth-krb5.c.ccache_name 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/auth-krb5.c 2021-04-19 14:40:55.142832954 +0200
From 1a5b32dbf550467a4ae19351667bcfdf9c52e44d Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 13/53] openssh-7.7p1-gssapi-new-unique
---
auth-krb5.c | 262 ++++++++++++++++++++++++++++++++++++++++++------
auth.h | 3 +-
gss-serv-krb5.c | 42 +++-----
gss-serv.c | 10 +-
servconf.c | 12 ++-
servconf.h | 2 +
session.c | 5 +-
ssh-gss.h | 4 +-
sshd-session.c | 2 +-
sshd_config.5 | 8 ++
10 files changed, 279 insertions(+), 71 deletions(-)
diff --git a/auth-krb5.c b/auth-krb5.c
index 9d2f1f0ea..035032221 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -51,6 +51,7 @@
#include <unistd.h>
#include <string.h>
@ -29,7 +28,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
extern ServerOptions options;
@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c
@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
#endif
krb5_error_code problem;
krb5_ccache ccache = NULL;
@ -38,7 +37,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
char *client, *platform_client;
const char *errmsg;
@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c
@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
goto out;
}
@ -49,7 +48,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
if (problem)
goto out;
@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c
@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
goto out;
#endif
@ -70,7 +69,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
#endif
@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c
@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
void
krb5_cleanup_proc(Authctxt *authctxt)
{
@ -126,12 +125,29 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
if (authctxt->krb5_user) {
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
authctxt->krb5_user = NULL;
@@ -238,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt)
@@ -238,36 +281,189 @@ krb5_cleanup_proc(Authctxt *authctxt)
}
}
-#ifndef HEIMDAL
+
-krb5_error_code
-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
- int tmpfd, ret, oerrno;
- char ccname[40];
- mode_t old_umask;
- ret = snprintf(ccname, sizeof(ccname),
- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
- if (ret < 0 || (size_t)ret >= sizeof(ccname))
- return ENOMEM;
-
- old_umask = umask(0177);
- tmpfd = mkstemp(ccname + strlen("FILE:"));
- oerrno = errno;
- umask(old_umask);
- if (tmpfd == -1) {
- logit("mkstemp(): %.100s", strerror(oerrno));
- return oerrno;
+#if !defined(HEIMDAL)
+int
+ssh_asprintf_append(char **dsc, const char *fmt, ...) {
@ -149,7 +165,8 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
+ old = *dsc;
+
+ i = asprintf(dsc, "%s%s", *dsc, src);
+ if (i == -1 || src == NULL) {
+ if (i == -1) {
+ *dsc = old;
+ free(src);
+ return -1;
+ }
@ -196,8 +213,9 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
+ /* unknown token, fallback to the default */
+ goto cleanup;
+ }
+ }
+
}
- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
+ if (ssh_asprintf_append(&r, "%s", p_o) == -1)
+ goto cleanup;
+
@ -232,29 +250,13 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
+ return ret;
+}
+
krb5_error_code
-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
- int tmpfd, ret, oerrno;
- char ccname[40];
+krb5_error_code
+ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) {
+ int tmpfd, ret, oerrno, type_len;
+ char *ccname = NULL;
mode_t old_umask;
+ mode_t old_umask;
+ char *type = NULL, *colon = NULL;
- ret = snprintf(ccname, sizeof(ccname),
- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
- if (ret < 0 || (size_t)ret >= sizeof(ccname))
- return ENOMEM;
-
- old_umask = umask(0177);
- tmpfd = mkstemp(ccname + strlen("FILE:"));
- oerrno = errno;
- umask(old_umask);
- if (tmpfd == -1) {
- logit("mkstemp(): %.100s", strerror(oerrno));
- return oerrno;
- }
+
+ debug3_f("called");
+ if (need_environment)
+ *need_environment = 0;
@ -269,8 +271,7 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
+ "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
+ if (ret < 0)
+ return ENOMEM;
- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
+
+ old_umask = umask(0177);
+ tmpfd = mkstemp(ccname + strlen("FILE:"));
oerrno = errno;
@ -337,42 +338,32 @@ diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
}
#endif /* !HEIMDAL */
#endif /* KRB5 */
diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c
--- openssh-8.6p1/gss-serv.c.ccache_name 2021-04-19 14:05:10.844744503 +0200
+++ openssh-8.6p1/gss-serv.c 2021-04-19 14:05:10.854744577 +0200
@@ -413,13 +413,15 @@ ssh_gssapi_cleanup_creds(void)
}
diff --git a/auth.h b/auth.h
index 83d07ae8b..10e88e11f 100644
--- a/auth.h
+++ b/auth.h
@@ -85,6 +85,7 @@ struct Authctxt {
krb5_principal krb5_user;
char *krb5_ticket_file;
char *krb5_ccname;
+ int krb5_set_env;
#endif
struct sshbuf *loginmsg;
/* As user */
-void
+int
ssh_gssapi_storecreds(void)
{
if (gssapi_client.mech && gssapi_client.mech->storecreds) {
- (*gssapi_client.mech->storecreds)(&gssapi_client);
+ return (*gssapi_client.mech->storecreds)(&gssapi_client);
} else
debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
+
+ return 0;
}
@@ -245,7 +246,7 @@ FILE *auth_openprincipals(const char *, struct passwd *, int);
int sys_auth_passwd(struct ssh *, const char *);
/* This allows GSSAPI methods to do things to the child's environment based
@@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) {
char *envstr;
#if defined(KRB5) && !defined(HEIMDAL)
-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
#endif
- if (gssapi_client.store.filename == NULL &&
- gssapi_client.store.envval == NULL &&
- gssapi_client.store.envvar == NULL)
+ if (gssapi_client.store.envval == NULL)
return;
ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
--- openssh-8.6p1/gss-serv-krb5.c.ccache_name 2021-04-19 14:05:10.852744562 +0200
+++ openssh-8.6p1/gss-serv-krb5.c 2021-04-19 14:05:10.854744577 +0200
@@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
#endif /* AUTH_H */
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index 14502c5a6..df55512d3 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
/* This writes out any forwarded credentials from the structure populated
* during userauth. Called after we have setuid to the user */
@ -381,7 +372,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
{
krb5_ccache ccache;
@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
OM_uint32 maj_status, min_status;
const char *new_ccname, *new_cctype;
const char *errmsg;
@ -399,7 +390,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
#ifdef HEIMDAL
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
krb5_get_err_text(krb_context, problem));
# endif
krb5_free_error_message(krb_context, errmsg);
@ -418,7 +409,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
}
#endif /* #ifdef HEIMDAL */
@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
errmsg = krb5_get_error_message(krb_context, problem);
logit("krb5_parse_name(): %.100s", errmsg);
krb5_free_error_message(krb_context, errmsg);
@ -427,7 +418,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
}
if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) {
@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
krb5_free_error_message(krb_context, errmsg);
krb5_free_principal(krb_context, princ);
krb5_cc_destroy(krb_context, ccache);
@ -436,7 +427,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
}
krb5_free_principal(krb_context, princ);
@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
client->creds, ccache))) {
logit("gss_krb5_copy_ccache() failed");
krb5_cc_destroy(krb_context, ccache);
@ -474,7 +465,7 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
do_pam_putenv(client->store.envvar, client->store.envval);
#endif
@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
client->store.data = krb_context;
@ -483,10 +474,44 @@ diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
}
int
diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c
--- openssh-8.6p1/servconf.c.ccache_name 2021-04-19 14:05:10.848744532 +0200
+++ openssh-8.6p1/servconf.c 2021-04-19 14:05:10.854744577 +0200
@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions
diff --git a/gss-serv.c b/gss-serv.c
index 6bac42931..d2bc03486 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void)
}
/* As user */
-void
+int
ssh_gssapi_storecreds(void)
{
if (gssapi_client.mech && gssapi_client.mech->storecreds) {
- (*gssapi_client.mech->storecreds)(&gssapi_client);
+ return (*gssapi_client.mech->storecreds)(&gssapi_client);
} else
debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
+
+ return 0;
}
/* This allows GSSAPI methods to do things to the child's environment based
@@ -500,9 +502,7 @@ ssh_gssapi_rekey_creds(void) {
char *envstr;
#endif
- if (gssapi_client.store.filename == NULL &&
- gssapi_client.store.envval == NULL &&
- gssapi_client.store.envvar == NULL)
+ if (gssapi_client.store.envval == NULL)
return;
ok = mm_ssh_gssapi_update_creds(&gssapi_client.store);
diff --git a/servconf.c b/servconf.c
index 3b93ca829..7bf1507df 100644
--- a/servconf.c
+++ b/servconf.c
@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions *options)
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
options->kerberos_get_afs_token = -1;
@ -494,7 +519,7 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c
options->gss_authentication=-1;
options->gss_keyex = -1;
options->gss_cleanup_creds = -1;
@@ -359,6 +360,8 @@ fill_default_server_options(ServerOption
@@ -376,6 +377,8 @@ fill_default_server_options(ServerOptions *options)
options->kerberos_ticket_cleanup = 1;
if (options->kerberos_get_afs_token == -1)
options->kerberos_get_afs_token = 0;
@ -503,16 +528,16 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c
if (options->gss_authentication == -1)
options->gss_authentication = 0;
if (options->gss_keyex == -1)
@@ -506,7 +509,7 @@ typedef enum {
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
@@ -558,7 +561,7 @@ typedef enum {
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
- sKerberosGetAFSToken, sPasswordAuthentication,
+ sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -593,11 +597,13 @@ static struct {
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -649,11 +652,13 @@ static struct {
#else
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
@ -526,7 +551,7 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c
#endif
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
@@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO
@@ -1662,6 +1667,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
intptr = &options->kerberos_get_afs_token;
goto parse_flag;
@ -537,7 +562,7 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c
case sGssAuthentication:
intptr = &options->gss_authentication;
goto parse_flag;
@@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o)
@@ -3295,6 +3304,7 @@ dump_config(ServerOptions *o)
# ifdef USE_AFS
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
# endif
@ -545,10 +570,11 @@ diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c
#endif
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h
--- openssh-8.6p1/servconf.h.ccache_name 2021-04-19 14:05:10.848744532 +0200
+++ openssh-8.6p1/servconf.h 2021-04-19 14:05:10.855744584 +0200
@@ -140,6 +140,8 @@ typedef struct {
diff --git a/servconf.h b/servconf.h
index c3f501400..a4a38d6d7 100644
--- a/servconf.h
+++ b/servconf.h
@@ -149,6 +149,8 @@ typedef struct {
* file on logout. */
int kerberos_get_afs_token; /* If true, try to get AFS token if
* authenticated with Kerberos. */
@ -557,10 +583,11 @@ diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h
int gss_authentication; /* If true, permit GSSAPI authentication */
int gss_keyex; /* If true, permit GSSAPI key exchange */
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c
--- openssh-8.6p1/session.c.ccache_name 2021-04-19 14:05:10.852744562 +0200
+++ openssh-8.6p1/session.c 2021-04-19 14:05:10.855744584 +0200
@@ -1038,7 +1038,8 @@ do_setup_env(struct ssh *ssh, Session *s
diff --git a/session.c b/session.c
index 3eae5bdf3..b8a2dae92 100644
--- a/session.c
+++ b/session.c
@@ -987,7 +987,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
/* Allow any GSSAPI methods that we've used to alter
* the child's environment as they see fit
*/
@ -570,7 +597,7 @@ diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c
#endif
/* Set basic environment. */
@@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s
@@ -1063,7 +1064,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
}
#endif
#ifdef KRB5
@ -579,10 +606,33 @@ diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c
child_set_env(&env, &envsize, "KRB5CCNAME",
s->authctxt->krb5_ccname);
#endif
diff -up openssh-8.6p1/sshd.c.ccache_name openssh-8.6p1/sshd.c
--- openssh-8.6p1/sshd.c.ccache_name 2021-04-19 14:05:10.849744540 +0200
+++ openssh-8.6p1/sshd.c 2021-04-19 14:05:10.855744584 +0200
@@ -2284,7 +2284,7 @@ main(int ac, char **av)
diff --git a/ssh-gss.h b/ssh-gss.h
index db34d77f4..a894e23c9 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -116,7 +116,7 @@ typedef struct ssh_gssapi_mech_struct {
int (*dochild) (ssh_gssapi_client *);
int (*userok) (ssh_gssapi_client *, char *);
int (*localname) (ssh_gssapi_client *, char **);
- void (*storecreds) (ssh_gssapi_client *);
+ int (*storecreds) (ssh_gssapi_client *);
int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *);
} ssh_gssapi_mech;
@@ -186,7 +186,7 @@ int ssh_gssapi_userok(char *name, 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);
-void ssh_gssapi_storecreds(void);
+int ssh_gssapi_storecreds(void);
const char *ssh_gssapi_displayname(void);
char *ssh_gssapi_server_mechanisms(void);
diff --git a/sshd-session.c b/sshd-session.c
index 6e28020e9..028d5850e 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1327,7 +1327,7 @@ main(int ac, char **av)
#ifdef GSSAPI
if (options.gss_authentication) {
temporarily_use_uid(authctxt->pw);
@ -591,10 +641,11 @@ diff -up openssh-8.6p1/sshd.c.ccache_name openssh-8.6p1/sshd.c
restore_uid();
}
#endif
diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5
--- openssh-8.6p1/sshd_config.5.ccache_name 2021-04-19 14:05:10.849744540 +0200
+++ openssh-8.6p1/sshd_config.5 2021-04-19 14:05:10.856744592 +0200
@@ -939,6 +939,14 @@ Specifies whether to automatically destr
diff --git a/sshd_config.5 b/sshd_config.5
index b90068bf3..cae0fd0b4 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1032,6 +1032,14 @@ Specifies whether to automatically destroy the user's ticket cache
file on logout.
The default is
.Cm yes .
@ -607,26 +658,8 @@ diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5
+can lead to overwriting previous tickets by subseqent connections to the same
+user account.
.It Cm KexAlgorithms
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
diff -up openssh-8.6p1/ssh-gss.h.ccache_name openssh-8.6p1/ssh-gss.h
--- openssh-8.6p1/ssh-gss.h.ccache_name 2021-04-19 14:05:10.852744562 +0200
+++ openssh-8.6p1/ssh-gss.h 2021-04-19 14:05:10.855744584 +0200
@@ -114,7 +114,7 @@ typedef struct ssh_gssapi_mech_struct {
int (*dochild) (ssh_gssapi_client *);
int (*userok) (ssh_gssapi_client *, char *);
int (*localname) (ssh_gssapi_client *, char **);
- void (*storecreds) (ssh_gssapi_client *);
+ int (*storecreds) (ssh_gssapi_client *);
int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *);
} ssh_gssapi_mech;
@@ -175,7 +175,7 @@ int ssh_gssapi_userok(char *name, struct
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);
-void ssh_gssapi_storecreds(void);
+int ssh_gssapi_storecreds(void);
const char *ssh_gssapi_displayname(void);
char *ssh_gssapi_server_mechanisms(void);
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
--
2.52.0

View file

@ -1,8 +1,20 @@
From 0b19c3dabb1e23837238e90238f1ab5fa3c99df8 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 14/53] openssh-7.2p2-k5login_directory
---
auth-krb5.c | 16 ++++++++++++++++
auth.h | 2 ++
gss-serv-krb5.c | 21 ++++++++++++++++++++-
sshd.8 | 4 ++++
4 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/auth-krb5.c b/auth-krb5.c
index 2b02a04..19b9364 100644
index 035032221..4910aa38a 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -375,5 +375,21 @@ cleanup:
@@ -465,5 +465,21 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm
return (krb5_cc_resolve(ctx, ccname, ccache));
}
}
@ -25,10 +37,10 @@ index 2b02a04..19b9364 100644
#endif /* !HEIMDAL */
#endif /* KRB5 */
diff --git a/auth.h b/auth.h
index f9d191c..c432d2f 100644
index 10e88e11f..391630350 100644
--- a/auth.h
+++ b/auth.h
@@ -222,6 +222,8 @@ int sys_auth_passwd(Authctxt *, const char *);
@@ -247,6 +247,8 @@ int sys_auth_passwd(struct ssh *, const char *);
#if defined(KRB5) && !defined(HEIMDAL)
krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
@ -38,10 +50,10 @@ index f9d191c..c432d2f 100644
#endif /* AUTH_H */
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index a7c0c5f..df8cc9a 100644
index df55512d3..820f794cf 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -244,8 +244,27 @@ ssh_gssapi_k5login_exists()
@@ -144,8 +144,27 @@ ssh_gssapi_k5login_exists()
{
char file[MAXPATHLEN];
struct passwd *pw = the_authctxt->pw;
@ -71,10 +83,10 @@ index a7c0c5f..df8cc9a 100644
}
diff --git a/sshd.8 b/sshd.8
index 5c4f15b..135e290 100644
index e2d8ff003..fa33f5232 100644
--- a/sshd.8
+++ b/sshd.8
@@ -806,6 +806,10 @@ rlogin/rsh.
@@ -880,6 +880,10 @@ rlogin/rsh.
These files enforce GSSAPI/Kerberos authentication access control.
Further details are described in
.Xr ksu 1 .
@ -85,3 +97,6 @@ index 5c4f15b..135e290 100644
.Pp
.It Pa ~/.ssh/
This directory is the default location for all user-specific configuration
--
2.52.0

View file

@ -1,7 +1,22 @@
diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c
--- openssh-7.4p1/auth-krb5.c.kuserok 2016-12-23 14:36:07.640465939 +0100
+++ openssh-7.4p1/auth-krb5.c 2016-12-23 14:36:07.644465936 +0100
@@ -56,6 +56,21 @@
From d0c2e8ddde548c79144547152b523346ae9f0358 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 15/53] openssh-6.6p1-kuserok
---
auth-krb5.c | 20 ++++++++-
gss-serv-krb5.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++--
servconf.c | 13 +++++-
servconf.h | 1 +
sshd_config | 1 +
sshd_config.5 | 5 +++
6 files changed, 139 insertions(+), 7 deletions(-)
diff --git a/auth-krb5.c b/auth-krb5.c
index 4910aa38a..b9c261a24 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -55,6 +55,21 @@
extern ServerOptions options;
@ -23,7 +38,7 @@ diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c
static int
krb5_init(void *context)
{
@@ -160,8 +175,9 @@ auth_krb5_password(Authctxt *authctxt, c
@@ -158,8 +173,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
if (problem)
goto out;
@ -35,10 +50,11 @@ diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c
problem = -1;
goto out;
}
diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c
--- openssh-7.4p1/gss-serv-krb5.c.kuserok 2016-12-23 14:36:07.640465939 +0100
+++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 14:36:07.644465936 +0100
@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index 820f794cf..187faf929 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -66,6 +66,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *,
int);
static krb5_context krb_context = NULL;
@ -46,7 +62,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
@@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void)
@@ -91,6 +92,103 @@ ssh_gssapi_krb5_init(void)
* Returns true if the user is OK to log in, otherwise returns 0
*/
@ -150,7 +166,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c
static int
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
{
@@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
@@ -115,7 +213,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
/* NOTE: .k5login and .k5users must opened as root, not the user,
* because if they are on a krb5-protected filesystem, user credentials
* to access these files aren't available yet. */
@ -160,7 +176,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c
retval = 1;
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
name, (char *)client->displayname.value);
@@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
@@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
/* If both .k5login and .k5users DNE, self-login is ok. */
if (!k5login_exists && (access(file, F_OK) == -1)) {
@ -172,18 +188,19 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c
}
if ((fp = fopen(file, "r")) == NULL) {
int saved_errno = errno;
diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
--- openssh-7.4p1/servconf.c.kuserok 2016-12-23 14:36:07.630465944 +0100
+++ openssh-7.4p1/servconf.c 2016-12-23 15:11:52.278133344 +0100
@@ -116,6 +116,7 @@ initialize_server_options(ServerOptions
diff --git a/servconf.c b/servconf.c
index 7bf1507df..8f4b2b43e 100644
--- a/servconf.c
+++ b/servconf.c
@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions *options)
options->gss_strict_acceptor = -1;
options->gss_store_rekey = -1;
options->gss_kex_algorithms = NULL;
+ options->use_kuserok = -1;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->permit_empty_passwd = -1;
@@ -278,6 +279,8 @@ fill_default_server_options(ServerOption
options->permit_empty_passwd = -1;
@@ -393,6 +394,8 @@ fill_default_server_options(ServerOptions *options)
if (options->gss_kex_algorithms == NULL)
options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
#endif
@ -192,16 +209,16 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -399,7 +402,7 @@ typedef enum {
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
@@ -561,7 +564,7 @@ typedef enum {
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
- sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication,
+ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -478,12 +481,14 @@ static struct {
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -653,12 +656,14 @@ static struct {
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL },
@ -216,18 +233,18 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
#endif
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
@@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions
}
break;
@@ -2431,6 +2436,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
}
break;
+ case sKerberosUseKuserok:
+ intptr = &options->use_kuserok;
+ goto parse_flag;
+
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
@@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
@@ -2997,6 +3006,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(client_alive_interval);
M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk);
@ -235,18 +252,19 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
@@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o)
@@ -3305,6 +3315,7 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
# endif
dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
#endif
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h
--- openssh-7.4p1/servconf.h.kuserok 2016-12-23 14:36:07.630465944 +0100
+++ openssh-7.4p1/servconf.h 2016-12-23 14:36:07.645465936 +0100
@@ -118,6 +118,7 @@ typedef struct {
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
diff --git a/servconf.h b/servconf.h
index a4a38d6d7..11de36a23 100644
--- a/servconf.h
+++ b/servconf.h
@@ -151,6 +151,7 @@ typedef struct {
* authenticated with Kerberos. */
int kerberos_unique_ccache; /* If true, the acquired ticket will
* be stored in per-session ccache */
@ -254,10 +272,23 @@ diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h
int gss_authentication; /* If true, permit GSSAPI authentication */
int gss_keyex; /* If true, permit GSSAPI key exchange */
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5
--- openssh-7.4p1/sshd_config.5.kuserok 2016-12-23 14:36:07.637465940 +0100
+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:14:03.117162222 +0100
@@ -850,6 +850,10 @@ Specifies whether to automatically destr
diff --git a/sshd_config b/sshd_config
index 8db9f0fb1..ea5a878e6 100644
--- a/sshd_config
+++ b/sshd_config
@@ -75,6 +75,7 @@ AuthorizedKeysFile .ssh/authorized_keys
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
+#KerberosUseKuserok yes
# GSSAPI options
#GSSAPIAuthentication no
diff --git a/sshd_config.5 b/sshd_config.5
index cae0fd0b4..c360fcfff 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1040,6 +1040,10 @@ The default value
.Cm no
can lead to overwriting previous tickets by subseqent connections to the same
user account.
@ -266,9 +297,9 @@ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5
+The default is
+.Cm yes .
.It Cm KexAlgorithms
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
@@ -1078,6 +1082,7 @@ Available keywords are
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
@@ -1354,6 +1358,7 @@ Available keywords are
.Cm IPQoS ,
.Cm KbdInteractiveAuthentication ,
.Cm KerberosAuthentication ,
@ -276,14 +307,6 @@ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5
.Cm LogLevel ,
.Cm MaxAuthTries ,
.Cm MaxSessions ,
diff -up openssh-7.4p1/sshd_config.kuserok openssh-7.4p1/sshd_config
--- openssh-7.4p1/sshd_config.kuserok 2016-12-23 14:36:07.631465943 +0100
+++ openssh-7.4p1/sshd_config 2016-12-23 14:36:07.646465935 +0100
@@ -73,6 +73,7 @@ ChallengeResponseAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
+#KerberosUseKuserok yes
# GSSAPI options
#GSSAPIAuthentication no
--
2.52.0

View file

@ -0,0 +1,28 @@
From d755d647c33f96cd4ec7d5499d11ecd443bdb098 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 16/53] openssh-6.4p1-fromto-remote
---
scp.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/scp.c b/scp.c
index c5f573cc1..d97a54cc4 100644
--- a/scp.c
+++ b/scp.c
@@ -1148,7 +1148,10 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
addargs(&alist, "%s", ssh_program);
addargs(&alist, "-x");
addargs(&alist, "-oClearAllForwardings=yes");
- addargs(&alist, "-n");
+ if (isatty(fileno(stdin)))
+ addargs(&alist, "-t");
+ else
+ addargs(&alist, "-n");
for (j = 0; j < remote_remote_args.num; j++) {
addargs(&alist, "%s",
remote_remote_args.list[j]);
--
2.52.0

View file

@ -1,7 +1,25 @@
diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c
--- openssh-8.6p1/log.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/log.c 2021-04-19 14:43:08.544843434 +0200
@@ -194,6 +194,11 @@ void
From 674851677d1e38cf6992948f8f452e46107a2014 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 17/53] openssh-6.6.1p1-log-in-chroot
---
log.c | 11 +++++++++--
log.h | 1 +
monitor.c | 17 +++++++++++++++--
monitor.h | 2 +-
session.c | 26 +++++++++++++++-----------
sftp-server-main.c | 2 +-
sftp-server.c | 6 +++---
sftp.h | 2 +-
sshd-session.c | 7 ++++++-
9 files changed, 52 insertions(+), 22 deletions(-)
diff --git a/log.c b/log.c
index 5969c4a16..49b0c8a68 100644
--- a/log.c
+++ b/log.c
@@ -196,6 +196,11 @@ void
log_init(const char *av0, LogLevel level, SyslogFacility facility,
int on_stderr)
{
@ -13,7 +31,7 @@ diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
struct syslog_data sdata = SYSLOG_DATA_INIT;
#endif
@@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level
@@ -208,8 +213,10 @@ log_init(const char *av0, LogLevel level, SyslogFacility facility,
exit(1);
}
@ -26,9 +44,10 @@ diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c
log_on_stderr = on_stderr;
if (on_stderr)
diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h
--- openssh-8.6p1/log.h.log-in-chroot 2021-04-19 14:43:08.544843434 +0200
+++ openssh-8.6p1/log.h 2021-04-19 14:56:46.931042176 +0200
diff --git a/log.h b/log.h
index 8e8dfc23f..70048a8af 100644
--- a/log.h
+++ b/log.h
@@ -52,6 +52,7 @@ typedef enum {
typedef void (log_handler_fn)(LogLevel, int, const char *, void *);
@ -37,43 +56,11 @@ diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h
LogLevel log_level_get(void);
int log_change_level(LogLevel);
int log_is_on_stderr(void);
diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c
--- openssh-8.6p1/monitor.c.log-in-chroot 2021-04-19 14:43:08.526843298 +0200
+++ openssh-8.6p1/monitor.c 2021-04-19 14:55:25.286424043 +0200
@@ -297,6 +297,8 @@ monitor_child_preauth(struct ssh *ssh, s
close(pmonitor->m_log_sendfd);
pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1;
+ pmonitor->m_state = "preauth";
+
authctxt = (Authctxt *)ssh->authctxt;
memset(authctxt, 0, sizeof(*authctxt));
ssh->authctxt = authctxt;
@@ -408,6 +410,8 @@ monitor_child_postauth(struct ssh *ssh,
close(pmonitor->m_recvfd);
pmonitor->m_recvfd = -1;
+ pmonitor->m_state = "postauth";
+
monitor_set_child_handler(pmonitor->m_pid);
ssh_signal(SIGHUP, &monitor_child_handler);
ssh_signal(SIGTERM, &monitor_child_handler);
@@ -480,7 +484,7 @@ monitor_read_log(struct monitor *pmonito
/* Log it */
if (log_level_name(level) == NULL)
fatal_f("invalid log level %u (corrupted message?)", level);
- sshlogdirect(level, forced, "%s [preauth]", msg);
+ sshlogdirect(level, forced, "%s [%s]", msg, pmonitor->m_state);
sshbuf_free(logmsg);
free(msg);
@@ -1868,13 +1872,28 @@ monitor_init(void)
mon = xcalloc(1, sizeof(*mon));
monitor_openfds(mon, 1);
+ mon->m_state = "";
+
return mon;
diff --git a/monitor.c b/monitor.c
index d463d6a9c..453469665 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2007,9 +2007,22 @@ monitor_init(void)
}
void
@ -98,14 +85,11 @@ diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c
}
#ifdef GSSAPI
diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h
--- openssh-8.6p1/monitor.h.log-in-chroot 2021-04-19 14:43:08.527843305 +0200
+++ openssh-8.6p1/monitor.h 2021-04-19 14:43:08.545843441 +0200
@@ -80,10 +80,11 @@ struct monitor {
int m_log_sendfd;
struct kex **m_pkex;
pid_t m_pid;
+ char *m_state;
diff --git a/monitor.h b/monitor.h
index dbc7e0037..d4d631ddc 100644
--- a/monitor.h
+++ b/monitor.h
@@ -85,7 +85,7 @@ struct monitor {
};
struct monitor *monitor_init(void);
@ -114,10 +98,11 @@ diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h
struct Authctxt;
void monitor_child_preauth(struct ssh *, struct monitor *);
diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
--- openssh-8.6p1/session.c.log-in-chroot 2021-04-19 14:43:08.534843358 +0200
+++ openssh-8.6p1/session.c 2021-04-19 14:43:08.545843441 +0200
@@ -160,6 +160,7 @@ login_cap_t *lc;
diff --git a/session.c b/session.c
index b8a2dae92..d034f5c65 100644
--- a/session.c
+++ b/session.c
@@ -162,6 +162,7 @@ login_cap_t *lc;
static int is_child = 0;
static int in_chroot = 0;
@ -125,7 +110,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
/* File containing userauth info, if ExposeAuthInfo set */
static char *auth_info_file = NULL;
@@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con
@@ -632,6 +633,7 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
int ret;
const char *forced = NULL, *tty = NULL;
char session_type[1024];
@ -133,7 +118,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
if (options.adm_forced_command) {
original_command = command;
@@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con
@@ -691,6 +693,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
tty += 5;
}
@ -144,7 +129,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d",
session_type,
tty == NULL ? "" : " on ",
@@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh)
@@ -1469,14 +1475,6 @@ child_close_fds(struct ssh *ssh)
/* Stop directing logs to a high-numbered fd before we close it */
log_redirect_stderr_to(NULL);
@ -159,7 +144,7 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
}
/*
@@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co
@@ -1609,8 +1607,6 @@ do_child(struct ssh *ssh, Session *s, const char *command)
exit(1);
}
@ -168,10 +153,10 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
do_rc_files(ssh, s, shell);
/* restore SIGPIPE for child */
@@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co
argv[i] = NULL;
optind = optreset = 1;
__progname = argv[0];
@@ -1638,9 +1634,17 @@ do_child(struct ssh *ssh, Session *s, const char *command)
#ifdef WITH_SELINUX
ssh_selinux_change_context("sftpd_t");
#endif
- exit(sftp_server_main(i, argv, s->pw));
+ exit(sftp_server_main(i, argv, s->pw, have_dev_log));
}
@ -187,29 +172,31 @@ diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
fflush(NULL);
/* Get the last component of the shell name. */
diff -up openssh-8.6p1/sftp.h.log-in-chroot openssh-8.6p1/sftp.h
--- openssh-8.6p1/sftp.h.log-in-chroot 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/sftp.h 2021-04-19 14:43:08.545843441 +0200
@@ -97,5 +97,5 @@
diff --git a/sftp-server-main.c b/sftp-server-main.c
index 2c70f89bc..bbb79f278 100644
--- a/sftp-server-main.c
+++ b/sftp-server-main.c
@@ -48,5 +48,5 @@ main(int argc, char **argv)
return 1;
}
struct passwd;
-int sftp_server_main(int, char **, struct passwd *);
+int sftp_server_main(int, char **, struct passwd *, int);
void sftp_server_cleanup_exit(int) __attribute__((noreturn));
diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c
--- openssh-8.6p1/sftp-server.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/sftp-server.c 2021-04-19 14:43:08.545843441 +0200
@@ -1644,7 +1644,7 @@ sftp_server_usage(void)
- return (sftp_server_main(argc, argv, user_pw));
+ return (sftp_server_main(argc, argv, user_pw, 0));
}
diff --git a/sftp-server.c b/sftp-server.c
index 777821acd..185ad1459 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1897,7 +1897,7 @@ sftp_server_usage(void)
}
int
-sftp_server_main(int argc, char **argv, struct passwd *user_pw)
+sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler)
{
int i, r, in, out, ch, skipargs = 0, log_stderr = 0;
ssize_t len, olen;
@@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv,
int i, r, in, out, ch, skipargs = 0, log_stderr = 0;
ssize_t len, olen;
@@ -1909,7 +1909,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
extern char *__progname;
__progname = ssh_get_progname(argv[0]);
@ -218,7 +205,7 @@ diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c
pw = pwcopy(user_pw);
@@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv,
@@ -1982,7 +1982,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
}
}
@ -227,21 +214,23 @@ diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c
/*
* On platforms where we can, avoid making /proc/self/{mem,maps}
diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-server-main.c
--- openssh-8.6p1/sftp-server-main.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/sftp-server-main.c 2021-04-19 14:43:08.545843441 +0200
@@ -50,5 +50,5 @@ main(int argc, char **argv)
return 1;
}
diff --git a/sftp.h b/sftp.h
index 2bde8bb7f..ddf1a3968 100644
--- a/sftp.h
+++ b/sftp.h
@@ -97,5 +97,5 @@
- return (sftp_server_main(argc, argv, user_pw));
+ return (sftp_server_main(argc, argv, user_pw, 0));
}
diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c
--- openssh-8.6p1/sshd.c.log-in-chroot 2021-04-19 14:43:08.543843426 +0200
+++ openssh-8.6p1/sshd.c 2021-04-19 14:43:08.545843441 +0200
@@ -559,7 +559,7 @@ privsep_postauth(struct ssh *ssh, Authct
}
struct passwd;
-int sftp_server_main(int, char **, struct passwd *);
+int sftp_server_main(int, char **, struct passwd *, int);
void sftp_server_cleanup_exit(int) __attribute__((noreturn));
diff --git a/sshd-session.c b/sshd-session.c
index 028d5850e..4a5eaa1ff 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -415,7 +415,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
#endif
/* New socket pair */
- monitor_reinit(pmonitor);
@ -249,7 +238,7 @@ diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c
pmonitor->m_pid = fork();
if (pmonitor->m_pid == -1)
@@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct
@@ -434,6 +434,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
close(pmonitor->m_sendfd);
pmonitor->m_sendfd = -1;
@ -261,3 +250,6 @@ diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c
/* Demote the private keys to public keys. */
demote_sensitive_data();
--
2.52.0

View file

@ -0,0 +1,27 @@
From 931f22f77ab2b9cebd96e113f1e3ab179dd1b6cb Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 18/53] openssh-6.6.1p1-scp-non-existing-directory
---
scp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/scp.c b/scp.c
index d97a54cc4..e1992622f 100644
--- a/scp.c
+++ b/scp.c
@@ -1866,6 +1866,10 @@ sink(int argc, char **argv, const char *src)
free(vect[0]);
continue;
}
+ if (buf[0] == 'C' && ! exists && np[strlen(np)-1] == '/') {
+ errno = ENOTDIR;
+ goto bad;
+ }
omode = mode;
mode |= S_IWUSR;
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) {
--
2.52.0

View file

@ -1,7 +1,21 @@
diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-serv-krb5.c
--- openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100
+++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 15:18:40.628216102 +0100
@@ -279,7 +279,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
From ef91c84a26a282adaf95e165ebcdd44a410c4328 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 19/53] openssh-6.6p1-GSSAPIEnablek5users
---
gss-serv-krb5.c | 3 +--
servconf.c | 13 ++++++++++++-
servconf.h | 1 +
sshd_config | 1 +
sshd_config.5 | 6 ++++++
5 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index 187faf929..03188d9b3 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -278,7 +278,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
FILE *fp;
char file[MAXPATHLEN];
char *line = NULL;
@ -9,7 +23,7 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-ser
struct stat st;
struct passwd *pw = the_authctxt->pw;
int found_principal = 0;
@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
/* If both .k5login and .k5users DNE, self-login is ok. */
@ -18,18 +32,19 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-ser
return ssh_krb5_kuserok(krb_context, principal, luser,
k5login_exists);
}
diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
--- openssh-7.4p1/servconf.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100
+++ openssh-7.4p1/servconf.c 2016-12-23 15:35:36.354401156 +0100
@@ -168,6 +168,7 @@ initialize_server_options(ServerOptions
diff --git a/servconf.c b/servconf.c
index 8f4b2b43e..5e40f1b00 100644
--- a/servconf.c
+++ b/servconf.c
@@ -144,6 +144,7 @@ initialize_server_options(ServerOptions *options)
options->gss_store_rekey = -1;
options->gss_kex_algorithms = NULL;
options->use_kuserok = -1;
+ options->enable_k5users = -1;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->permit_empty_passwd = -1;
@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption
options->permit_empty_passwd = -1;
@@ -396,6 +397,8 @@ fill_default_server_options(ServerOptions *options)
#endif
if (options->use_kuserok == -1)
options->use_kuserok = 1;
@ -38,16 +53,16 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -418,7 +421,7 @@ typedef enum {
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
@@ -579,7 +582,7 @@ typedef enum {
sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
sPerSourcePenalties, sPerSourcePenaltyExemptList,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
- sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
+ sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
@@ -497,14 +500,16 @@ static struct {
@@ -675,6 +678,7 @@ static struct {
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
@ -55,8 +70,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
@@ -683,6 +687,7 @@ static struct {
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
@ -64,7 +78,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
#endif
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
@@ -1653,6 +1658,10 @@ process_server_config_line(ServerOptions
@@ -2440,6 +2445,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
intptr = &options->use_kuserok;
goto parse_flag;
@ -72,10 +86,10 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
+ intptr = &options->enable_k5users;
+ goto parse_flag;
+
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
@@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
@@ -3007,6 +3016,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk);
M_CP_INTOPT(use_kuserok);
@ -83,7 +97,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
@@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o)
@@ -3316,6 +3326,7 @@ dump_config(ServerOptions *o)
# endif
dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
@ -91,21 +105,35 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
#endif
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h
--- openssh-7.4p1/servconf.h.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100
+++ openssh-7.4p1/servconf.h 2016-12-23 15:18:40.629216102 +0100
@@ -174,6 +174,7 @@ typedef struct {
int kerberos_unique_ccache; /* If true, the acquired ticket will
* be stored in per-session ccache */
diff --git a/servconf.h b/servconf.h
index 11de36a23..c08cf6a7a 100644
--- a/servconf.h
+++ b/servconf.h
@@ -152,6 +152,7 @@ typedef struct {
int kerberos_unique_ccache; /* If true, the acquired ticket will
* be stored in per-session ccache */
int use_kuserok;
+ int enable_k5users;
int gss_authentication; /* If true, permit GSSAPI authentication */
int gss_keyex; /* If true, permit GSSAPI key exchange */
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5
--- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users 2016-12-23 15:18:40.630216103 +0100
+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:36:21.607408435 +0100
@@ -628,6 +628,12 @@ Specifies whether to automatically destr
diff --git a/sshd_config b/sshd_config
index ea5a878e6..33713c886 100644
--- a/sshd_config
+++ b/sshd_config
@@ -82,6 +82,7 @@ AuthorizedKeysFile .ssh/authorized_keys
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
+#GSSAPIEnablek5users no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
diff --git a/sshd_config.5 b/sshd_config.5
index c360fcfff..a0fc6064f 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -739,6 +739,12 @@ Specifies whether to automatically destroy the user's credentials cache
on logout.
The default is
.Cm yes .
@ -118,14 +146,6 @@ diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_conf
.It Cm GSSAPIKeyExchange
Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange
doesn't rely on ssh keys to verify host identity.
diff -up openssh-7.4p1/sshd_config.GSSAPIEnablek5users openssh-7.4p1/sshd_config
--- openssh-7.4p1/sshd_config.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100
+++ openssh-7.4p1/sshd_config 2016-12-23 15:18:40.631216103 +0100
@@ -80,6 +80,7 @@ GSSAPIAuthentication yes
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
+#GSSAPIEnablek5users no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
--
2.52.0

View file

@ -0,0 +1,25 @@
From cce18d636f4137a4e5401170538868b8b80651c1 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 20/53] openssh-6.8p1-sshdT-output
---
servconf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/servconf.c b/servconf.c
index 5e40f1b00..b63a7f0b0 100644
--- a/servconf.c
+++ b/servconf.c
@@ -3368,7 +3368,7 @@ dump_config(ServerOptions *o)
dump_cfg_string(sXAuthLocation, o->xauth_location);
dump_cfg_string(sCiphers, o->ciphers);
dump_cfg_string(sMacs, o->macs);
- dump_cfg_string(sBanner, o->banner);
+ dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none");
dump_cfg_string(sForceCommand, o->adm_forced_command);
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
--
2.52.0

View file

@ -1,6 +1,17 @@
diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8
--- openssh-7.2p2/sftp-server.8.sftp-force-mode 2016-03-09 19:04:48.000000000 +0100
+++ openssh-7.2p2/sftp-server.8 2016-06-23 16:18:20.463854117 +0200
From 57ae33c2f43425725345c910d90ef6fed75d3b85 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 21/53] openssh-6.7p1-sftp-force-permission
---
sftp-server.8 | 7 +++++++
sftp-server.c | 24 ++++++++++++++++++++++--
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/sftp-server.8 b/sftp-server.8
index 5311bf929..5e6e3aa44 100644
--- a/sftp-server.8
+++ b/sftp-server.8
@@ -38,6 +38,7 @@
.Op Fl P Ar denied_requests
.Op Fl p Ar allowed_requests
@ -22,10 +33,11 @@ diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8
.El
.Pp
On some systems,
diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
--- openssh-7.2p2/sftp-server.c.sftp-force-mode 2016-06-23 16:18:20.446854128 +0200
+++ openssh-7.2p2/sftp-server.c 2016-06-23 16:20:37.950766082 +0200
@@ -69,6 +69,10 @@ struct sshbuf *oqueue;
diff --git a/sftp-server.c b/sftp-server.c
index 185ad1459..e04fc63b3 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -72,6 +72,10 @@ struct sshbuf *oqueue;
/* Version of client */
static u_int version;
@ -36,7 +48,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
/* SSH2_FXP_INIT received */
static int init_done;
@@ -683,6 +687,7 @@ process_open(u_int32_t id)
@@ -741,6 +745,7 @@ process_open(u_int32_t id)
Attrib a;
char *name;
int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE;
@ -44,7 +56,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */
@@ -692,6 +697,10 @@ process_open(u_int32_t id)
@@ -750,6 +755,10 @@ process_open(u_int32_t id)
debug3("request %u: open flags %d", id, pflags);
flags = flags_from_portable(pflags);
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
@ -55,7 +67,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
logit("open \"%s\" flags %s mode 0%o",
name, string_from_portable(pflags), mode);
if (readonly &&
@@ -713,6 +722,8 @@ process_open(u_int32_t id)
@@ -771,6 +780,8 @@ process_open(u_int32_t id)
}
}
}
@ -64,7 +76,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
if (status != SSH2_FX_OK)
send_status(id, status);
free(name);
@@ -1494,7 +1505,7 @@ sftp_server_usage(void)
@@ -1890,7 +1901,7 @@ sftp_server_usage(void)
fprintf(stderr,
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
"[-l log_level]\n\t[-P denied_requests] "
@ -73,7 +85,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
" %s -Q protocol_feature\n",
__progname, __progname);
exit(1);
@@ -1520,7 +1531,7 @@ sftp_server_main(int argc, char **argv,
@@ -1914,7 +1925,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle
pw = pwcopy(user_pw);
while (!skipargs && (ch = getopt(argc, argv,
@ -82,7 +94,7 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
switch (ch) {
case 'Q':
if (strcasecmp(optarg, "requests") != 0) {
@@ -1580,6 +1591,15 @@ sftp_server_main(int argc, char **argv,
@@ -1976,6 +1987,15 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle
fatal("Invalid umask \"%s\"", optarg);
(void)umask((mode_t)mask);
break;
@ -98,3 +110,6 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
case 'h':
default:
sftp_server_usage();
--
2.52.0

View file

@ -1,21 +1,17 @@
Zseries only: Leave the hardware filedescriptors open.
All filedescriptors above 2 are getting closed when a new
sshd process to handle a new client connection is
spawned. As the process also chroot into an empty filesystem
without any device nodes, there is no chance to reopen the
files. This patch filters out the reqired fds in the
closefrom function so these are skipped in the close loop.
Author: Harald Freudenberger <freude@de.ibm.com>
From 25b593f41fa85bcaf1bbdc9c368325c4af033208 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 22/53] openssh-7.2p2-s390-closefrom
---
openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++
openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c
index 49a4f35ff..f61124585 100644
--- a/openbsd-compat/bsd-closefrom.c
+++ b/openbsd-compat/bsd-closefrom.c
@@ -82,7 +82,33 @@ closefrom(int lowfd)
@@ -140,7 +140,33 @@ closefrom(int lowfd)
fd = strtol(dent->d_name, &endp, 10);
if (dent->d_name != endp && *endp == '\0' &&
fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp))
@ -49,4 +45,6 @@ Author: Harald Freudenberger <freude@de.ibm.com>
}
(void) closedir(dirp);
return;
--
2.52.0

View file

@ -1,40 +1,58 @@
diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
--- openssh/auth2-pubkey.c.refactor 2019-04-04 13:19:12.188821236 +0200
+++ openssh/auth2-pubkey.c 2019-04-04 13:19:12.276822078 +0200
@@ -72,6 +72,9 @@
From 4cacb1bda51a2d91cf4cc1c8058b989dfc0c58c8 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 23/53] openssh-7.6p1-cleanup-selinux
---
auth2-pubkey.c | 8 ++++--
misc.c | 5 ++--
misc.h | 2 +-
openbsd-compat/port-linux-sshd.c | 42 +++++++++++++++++---------------
openbsd-compat/port-linux.h | 5 ++--
platform.c | 6 ++++-
sshconnect.c | 2 +-
sshd-auth.c | 2 +-
sshd-session.c | 6 +++--
9 files changed, 46 insertions(+), 32 deletions(-)
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index c326a69ba..b7300ca9e 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -75,6 +75,8 @@
/* import */
extern ServerOptions options;
+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)
@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
@@ -483,7 +485,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key,
if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
+ runas_pw, temporarily_use_uid, restore_uid,
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
+ inetd_flag, the_authctxt)) == 0)
goto out;
uid_swapped = 1;
@@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
@@ -759,7 +762,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key,
if ((pid = subprocess("AuthorizedKeysCommand", command,
ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
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 && !rexeced_flag), the_authctxt)) == 0)
+ inetd_flag, the_authctxt)) == 0)
goto out;
uid_swapped = 1;
diff -up openssh/misc.c.refactor openssh/misc.c
--- openssh/misc.c.refactor 2019-04-04 13:19:12.235821686 +0200
+++ openssh/misc.c 2019-04-04 13:19:12.276822078 +0200
@@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh *
diff --git a/misc.c b/misc.c
index 7e27a38d1..2fd14159d 100644
--- a/misc.c
+++ b/misc.c
@@ -2788,7 +2788,8 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr)
pid_t
subprocess(const char *tag, const char *command,
int ac, char **av, FILE **child, u_int flags,
@ -44,7 +62,7 @@ diff -up openssh/misc.c.refactor openssh/misc.c
{
FILE *f = NULL;
struct stat st;
@@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
@@ -2922,7 +2923,7 @@ subprocess(const char *tag, const char *command,
_exit(1);
}
#ifdef WITH_SELINUX
@ -53,10 +71,11 @@ diff -up openssh/misc.c.refactor openssh/misc.c
error ("failed to copy environment: %s",
strerror(errno));
_exit(127);
diff -up openssh/misc.h.refactor openssh/misc.h
--- openssh/misc.h.refactor 2019-04-04 13:19:12.251821839 +0200
+++ openssh/misc.h 2019-04-04 13:19:12.276822078 +0200
@@ -235,7 +235,7 @@ struct passwd *fakepw(void);
diff --git a/misc.h b/misc.h
index f3c5a18c6..8cdfd7cec 100644
--- a/misc.h
+++ b/misc.h
@@ -124,7 +124,7 @@ typedef void privrestore_fn(void);
#define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */
#define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */
pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int,
@ -65,36 +84,22 @@ diff -up openssh/misc.h.refactor openssh/misc.h
typedef struct arglist arglist;
struct arglist {
diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h
--- openssh/openbsd-compat/port-linux.h.refactor 2019-04-04 13:19:12.256821887 +0200
+++ openssh/openbsd-compat/port-linux.h 2019-04-04 13:19:12.276822078 +0200
@@ -26,8 +26,8 @@ void ssh_selinux_setfscreatecon(const ch
int sshd_selinux_enabled(void);
void sshd_selinux_copy_context(void);
-void sshd_selinux_setup_exec_context(char *);
-int sshd_selinux_setup_env_variables(void);
+void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int);
+int sshd_selinux_setup_env_variables(int inetd, void *);
void sshd_selinux_change_privsep_preauth_context(void);
#endif
diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compat/port-linux-sshd.c
--- openssh/openbsd-compat/port-linux-sshd.c.refactor 2019-04-04 13:19:12.256821887 +0200
+++ openssh/openbsd-compat/port-linux-sshd.c 2019-04-04 13:19:12.276822078 +0200
@@ -49,11 +49,6 @@
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
index 4d56745f7..ab083a637 100644
--- a/openbsd-compat/port-linux-sshd.c
+++ b/openbsd-compat/port-linux-sshd.c
@@ -48,10 +48,6 @@
#include <unistd.h>
#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
sshd_selinux_enabled(void)
@@ -223,7 +218,8 @@ get_user_context(const char *sename, con
@@ -221,7 +217,8 @@ get_user_context(const char *sename, const char *role, const char *lvl,
}
static void
@ -104,7 +109,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
{
*role = NULL;
*level = NULL;
@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
@@ -239,8 +236,8 @@ ssh_selinux_get_role_level(char **role, const char **level)
/* Return the default security context for the given username */
static int
@ -115,7 +120,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
{
char *sename, *lvl;
char *role;
@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -248,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname,
int r = 0;
context_t con = NULL;
@ -124,16 +129,16 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
#ifdef HAVE_GETSEUSERBYNAME
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -270,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname,
if (r == 0) {
/* If launched from xinetd, we must use current level */
- if (inetd_flag && !rexeced_flag) {
- if (inetd_flag) {
+ if (inetd) {
security_context_t sshdsc=NULL;
if (getcon_raw(&sshdsc) < 0)
@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -331,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname,
/* Setup environment variables for pam_selinux */
static int
@ -143,7 +148,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
{
const char *reqlvl;
char *role;
@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
@@ -340,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
debug3_f("setting execution context");
@ -152,12 +157,12 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
- if (inetd_flag && !rexeced_flag) {
- if (inetd_flag) {
+ if (inetd) {
use_current = "1";
} else {
use_current = "";
@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
@@ -360,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
}
static int
@ -170,7 +175,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
}
static int
@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
@@ -372,25 +371,28 @@ do_setenv(char *name, const char *value)
}
int
@ -204,7 +209,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
switch (security_getenforce()) {
case -1:
fatal_f("security_getenforce() failed");
@@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
@@ -406,7 +408,7 @@ sshd_selinux_setup_exec_context(char *pwname)
debug3_f("setting execution context");
@ -213,66 +218,51 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
if (r >= 0) {
r = setexeccon(user_ctx);
if (r < 0) {
diff -up openssh/platform.c.refactor openssh/platform.c
--- openssh/platform.c.refactor 2019-04-04 13:19:12.204821389 +0200
+++ openssh/platform.c 2019-04-04 13:19:12.277822088 +0200
@@ -32,6 +32,9 @@
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index c004071d1..26c5f773b 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -23,8 +23,9 @@ void ssh_selinux_setup_pty(char *, const char *);
void ssh_selinux_change_context(const char *);
void ssh_selinux_setfscreatecon(const char *);
-void sshd_selinux_setup_exec_context(char *);
-int sshd_selinux_setup_env_variables(void);
+int sshd_selinux_enabled(void);
+void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int);
+int sshd_selinux_setup_env_variables(int inetd, void *);
#endif
#ifdef LINUX_OOM_ADJUST
diff --git a/platform.c b/platform.c
index c92a0cba6..66d0c2a6b 100644
--- a/platform.c
+++ b/platform.c
@@ -33,6 +33,8 @@
#include "openbsd-compat/openbsd-compat.h"
extern int use_privsep;
extern ServerOptions options;
+extern int inetd_flag;
+extern int rexeced_flag;
+extern Authctxt *the_authctxt;
void
platform_pre_listen(void)
@@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru
/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
int
@@ -140,7 +142,9 @@ platform_setusercontext_post_groups(struct passwd *pw)
}
#endif /* HAVE_SETPCRED */
#ifdef WITH_SELINUX
- sshd_selinux_setup_exec_context(pw->pw_name);
+ sshd_selinux_setup_exec_context(pw->pw_name,
+ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt,
+ inetd_flag, do_pam_putenv, the_authctxt,
+ options.use_pam);
#endif
}
diff -up openssh/sshd.c.refactor openssh/sshd.c
--- openssh/sshd.c.refactor 2019-04-04 13:19:12.275822068 +0200
+++ openssh/sshd.c 2019-04-04 13:19:51.270195262 +0200
@@ -158,7 +158,7 @@ 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;
/* Flag indicating that sshd should not detach and become a daemon. */
static int no_daemon_flag = 0;
@@ -171,7 +171,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;
@@ -2192,7 +2192,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 && !rexeced_flag), do_pam_putenv, the_authctxt,
+ options.use_pam);
#endif
#ifdef USE_PAM
if (options.use_pam) {
diff -up openssh/sshconnect.c.refactor openssh/sshconnect.c
--- openssh/sshconnect.c.refactor 2021-02-24 00:12:03.065325046 +0100
+++ openssh/sshconnect.c 2021-02-24 00:12:12.126449544 +0100
@@ -892,7 +892,7 @@ load_hostkeys_command(struct hostkeys *h
diff --git a/sshconnect.c b/sshconnect.c
index 912a520c5..babe4a982 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -917,7 +917,7 @@ load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template,
if ((pid = subprocess(tag, command, ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH|
@ -281,3 +271,43 @@ diff -up openssh/sshconnect.c.refactor openssh/sshconnect.c
goto out;
load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1);
diff --git a/sshd-auth.c b/sshd-auth.c
index 5a4ee733c..f3c38a7d1 100644
--- a/sshd-auth.c
+++ b/sshd-auth.c
@@ -120,7 +120,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE;
int debug_flag = 0;
/* Flag indicating that the daemon is being started from inetd. */
-static int inetd_flag = 0;
+int inetd_flag = 0;
/* Saved arguments to main(). */
static char **saved_argv;
diff --git a/sshd-session.c b/sshd-session.c
index 4a5eaa1ff..d6bece941 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -130,7 +130,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE;
int debug_flag = 0;
/* Flag indicating that the daemon is being started from inetd. */
-static int inetd_flag = 0;
+int inetd_flag = 0;
/* debug goes to stderr unless inetd_flag is set */
static int log_stderr = 0;
@@ -1337,7 +1337,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,
+ options.use_pam);
#endif
#ifdef USE_PAM
if (options.use_pam) {
--
2.52.0

View file

@ -0,0 +1,58 @@
From 503297ec6f6eef3bb4906271d170fab848e27298 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 24/53] openssh-7.5p1-sandbox
---
sandbox-seccomp-filter.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index a0692dd2f..e0f2d4289 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -305,6 +305,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_exit_group
SC_ALLOW(__NR_exit_group),
#endif
+#if defined(__NR_flock) && defined(__s390__)
+ SC_ALLOW(__NR_flock),
+#endif
#ifdef __NR_futex
SC_FUTEX(__NR_futex),
#endif
@@ -323,6 +326,21 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_getpid
SC_ALLOW(__NR_getpid),
#endif
+#ifdef __NR_getuid
+ SC_ALLOW(__NR_getuid),
+#endif
+#ifdef __NR_getuid32
+ SC_ALLOW(__NR_getuid32),
+#endif
+#ifdef __NR_geteuid
+ SC_ALLOW(__NR_geteuid),
+#endif
+#ifdef __NR_geteuid32
+ SC_ALLOW(__NR_geteuid32),
+#endif
+#ifdef __NR_gettid
+ SC_ALLOW(__NR_gettid),
+#endif
#ifdef __NR_getrandom
SC_ALLOW(__NR_getrandom),
#endif
@@ -332,6 +350,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_gettimeofday
SC_ALLOW(__NR_gettimeofday),
#endif
+#if defined(__NR_ipc) && defined(__s390__)
+ SC_ALLOW(__NR_ipc),
+#endif
#ifdef __NR_getuid
SC_ALLOW(__NR_getuid),
#endif
--
2.52.0

View file

@ -1,8 +1,17 @@
From e1d86d265d9543c77fa90a33acc70246e68bf3bf Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 25/53] openssh-7.8p1-scp-ipv6
---
scp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scp.c b/scp.c
index 60682c68..9344806e 100644
index e1992622f..621131ffc 100644
--- a/scp.c
+++ b/scp.c
@@ -714,7 +714,9 @@ toremote(int argc, char **argv)
@@ -1169,7 +1169,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
addargs(&alist, "%s", host);
addargs(&alist, "%s", cmd);
addargs(&alist, "%s", src);
@ -13,4 +22,6 @@ index 60682c68..9344806e 100644
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
if (do_local_cmd(&alist) != 0)
--
2.52.0

View file

@ -1,7 +1,18 @@
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh_config.5 openssh-9.3p1-patched/ssh_config.5
--- openssh-9.3p1/ssh_config.5 2023-06-07 10:26:48.284590156 +0200
+++ openssh-9.3p1-patched/ssh_config.5 2023-06-07 10:26:00.623052194 +0200
@@ -378,17 +378,13 @@
From 6d9e08f061451f6cd464af5ec598fa99d15acadb Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 26/53] openssh-8.0p1-crypto-policies
---
ssh_config.5 | 164 ++++++++++++++++++++-------------------------
sshd_config.5 | 179 +++++++++++++++++++-------------------------------
2 files changed, 140 insertions(+), 203 deletions(-)
diff --git a/ssh_config.5 b/ssh_config.5
index 8a4b469cf..8ac5e1633 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -438,17 +438,13 @@ A single argument of
causes no CNAMEs to be considered for canonicalization.
This is the default behaviour.
.It Cm CASignatureAlgorithms
@ -24,7 +35,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
If the specified list begins with a
.Sq +
character, then the specified algorithms will be appended to the default set
@@ -450,20 +446,25 @@
@@ -587,20 +583,25 @@ If the option is set to
(the default),
the check will not be executed.
.It Cm Ciphers
@ -54,21 +65,21 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Pp
The supported ciphers are:
.Bd -literal -offset indent
@@ -479,13 +480,6 @@
@@ -616,13 +617,6 @@ aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
.Ed
.Pp
-The default is:
-.Bd -literal -offset indent
-chacha20-poly1305@openssh.com,
-aes128-ctr,aes192-ctr,aes256-ctr,
-aes128-gcm@openssh.com,aes256-gcm@openssh.com
-aes128-gcm@openssh.com,aes256-gcm@openssh.com,
-aes128-ctr,aes192-ctr,aes256-ctr
-.Ed
-.Pp
The list of available ciphers may also be obtained using
.Qq ssh -Q cipher .
.It Cm ClearAllForwardings
@@ -885,6 +879,11 @@
@@ -1022,6 +1016,11 @@ command line will be passed untouched to the GSSAPI library.
The default is
.Dq no .
.It Cm GSSAPIKexAlgorithms
@ -80,7 +91,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
The list of key exchange algorithms that are offered for GSSAPI
key exchange. Possible values are
.Bd -literal -offset 3n
@@ -897,10 +896,8 @@
@@ -1034,10 +1033,8 @@ gss-nistp256-sha256-,
gss-curve25519-sha256-
.Ed
.Pp
@ -92,7 +103,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.It Cm HashKnownHosts
Indicates that
.Xr ssh 1
@@ -919,36 +916,25 @@
@@ -1056,36 +1053,25 @@ will not be converted automatically,
but may be manually hashed using
.Xr ssh-keygen 1 .
.It Cm HostbasedAcceptedAlgorithms
@ -137,7 +148,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Pp
The
.Fl Q
@@ -1001,6 +987,17 @@
@@ -1138,6 +1124,17 @@ to prefer their algorithms.
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
@ -155,7 +166,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.It Cm HostKeyAlias
Specifies an alias that should be used instead of the
real host name when looking up or saving the host key
@@ -1232,30 +1229,25 @@
@@ -1360,6 +1357,11 @@ it may be zero or more of:
and
.Cm pam .
.It Cm KexAlgorithms
@ -164,8 +175,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
Specifies the permitted KEX (Key Exchange) algorithms that will be used and
their preference order.
The selected algorithm will be the first algorithm in this list that
@@ -1368,29 +1370,17 @@ Multiple algorithms must be comma-separated.
.Pp
If the specified list begins with a
.Sq +
-character, then the specified algorithms will be appended to the default set
@ -181,9 +195,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.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,
-mlkem768x25519-sha256,
-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,
-curve25519-sha256,curve25519-sha256@libssh.org,
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
-diffie-hellman-group-exchange-sha256,
@ -191,11 +207,12 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
-diffie-hellman-group18-sha512,
-diffie-hellman-group14-sha256
-.Ed
+built-in openssh default set.
.Pp
The list of available key exchange algorithms may also be obtained using
+built-in openssh default set.
The list of supported key exchange algorithms may also be obtained using
.Qq ssh -Q kex .
@@ -1365,37 +1357,33 @@
.It Cm KnownHostsCommand
@@ -1506,37 +1496,33 @@ function, and all code in the
file.
This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
@ -242,7 +259,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac .
.It Cm NoHostAuthenticationForLocalhost
@@ -1567,39 +1555,31 @@
@@ -1725,39 +1711,31 @@ instead of continuing to execute and pass data.
The default is
.Cm no .
.It Cm PubkeyAcceptedAlgorithms
@ -294,7 +311,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.It Cm PubkeyAuthentication
Specifies whether to try public key authentication.
The argument to this keyword must be
@@ -2265,7 +2245,9 @@
@@ -2504,7 +2482,9 @@ for those users who do not have a configuration file.
This file must be world-readable.
.El
.Sh SEE ALSO
@ -305,10 +322,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshd_config.5 openssh-9.3p1-patched/sshd_config.5
--- openssh-9.3p1/sshd_config.5 2023-06-07 10:26:48.277590077 +0200
+++ openssh-9.3p1-patched/sshd_config.5 2023-06-07 10:26:00.592051845 +0200
@@ -379,17 +379,13 @@
diff --git a/sshd_config.5 b/sshd_config.5
index a0fc6064f..c172d5aab 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -379,17 +379,13 @@ If the argument is
then no banner is displayed.
By default, no banner is displayed.
.It Cm CASignatureAlgorithms
@ -331,7 +349,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
If the specified list begins with a
.Sq +
character, then the specified algorithms will be appended to the default set
@@ -525,20 +521,25 @@
@@ -533,20 +529,25 @@ The default is
indicating not to
.Xr chroot 2 .
.It Cm Ciphers
@ -361,21 +379,21 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Pp
The supported ciphers are:
.Pp
@@ -565,13 +566,6 @@
@@ -573,13 +574,6 @@ aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-chacha20-poly1305@openssh.com,
-aes128-ctr,aes192-ctr,aes256-ctr,
-aes128-gcm@openssh.com,aes256-gcm@openssh.com
-aes128-gcm@openssh.com,aes256-gcm@openssh.com,
-aes128-ctr,aes192-ctr,aes256-ctr
-.Ed
-.Pp
The list of available ciphers may also be obtained using
.Qq ssh -Q cipher .
.It Cm ClientAliveCountMax
@@ -766,53 +760,43 @@
@@ -774,53 +768,43 @@ For this to work
.Cm GSSAPIKeyExchange
needs to be enabled in the server and also used by the client.
.It Cm GSSAPIKexAlgorithms
@ -448,7 +466,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostbasedAcceptedAlgorithms .
@@ -879,25 +863,14 @@
@@ -887,25 +871,14 @@ is specified, the location of the socket will be read from the
.Ev SSH_AUTH_SOCK
environment variable.
.It Cm HostKeyAlgorithms
@ -479,7 +497,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts
@@ -1044,20 +1017,25 @@
@@ -1051,6 +1024,11 @@ Specifies whether to look at .k5login file for user's aliases.
The default is
.Cm yes .
.It Cm KexAlgorithms
@ -488,9 +506,12 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
Alternately if the specified list begins with a
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
The ordering of this list is not important, as the client specifies the
@@ -1059,16 +1037,16 @@ Multiple algorithms must be comma-separated.
.Pp
If the specified list begins with a
.Sq +
-character, then the specified algorithms will be appended to the default set
-instead of replacing them.
@ -506,27 +527,25 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
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
@@ -1089,16 +1067,6 @@
@@ -1105,14 +1083,6 @@ sntrup761x25519-sha512
sntrup761x25519-sha512@openssh.com
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-sntrup761x25519-sha512@openssh.com,
-mlkem768x25519-sha256,
-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,
-curve25519-sha256,curve25519-sha256@libssh.org,
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
-diffie-hellman-group-exchange-sha256,
-diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
-diffie-hellman-group14-sha256
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
-.Ed
-.Pp
The list of available key exchange algorithms may also be obtained using
The list of supported key exchange algorithms may also be obtained using
.Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress
@@ -1184,21 +1152,26 @@
@@ -1199,21 +1169,26 @@ function, and all code in the
file.
This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
@ -557,7 +576,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Pp
The algorithms that contain
.Qq -etm
@@ -1241,15 +1214,6 @@
@@ -1256,15 +1231,6 @@ umac-64-etm@openssh.com
umac-128-etm@openssh.com
.El
.Pp
@ -573,7 +592,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac .
.It Cm Match
@@ -1633,36 +1597,25 @@
@@ -1751,36 +1717,25 @@ or equivalent.)
The default is
.Cm yes .
.It Cm PubkeyAcceptedAlgorithms
@ -619,7 +638,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q PubkeyAcceptedAlgorithms .
@@ -2131,7 +2084,9 @@
@@ -2281,7 +2236,9 @@ This file should be writable by root only, but it is recommended
.El
.Sh SEE ALSO
.Xr sftp-server 8 ,
@ -630,3 +649,6 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free
--
2.52.0

View file

@ -0,0 +1,157 @@
From d73633dd9770bea0c3802075842398faf3e55e30 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 27/53] openssh-8.0p1-openssl-kdf
---
configure.ac | 1 +
kex.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+)
diff --git a/configure.ac b/configure.ac
index adccaebd4..805be4b5e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3182,6 +3182,7 @@ if test "x$openssl" = "xyes" ; then
HMAC_CTX_init \
RSA_generate_key_ex \
RSA_get_default_method \
+ EVP_KDF_CTX_new \
])
# OpenSSL_add_all_algorithms may be a macro.
diff --git a/kex.c b/kex.c
index 9a2ce6d88..5f9530908 100644
--- a/kex.c
+++ b/kex.c
@@ -38,6 +38,11 @@
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
#include <openssl/dh.h>
+# ifdef HAVE_EVP_KDF_CTX_NEW
+# include <openssl/kdf.h>
+# include <openssl/param_build.h>
+# include <openssl/core_names.h>
+# endif
#endif
#include "ssh.h"
@@ -1077,6 +1082,107 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq)
return r;
}
+#ifdef HAVE_EVP_KDF_CTX_NEW
+static const char *
+digest_to_md(int digest_type)
+{
+ switch (digest_type) {
+ case SSH_DIGEST_SHA1:
+ return SN_sha1;
+ case SSH_DIGEST_SHA256:
+ return SN_sha256;
+ case SSH_DIGEST_SHA384:
+ return SN_sha384;
+ case SSH_DIGEST_SHA512:
+ return SN_sha512;
+ }
+ return NULL;
+}
+
+static int
+derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
+ const struct sshbuf *shared_secret, u_char **keyp)
+{
+ struct kex *kex = ssh->kex;
+ u_char *key = NULL;
+ int r, key_len;
+
+ EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL);
+ EVP_KDF_CTX *ctx = EVP_KDF_CTX_new(kdf);
+ OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new();
+ OSSL_PARAM *params = NULL;
+ const char *md = digest_to_md(kex->hash_alg);
+ char keytype = (char)id;
+
+ EVP_KDF_free(kdf);
+ if (!ctx) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (md == NULL) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
+ if (param_bld == NULL) {
+ EVP_KDF_CTX_free(ctx);
+ return -1;
+ }
+ if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
+ key_len = ROUNDUP(need, key_len);
+ if ((key = calloc(1, key_len)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ r = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_DIGEST,
+ md, strlen(md)) && /* SN */
+ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_KEY,
+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret)) &&
+ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_SSHKDF_XCGHASH,
+ hash, hashlen) &&
+ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_SSHKDF_SESSION_ID,
+ sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id)) &&
+ OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_SSHKDF_TYPE,
+ &keytype, 1);
+ if (r != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ params = OSSL_PARAM_BLD_to_param(param_bld);
+ if (params == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ r = EVP_KDF_derive(ctx, key, key_len, params);
+ if (r != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+#ifdef DEBUG_KEX
+ fprintf(stderr, "key '%c'== ", id);
+ dump_digest("key", key, key_len);
+#endif
+ *keyp = key;
+ key = NULL;
+ r = 0;
+
+out:
+ OSSL_PARAM_BLD_free(param_bld);
+ OSSL_PARAM_free(params);
+ free (key);
+ EVP_KDF_CTX_free(ctx);
+ if (r < 0) {
+ return r;
+ }
+ return 0;
+}
+#else
static int
derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
const struct sshbuf *shared_secret, u_char **keyp)
@@ -1140,6 +1246,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
ssh_digest_free(hashctx);
return r;
}
+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW */
#define NKEYS 6
int
--
2.52.0

View file

@ -1,8 +1,17 @@
From ed5e5df9ec7ac96ac2a68c5711db00ed29d4d1cd Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 28/53] openssh-8.2p1-visibility
---
regress/misc/sk-dummy/sk-dummy.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c
index dca158de..afdcb1d2 100644
index 4c96e8827..4af5209db 100644
--- a/regress/misc/sk-dummy/sk-dummy.c
+++ b/regress/misc/sk-dummy/sk-dummy.c
@@ -71,7 +71,7 @@ skdebug(const char *func, const char *fmt, ...)
@@ -80,7 +80,7 @@ skdebug(const char *func, const char *fmt, ...)
#endif
}
@ -11,7 +20,7 @@ index dca158de..afdcb1d2 100644
sk_api_version(void)
{
return SSH_SK_VERSION_MAJOR;
@@ -220,7 +220,7 @@ check_options(struct sk_option **options)
@@ -229,7 +229,7 @@ check_options(struct sk_option **options)
return 0;
}
@ -20,7 +29,7 @@ index dca158de..afdcb1d2 100644
sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
const char *application, uint8_t flags, const char *pin,
struct sk_option **options, struct sk_enroll_response **enroll_response)
@@ -467,7 +467,7 @@ sig_ed25519(const uint8_t *message, size_t message_len,
@@ -477,7 +477,7 @@ sig_ed25519(const uint8_t *message, size_t message_len,
return ret;
}
@ -29,7 +38,7 @@ index dca158de..afdcb1d2 100644
sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
const char *application, const uint8_t *key_handle, size_t key_handle_len,
uint8_t flags, const char *pin, struct sk_option **options,
@@ -518,7 +518,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
@@ -534,7 +534,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
return ret;
}
@ -38,3 +47,6 @@ index dca158de..afdcb1d2 100644
sk_load_resident_keys(const char *pin, struct sk_option **options,
struct sk_resident_key ***rks, size_t *nrks)
{
--
2.52.0

View file

@ -1,12 +1,17 @@
From c8dce0615eac6d2a724cdb3f288d7aaa1362f65b Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 29/53] openssh-8.2p1-x11-without-ipv6
---
channels.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/channels.c b/channels.c
index 5ce6bd400..26ed9945f 100644
--- a/channels.c
+++ b/channels.c
@@ -3933,16 +3933,26 @@ x11_create_display_inet(int x11_display_
if (ai->ai_family == AF_INET6)
sock_set_v6only(sock);
if (x11_use_localhost)
set_reuseaddr(sock);
if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
@@ -5123,6 +5123,16 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
debug2_f("bind port %d: %.100s", port,
strerror(errno));
close(sock);
@ -23,8 +28,6 @@ diff --git a/channels.c b/channels.c
for (n = 0; n < num_socks; n++)
close(socks[n]);
num_socks = 0;
break;
}
socks[num_socks++] = sock;
if (num_socks == NUM_SOCKS)
break;
--
2.52.0

View file

@ -1,7 +1,17 @@
diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c
--- openssh-8.0p1/auth-pam.c.preserve-pam-errors 2021-03-31 17:03:15.618592347 +0200
+++ openssh-8.0p1/auth-pam.c 2021-03-31 17:06:58.115220014 +0200
@@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp)
From a3b6182e1d6b69a37a6c841baa43b818251036b1 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 30/53] openssh-8.0p1-preserve-pam-errors
---
auth-pam.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/auth-pam.c b/auth-pam.c
index 70bcae83a..70b2b8580 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -551,7 +551,11 @@ sshpam_thread(void *ctxtp)
goto auth_fail;
if (!do_pam_account()) {
@ -14,9 +24,9 @@ diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c
goto auth_fail;
}
if (sshpam_authctxt->force_pwchange) {
@@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp)
@@ -608,8 +612,10 @@ sshpam_thread(void *ctxtp)
pam_strerror(sshpam_handle, sshpam_err))) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
fatal_fr(r, "buffer error");
/* XXX - can't do much about an error here */
- if (sshpam_err == PAM_ACCT_EXPIRED)
- ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer);
@ -27,18 +37,20 @@ diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c
else if (sshpam_maxtries_reached)
ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer);
else
@@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha
plen++;
@@ -913,9 +919,11 @@ sshpam_query(void *ctx, char **name, char **info,
free(msg);
break;
+ case PAM_USER_UNKNOWN:
+ case PAM_PERM_DENIED:
case PAM_ACCT_EXPIRED:
+ sshpam_account_status = 0;
+ /* FALLTHROUGH */
case PAM_MAXTRIES:
- if (type == PAM_ACCT_EXPIRED)
- sshpam_account_status = 0;
+ case PAM_USER_UNKNOWN:
+ case PAM_PERM_DENIED:
if (type == PAM_MAXTRIES)
sshpam_set_maxtries_reached(1);
/* FALLTHROUGH */
--
2.52.0

View file

@ -1,18 +1,31 @@
diff -up openssh-8.7p1/pathnames.h.kill-scp openssh-8.7p1/pathnames.h
--- openssh-8.7p1/pathnames.h.kill-scp 2021-09-16 11:37:57.240171687 +0200
+++ openssh-8.7p1/pathnames.h 2021-09-16 11:42:29.183427917 +0200
@@ -42,6 +42,7 @@
#define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key"
From ca8b4de1019b859e2c68288a554d1905a6cf029f Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 31/53] openssh-8.7p1-scp-kill-switch
---
pathnames.h | 1 +
scp.1 | 7 +++++++
scp.c | 8 ++++++++
3 files changed, 16 insertions(+)
diff --git a/pathnames.h b/pathnames.h
index 0dcc49552..78bba2314 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -40,6 +40,7 @@
#define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key"
#define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key"
#define _PATH_DH_MODULI SSHDIR "/moduli"
+#define _PATH_SCP_KILL_SWITCH SSHDIR "/disable_scp"
#ifndef _PATH_SSH_PROGRAM
#define _PATH_SSH_PROGRAM "/usr/bin/ssh"
diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1
--- openssh-8.7p1/scp.1.kill-scp 2021-09-16 12:09:02.646714578 +0200
+++ openssh-8.7p1/scp.1 2021-09-16 12:26:49.978628226 +0200
@@ -278,6 +278,13 @@ to print debugging messages about their
diff --git a/scp.1 b/scp.1
index 7bce0fe6f..2bb838c7d 100644
--- a/scp.1
+++ b/scp.1
@@ -334,6 +334,13 @@ during download or upload.
By default a 32KB buffer is used.
.El
.El
@ -26,10 +39,11 @@ diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1
.Sh EXIT STATUS
.Ex -std scp
.Sh SEE ALSO
diff -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c
--- openssh-8.7p1/scp.c.kill-scp 2021-09-16 11:42:56.013650519 +0200
+++ openssh-8.7p1/scp.c 2021-09-16 11:53:03.249713836 +0200
@@ -596,6 +596,14 @@ main(int argc, char **argv)
diff --git a/scp.c b/scp.c
index 621131ffc..3c213f83d 100644
--- a/scp.c
+++ b/scp.c
@@ -633,6 +633,14 @@ main(int argc, char **argv)
if (iamremote)
mode = MODE_SCP;
@ -44,3 +58,6 @@ diff -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c
if ((pwd = getpwuid(userid = getuid())) == NULL)
fatal("unknown user %u", (u_int) userid);
--
2.52.0

View file

@ -0,0 +1,200 @@
From e6478b233cd2298c9e6e6128867421892ff8f0e4 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 32/53] openssh-8.7p1-recursive-scp
---
scp.c | 2 +-
sftp-client.c | 60 +++++++++++++++++++++++++++++++++++++++------------
sftp-client.h | 4 ++--
sftp.c | 6 +++---
4 files changed, 52 insertions(+), 20 deletions(-)
diff --git a/scp.c b/scp.c
index 3c213f83d..78c79a755 100644
--- a/scp.c
+++ b/scp.c
@@ -1378,7 +1378,7 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
if (src_is_dir && iamrecursive) {
if (sftp_upload_dir(conn, src, abs_dst, pflag,
- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) {
error("failed to upload directory %s to %s", src, targ);
errs = 1;
}
diff --git a/sftp-client.c b/sftp-client.c
index 840170ab6..9bf9cc047 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1001,7 +1001,7 @@ sftp_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
/* Implements both the realpath and expand-path operations */
static char *
-sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
+sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir)
{
struct sshbuf *msg;
u_int expected_id, count, id;
@@ -1047,11 +1047,43 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
fatal_fr(r, "parse status");
- error("%s %s: %s", expand ? "expand" : "realpath",
- path, *errmsg == '\0' ? fx2txt(status) : errmsg);
- free(errmsg);
- sshbuf_free(msg);
- return NULL;
+ if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) {
+ memset(&a, '\0', sizeof(a));
+ if ((r = sftp_mkdir(conn, path, &a, 0)) != 0) {
+ sshbuf_free(msg);
+ return NULL;
+ }
+ debug2("Sending SSH2_FXP_REALPATH \"%s\" - create dir", path);
+ send_string_request(conn, id, SSH2_FXP_REALPATH,
+ path, strlen(path));
+
+ get_msg(conn, msg);
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+ (r = sshbuf_get_u32(msg, &id)) != 0)
+ fatal_fr(r, "parse");
+
+ if (id != expected_id)
+ fatal("ID mismatch (%u != %u)", id, expected_id);
+
+ if (type == SSH2_FXP_STATUS) {
+ free(errmsg);
+
+ if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
+ (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
+ fatal_fr(r, "parse status");
+ error("%s %s: %s", expand ? "expand" : "realpath",
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+ free(errmsg);
+ sshbuf_free(msg);
+ return NULL;
+ }
+ } else {
+ error("%s %s: %s", expand ? "expand" : "realpath",
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+ free(errmsg);
+ sshbuf_free(msg);
+ return NULL;
+ }
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
@@ -1076,9 +1108,9 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
}
char *
-sftp_realpath(struct sftp_conn *conn, const char *path)
+sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir)
{
- return sftp_realpath_expand(conn, path, 0);
+ return sftp_realpath_expand(conn, path, 0, create_dir);
}
int
@@ -1092,9 +1124,9 @@ sftp_expand_path(struct sftp_conn *conn, const char *path)
{
if (!sftp_can_expand_path(conn)) {
debug3_f("no server support, fallback to realpath");
- return sftp_realpath_expand(conn, path, 0);
+ return sftp_realpath_expand(conn, path, 0, 0);
}
- return sftp_realpath_expand(conn, path, 1);
+ return sftp_realpath_expand(conn, path, 1, 0);
}
int
@@ -2014,7 +2046,7 @@ sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst,
char *src_canon;
int ret;
- if ((src_canon = sftp_realpath(conn, src)) == NULL) {
+ if ((src_canon = sftp_realpath(conn, src, 0)) == NULL) {
error("download \"%s\": path canonicalization failed", src);
return -1;
}
@@ -2366,12 +2398,12 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int
sftp_upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
int preserve_flag, int print_flag, int resume, int fsync_flag,
- int follow_link_flag, int inplace_flag)
+ int follow_link_flag, int inplace_flag, int create_dir)
{
char *dst_canon;
int ret;
- if ((dst_canon = sftp_realpath(conn, dst)) == NULL) {
+ if ((dst_canon = sftp_realpath(conn, dst, create_dir)) == NULL) {
error("upload \"%s\": path canonicalization failed", dst);
return -1;
}
@@ -2826,7 +2858,7 @@ sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
char *from_path_canon;
int ret;
- if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) {
+ if ((from_path_canon = sftp_realpath(from, from_path, 0)) == NULL) {
error("crossload \"%s\": path canonicalization failed",
from_path);
return -1;
diff --git a/sftp-client.h b/sftp-client.h
index 873ad3849..fe58651c1 100644
--- a/sftp-client.h
+++ b/sftp-client.h
@@ -112,7 +112,7 @@ int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
/* Canonicalise 'path' - caller must free result */
-char *sftp_realpath(struct sftp_conn *, const char *);
+char *sftp_realpath(struct sftp_conn *, const char *, int);
/* Canonicalisation with tilde expansion (requires server extension) */
char *sftp_expand_path(struct sftp_conn *, const char *);
@@ -164,7 +164,7 @@ int sftp_upload(struct sftp_conn *, const char *, const char *,
* times if 'pflag' is set
*/
int sftp_upload_dir(struct sftp_conn *, const char *, const char *,
- int, int, int, int, int, int);
+ int, int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to
diff --git a/sftp.c b/sftp.c
index 3b505eea2..2a99698a8 100644
--- a/sftp.c
+++ b/sftp.c
@@ -801,7 +801,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
(rflag || global_rflag)) {
if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
- fflag || global_fflag, 0, 0) == -1)
+ fflag || global_fflag, 0, 0, 0) == -1)
err = -1;
} else {
if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
@@ -1636,7 +1636,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
path1 = sftp_make_absolute(path1, *pwd);
- if ((tmp = sftp_realpath(conn, path1)) == NULL) {
+ if ((tmp = sftp_realpath(conn, path1, 0)) == NULL) {
err = 1;
break;
}
@@ -2241,7 +2241,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
}
#endif /* USE_LIBEDIT */
- if ((remote_path = sftp_realpath(conn, ".")) == NULL)
+ if ((remote_path = sftp_realpath(conn, ".", 0)) == NULL)
fatal("Need cwd");
startdir = xstrdup(remote_path);
--
2.52.0

View file

@ -0,0 +1,37 @@
From 14f25e21b4e2c5e625f266fcc9af42c2f89845de Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 33/53] openssh-8.7p1-minrsabits
---
readconf.c | 1 +
servconf.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/readconf.c b/readconf.c
index eab734aaf..3f67f4de4 100644
--- a/readconf.c
+++ b/readconf.c
@@ -337,6 +337,7 @@ static struct {
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
{ "requiredrsasize", oRequiredRSASize },
+ { "rsaminsize", oRequiredRSASize }, /* alias */
{ "enableescapecommandline", oEnableEscapeCommandline },
{ "obscurekeystroketiming", oObscureKeystrokeTiming },
{ "channeltimeout", oChannelTimeout },
diff --git a/servconf.c b/servconf.c
index b63a7f0b0..ac84b74d9 100644
--- a/servconf.c
+++ b/servconf.c
@@ -778,6 +778,7 @@ static struct {
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
+ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */
{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },
{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
{ "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL },
--
2.52.0

View file

@ -0,0 +1,25 @@
From e2c0fb233119584b04d61d243cd58433072559c2 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 34/53] openssh-8.7p1-ibmca
---
openbsd-compat/bsd-closefrom.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c
index f61124585..417c20484 100644
--- a/openbsd-compat/bsd-closefrom.c
+++ b/openbsd-compat/bsd-closefrom.c
@@ -16,7 +16,7 @@
#include "includes.h"
-#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM)
+#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__)
#include <sys/types.h>
#include <unistd.h>
--
2.52.0

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,19 @@
diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c
--- openssh-7.4p1/monitor_wrap.c.audit-race 2016-12-23 16:35:52.694685771 +0100
+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:35:52.697685772 +0100
@@ -1107,4 +1107,50 @@ mm_audit_destroy_sensitive_data(const ch
From ffa3fdb2ad2c7afc91993d9301e35d2e9a83ea47 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 36/53] openssh-7.1p2-audit-race-condition
---
monitor_wrap.c | 46 +++++++++++++++++++++++++++++++++++++
monitor_wrap.h | 2 ++
session.c | 61 ++++++++++++++++++++++++++++++++++++++++++++------
3 files changed, 102 insertions(+), 7 deletions(-)
diff --git a/monitor_wrap.c b/monitor_wrap.c
index fb44ae733..17a6c9786 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1426,4 +1426,50 @@ mm_audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m);
sshbuf_free(m);
}
@ -52,10 +64,11 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c
+ pmonitor->m_recvfd = fd;
+}
#endif /* SSH_AUDIT_EVENTS */
diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h
--- openssh-7.4p1/monitor_wrap.h.audit-race 2016-12-23 16:35:52.694685771 +0100
+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 16:35:52.698685772 +0100
@@ -83,6 +83,8 @@ void mm_audit_unsupported_body(int);
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 1bcbfd305..2b814dbd1 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -97,6 +97,8 @@ void mm_audit_unsupported_body(struct ssh *, int);
void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t);
void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t);
void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t);
@ -64,10 +77,11 @@ diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h
#endif
struct Session;
diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
--- openssh-7.4p1/session.c.audit-race 2016-12-23 16:35:52.695685771 +0100
+++ openssh-7.4p1/session.c 2016-12-23 16:37:26.339730596 +0100
@@ -162,6 +162,10 @@ static Session *sessions = NULL;
diff --git a/session.c b/session.c
index 107edcf91..80282dfd8 100644
--- a/session.c
+++ b/session.c
@@ -161,6 +161,10 @@ static Session *sessions = NULL;
login_cap_t *lc;
#endif
@ -78,7 +92,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
static int is_child = 0;
static int in_chroot = 0;
static int have_dev_log = 1;
@@ -289,6 +293,8 @@ xauth_valid_string(const char *s)
@@ -358,6 +362,8 @@ xauth_valid_string(const char *s)
return 1;
}
@ -87,7 +101,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
#define USE_PIPES 1
/*
* This is called to fork and execute a command when we have no tty. This
@@ -424,6 +430,8 @@ do_exec_no_pty(Session *s, const char *c
@@ -481,6 +487,8 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
close(err[0]);
#endif
@ -96,7 +110,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
/* Do processing for the child (exec command etc). */
do_child(ssh, s, command);
/* NOTREACHED */
@@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm
@@ -595,6 +603,9 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
/* Close the extra descriptor for the pseudo tty. */
close(ttyfd);
@ -106,22 +120,22 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
/* record login, etc. similar to login(1) */
#ifndef HAVE_OSF_SIA
do_login(ssh, s, command);
@@ -717,6 +728,8 @@ do_exec(Session *s, const char *command)
@@ -729,6 +740,8 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
}
if (s->command != NULL && s->ptyfd == -1)
s->command_handle = PRIVSEP(audit_run_command(ssh, s->command));
s->command_handle = mm_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);
@@ -732,6 +745,20 @@ do_exec(Session *s, const char *command)
@@ -744,6 +757,20 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
*/
sshbuf_reset(loginmsg);
+#ifdef SSH_AUDIT_EVENTS
+ close(paudit[1]);
+ if (use_privsep && ret == 0) {
+ if (ret == 0) {
+ /*
+ * Read the audit messages from forked child and send them
+ * back to monitor. We don't want to communicate directly,
@ -136,7 +150,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
return ret;
}
@@ -1538,6 +1565,34 @@ child_close_fds(void)
@@ -1490,6 +1517,33 @@ child_close_fds(struct ssh *ssh)
log_redirect_stderr_to(NULL);
}
@ -147,12 +161,11 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
+ 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);
+ mm_set_monitor_pipe(pparent);
+#endif
+
+ /* remove hostkey from the child's memory */
+ destroy_sensitive_data(ssh, use_privsep);
+ /* FIXME beldmit destroy_sensitive_data(ssh); */
+ /*
+ * We can audit this, because we hacked the pipe to direct the
+ * messages over postauth child. But this message requires answer
@ -171,12 +184,12 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
/*
* Performs common processing for the child, such as setting up the
* environment, closing extra file descriptors, setting the user and group
@@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command
@@ -1507,13 +1561,6 @@ do_child(struct ssh *ssh, Session *s, const char *command)
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
- /* remove hostkey from the child's memory */
- destroy_sensitive_data(ssh, 1);
- /* remove keys from memory */
- 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. */
@ -185,3 +198,6 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
/* Force a password change */
if (s->authctxt->force_pwchange) {
do_setusercontext(pw);
--
2.52.0

View file

@ -0,0 +1,265 @@
From ef05b1fceddc64cfc7eb40daac60a137634d0a9f Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 37/53] openssh-9.0p1-audit-log
---
audit-bsm.c | 2 +-
audit-linux.c | 76 +++++++++++++++++++++++++++++++++++++++++++--------
audit.c | 18 +++++++++---
audit.h | 2 +-
4 files changed, 81 insertions(+), 17 deletions(-)
diff --git a/audit-bsm.c b/audit-bsm.c
index a6292cb8f..0f2ef8235 100644
--- a/audit-bsm.c
+++ b/audit-bsm.c
@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li)
}
int
-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv)
+audit_keyusage(struct ssh *ssh, int host_user, char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv)
{
/* not implemented */
}
diff --git a/audit-linux.c b/audit-linux.c
index 4d3e9d41e..d2bc0b526 100644
--- a/audit-linux.c
+++ b/audit-linux.c
@@ -52,7 +52,7 @@ extern u_int utmp_len;
const char *audit_username(void);
static void
-linux_audit_user_logxxx(int uid, const char *username,
+linux_audit_user_logxxx(int uid, const char *username, const char *hostname,
const char *ip, const char *ttyn, int success, int event)
{
int audit_fd, rc, saved_errno;
@@ -68,7 +68,7 @@ linux_audit_user_logxxx(int uid, const char *username,
hostname = NULL;
rc = audit_log_acct_message(audit_fd, event,
NULL, "login", username ? username : "(unknown)",
- username == NULL ? uid : -1, NULL, ip, ttyn, success);
+ username == NULL ? uid : -1, hostname, ip, ttyn, success);
saved_errno = errno;
close(audit_fd);
@@ -139,10 +139,12 @@ fatal_report:
}
int
-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv)
+audit_keyusage(struct ssh *ssh, int host_user, const char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv)
{
char buf[AUDIT_LOG_SIZE];
int audit_fd, rc, saved_errno;
+ const char *rip;
+ u_int i;
audit_fd = audit_open();
if (audit_fd < 0) {
@@ -152,14 +154,44 @@ audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv)
else
return 0; /* Must prevent login */
}
+ rip = ssh_remote_ipaddr(ssh);
snprintf(buf, sizeof(buf), "%s_auth grantors=auth-key", host_user ? "pubkey" : "hostbased");
rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
- buf, audit_username(), -1, NULL, ssh_remote_ipaddr(ssh), NULL, rv);
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
goto out;
- snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", fp);
+ snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", key_fp);
rc = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, buf, NULL,
- ssh_remote_ipaddr(ssh), NULL, rv);
+ rip, NULL, rv);
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
+ goto out;
+
+ if (cert) {
+ char *pbuf;
+
+ pbuf = audit_encode_nv_string("key_id", cert->key_id, 0);
+ if (pbuf == NULL)
+ goto out;
+ snprintf(buf, sizeof(buf), "cert %s cert_serial=%llu cert_issuer_alg=\"%s\" cert_issuer_fp=\"%s\"",
+ pbuf, (unsigned long long)cert->serial, sshkey_type(cert->signature_key), issuer_fp);
+ free(pbuf);
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
+ goto out;
+
+ for (i = 0; cert->principals != NULL && i < cert->nprincipals; i++) {
+ pbuf = audit_encode_nv_string("cert_principal", cert->principals[i], 0);
+ if (pbuf == NULL)
+ goto out;
+ snprintf(buf, sizeof(buf), "principal %s", pbuf);
+ free(pbuf);
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
+ goto out;
+ }
+ }
out:
saved_errno = errno;
audit_close(audit_fd);
@@ -181,26 +213,34 @@ audit_connection_from(const char *host, int port)
int
audit_run_command(struct ssh *ssh, const char *command)
{
+ char * audit_hostname = options.use_dns ? remote_hostname(ssh) : NULL;
if (!user_login_count++)
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
+ audit_hostname,
ssh_remote_ipaddr(ssh),
"ssh", 1, AUDIT_USER_LOGIN);
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
+ audit_hostname,
ssh_remote_ipaddr(ssh),
"ssh", 1, AUDIT_USER_START);
+ free(audit_hostname);
return 0;
}
void
audit_end_command(struct ssh *ssh, int handle, const char *command)
{
+ char * audit_hostname = options.use_dns ? remote_hostname(ssh) : NULL;
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
+ audit_hostname,
ssh_remote_ipaddr(ssh),
"ssh", 1, AUDIT_USER_END);
if (user_login_count && !--user_login_count)
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
+ audit_hostname,
ssh_remote_ipaddr(ssh),
"ssh", 1, AUDIT_USER_LOGOUT);
+ free(audit_hostname);
}
void
@@ -213,31 +253,41 @@ void
audit_session_open(struct logininfo *li)
{
if (!user_login_count++)
- linux_audit_user_logxxx(li->uid, NULL, li->hostname,
+ linux_audit_user_logxxx(li->uid, NULL,
+ options.use_dns ? li->hostname : NULL,
+ options.use_dns ? NULL : li->hostname,
li->line, 1, AUDIT_USER_LOGIN);
- linux_audit_user_logxxx(li->uid, NULL, li->hostname,
+ linux_audit_user_logxxx(li->uid, NULL,
+ options.use_dns ? li->hostname : NULL,
+ options.use_dns ? NULL : li->hostname,
li->line, 1, AUDIT_USER_START);
}
void
audit_session_close(struct logininfo *li)
{
- linux_audit_user_logxxx(li->uid, NULL, li->hostname,
+ linux_audit_user_logxxx(li->uid, NULL,
+ options.use_dns ? li->hostname : NULL,
+ options.use_dns ? NULL : li->hostname,
li->line, 1, AUDIT_USER_END);
if (user_login_count && !--user_login_count)
- linux_audit_user_logxxx(li->uid, NULL, li->hostname,
+ linux_audit_user_logxxx(li->uid, NULL,
+ options.use_dns ? li->hostname : NULL,
+ options.use_dns ? NULL : li->hostname,
li->line, 1, AUDIT_USER_LOGOUT);
}
void
audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
+ char * audit_hostname = options.use_dns ? remote_hostname(ssh) : NULL;
+
switch(event) {
case SSH_NOLOGIN:
case SSH_LOGIN_ROOT_DENIED:
linux_audit_user_auth(-1, audit_username(),
ssh_remote_ipaddr(ssh), "ssh", 0, event);
- linux_audit_user_logxxx(-1, audit_username(),
+ linux_audit_user_logxxx(-1, audit_username(), audit_hostname,
ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN);
break;
case SSH_AUTH_FAIL_PASSWD:
@@ -257,9 +307,11 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event)
if (user_login_count) {
while (user_login_count--)
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
+ audit_hostname,
ssh_remote_ipaddr(ssh),
"ssh", 1, AUDIT_USER_END);
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
+ audit_hostname,
ssh_remote_ipaddr(ssh),
"ssh", 1, AUDIT_USER_LOGOUT);
}
@@ -268,12 +320,14 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event)
case SSH_CONNECTION_ABANDON:
case SSH_INVALID_USER:
linux_audit_user_logxxx(-1, audit_username(),
+ audit_hostname,
ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN);
break;
default:
debug_f("unhandled event %d", event);
break;
}
+ free(audit_hostname);
}
void
diff --git a/audit.c b/audit.c
index d0433c3a0..28d51a146 100644
--- a/audit.c
+++ b/audit.c
@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev)
void
audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key)
{
- char *fp;
+ char *key_fp = NULL;
+ char *issuer_fp = NULL;
+ struct sshkey_cert *cert = NULL;
- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0)
+ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
+ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) {
+ cert = key->cert;
+ issuer_fp = sshkey_fingerprint(cert->signature_key,
+ options.fingerprint_hash, SSH_FP_DEFAULT);
+ }
+ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0)
*rv = -SSH_ERR_INTERNAL_ERROR;
- free(fp);
+ if (key_fp)
+ free(key_fp);
+ if (issuer_fp)
+ free(issuer_fp);
}
void
diff --git a/audit.h b/audit.h
index 45d66ccff..05ac132cf 100644
--- a/audit.h
+++ b/audit.h
@@ -64,7 +64,7 @@ void audit_session_close(struct logininfo *);
int audit_run_command(struct ssh *, const char *);
void audit_end_command(struct ssh *, int, const char *);
ssh_audit_event_t audit_classify_auth(const char *);
-int audit_keyusage(struct ssh *, int, char *, int);
+int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int);
void audit_key(struct ssh *, int, int *, const struct sshkey *);
void audit_unsupported(struct ssh *, int);
void audit_kex(struct ssh *, int, char *, char *, char *, char *);
--
2.52.0

View file

@ -1,6 +1,33 @@
diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
--- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/dh.c 2021-05-06 12:12:10.107634472 +0200
From d7dd45f9e19a71269828bc5f8567613a02f6feef Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 28 Aug 2025 14:01:38 +0200
Subject: [PATCH 38/53] openssh-7.7p1-fips
---
dh.c | 41 ++++++++++++++++++++++
dh.h | 1 +
kex-names.c | 6 +++-
kex.c | 3 +-
kexgen.c | 74 ++++++++++++++++++++++++++++++++--------
kexgexc.c | 5 +++
myproposal.h | 33 ++++++++++++++++++
readconf.c | 16 ++++++---
sandbox-seccomp-filter.c | 3 ++
servconf.c | 18 +++++++---
ssh-ed25519.c | 9 +++++
ssh-gss.h | 5 +++
ssh-keygen.c | 20 +++++++++--
ssh-rsa.c | 3 ++
ssh.c | 5 +++
sshconnect2.c | 9 ++++-
sshd.c | 13 +++++++
sshkey.c | 37 ++++++++++++++++++++
18 files changed, 271 insertions(+), 30 deletions(-)
diff --git a/dh.c b/dh.c
index 168dea1dd..8c9a29fa7 100644
--- a/dh.c
+++ b/dh.c
@@ -36,6 +36,7 @@
#include <openssl/bn.h>
@ -9,7 +36,7 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
#include "dh.h"
#include "pathnames.h"
@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max
@@ -164,6 +165,12 @@ choose_dh(int min, int wantbits, int max)
int best, bestcount, which, linenum;
struct dhgroup dhg;
@ -22,7 +49,7 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
if ((f = fopen(get_moduli_filename(), "r")) == NULL) {
logit("WARNING: could not open %s (%s), using fixed modulus",
get_moduli_filename(), strerror(errno));
@@ -502,4 +508,38 @@ dh_estimate(int bits)
@@ -502,4 +509,38 @@ dh_estimate(int bits)
return 8192;
}
@ -61,9 +88,10 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
+}
+
#endif /* WITH_OPENSSL */
diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h
--- openssh-8.6p1/dh.h.fips 2021-05-06 12:08:36.498926877 +0200
+++ openssh-8.6p1/dh.h 2021-05-06 12:11:28.393298005 +0200
diff --git a/dh.h b/dh.h
index c6326a39d..e51e292b8 100644
--- a/dh.h
+++ b/dh.h
@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);
@ -72,18 +100,19 @@ diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h
u_int dh_estimate(int);
void dh_set_moduli_file(const char *);
diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c
--- openssh-8.6p1/kex.c.fips 2021-05-06 12:08:36.489926807 +0200
+++ openssh-8.6p1/kex.c 2021-05-06 12:08:36.498926877 +0200
@@ -39,6 +39,7 @@
diff --git a/kex-names.c b/kex-names.c
index 31e395aa2..1360a4095 100644
--- a/kex-names.c
+++ b/kex-names.c
@@ -33,6 +33,7 @@
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
+#include <openssl/fips.h>
#include <openssl/dh.h>
# ifdef HAVE_EVP_KDF_CTX_NEW_ID
# include <openssl/kdf.h>
@@ -203,7 +203,10 @@ kex_names_valid(const char *names)
#include <openssl/evp.h>
#endif
@@ -208,7 +209,10 @@ kex_names_valid(const char *names)
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (kex_alg_by_name(p) == NULL) {
@ -95,9 +124,149 @@ diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c
free(s);
return 0;
}
diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
--- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/kexgexc.c 2021-05-06 12:08:36.498926877 +0200
diff --git a/kex.c b/kex.c
index 44f350ce8..da2a537ce 100644
--- a/kex.c
+++ b/kex.c
@@ -38,6 +38,7 @@
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
#include <openssl/dh.h>
+#include <openssl/fips.h>
# ifdef HAVE_EVP_KDF_CTX_NEW
# include <openssl/kdf.h>
# include <openssl/param_build.h>
@@ -107,7 +108,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX],
/* Append EXT_INFO signalling to KexAlgorithms */
if (kexalgos == NULL)
- kexalgos = defprop[PROPOSAL_KEX_ALGS];
+ kexalgos = FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : defprop[PROPOSAL_KEX_ALGS];
if ((cp = kex_names_cat(kexalgos, ssh->kex->server ?
"ext-info-s,kex-strict-s-v00@openssh.com" :
"ext-info-c,kex-strict-c-v00@openssh.com")) == NULL)
diff --git a/kexgen.c b/kexgen.c
index 58edc79ad..9a970adf1 100644
--- a/kexgen.c
+++ b/kexgen.c
@@ -31,6 +31,7 @@
#include <stdio.h>
#include <string.h>
#include <signal.h>
+#include <openssl/fips.h>
#include "sshkey.h"
#include "kex.h"
@@ -115,13 +116,28 @@ kex_gen_client(struct ssh *ssh)
break;
#endif /* WITH_OPENSSL */
case KEX_C25519_SHA256:
- r = kex_c25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_keypair(kex);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_keypair(kex);
+ }
break;
case KEX_KEM_MLKEM768X25519_SHA256:
- r = kex_kem_mlkem768x25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_mlkem768x25519_keypair(kex);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -189,15 +205,30 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
break;
#endif /* WITH_OPENSSL */
case KEX_C25519_SHA256:
- r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_dec(kex, server_blob,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_dec(kex, server_blob,
+ &shared_secret);
+ }
break;
case KEX_KEM_MLKEM768X25519_SHA256:
- r = kex_kem_mlkem768x25519_dec(kex, server_blob,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_mlkem768x25519_dec(kex, server_blob,
+ &shared_secret);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -312,16 +343,31 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
break;
#endif /* WITH_OPENSSL */
case KEX_C25519_SHA256:
- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
+ &shared_secret);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
- &server_pubkey, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
+ &server_pubkey, &shared_secret);
+ }
break;
case KEX_KEM_MLKEM768X25519_SHA256:
- r = kex_kem_mlkem768x25519_enc(kex, client_pubkey,
- &server_pubkey, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_mlkem768x25519_enc(kex, client_pubkey,
+ &server_pubkey, &shared_secret);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
diff --git a/kexgexc.c b/kexgexc.c
index 097d83f30..ccbb9b580 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -28,6 +28,7 @@
#ifdef WITH_OPENSSL
@ -105,8 +274,8 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
+#include <openssl/fips.h>
#include <sys/types.h>
#include <openssl/dh.h>
@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32
#include "openbsd-compat/openssl-compat.h"
@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@ -117,10 +286,11 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
p = g = NULL; /* belong to kex->dh now */
/* generate and send 'e', client DH public key */
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
@@ -57,6 +57,18 @@
diff --git a/myproposal.h b/myproposal.h
index 8fe9276c2..3e0ec6826 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -58,6 +58,18 @@
"rsa-sha2-512," \
"rsa-sha2-256"
@ -138,8 +308,8 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
+
#define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \
"aes128-ctr,aes192-ctr,aes256-ctr," \
@@ -78,6 +92,27 @@
"aes128-gcm@openssh.com,aes256-gcm@openssh.com," \
@@ -79,6 +91,27 @@
#define KEX_CLIENT_MAC KEX_SERVER_MAC
@ -167,9 +337,10 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
/* Not a KEX value, but here so all the algorithm defaults are together */
#define SSH_ALLOWED_CA_SIGALGS \
"ssh-ed25519," \
diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c
--- openssh-8.6p1/readconf.c.fips 2021-05-06 12:08:36.428926336 +0200
+++ openssh-8.6p1/readconf.c 2021-05-06 12:08:36.499926885 +0200
diff --git a/readconf.c b/readconf.c
index 3f67f4de4..b6ad47b49 100644
--- a/readconf.c
+++ b/readconf.c
@@ -39,6 +39,7 @@
#include <string.h>
#include <stdarg.h>
@ -178,7 +349,7 @@ diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
@@ -2538,11 +2538,16 @@ fill_default_options(Options * options)
@@ -3078,11 +3079,16 @@ fill_default_options(Options * options)
all_key = sshkey_alg_list(0, 0, 1, ',');
all_sig = sshkey_alg_list(0, 1, 1, ',');
/* remove unsupported algos from default lists */
@ -200,10 +371,11 @@ diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&options->what, \
diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c
--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-05-06 12:08:36.463926606 +0200
+++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-06 12:08:36.499926885 +0200
@@ -160,6 +160,9 @@ static const struct sock_filter preauth_
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index e0f2d4289..c52f64897 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -258,6 +258,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_open
SC_DENY(__NR_open, EACCES),
#endif
@ -213,18 +385,22 @@ diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-secco
#ifdef __NR_openat
SC_DENY(__NR_openat, EACCES),
#endif
diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c
--- openssh-8.6p1/servconf.c.fips 2021-05-06 12:08:36.455926545 +0200
+++ openssh-8.6p1/servconf.c 2021-05-06 12:08:36.500926893 +0200
@@ -38,6 +38,7 @@
diff --git a/servconf.c b/servconf.c
index ac84b74d9..f78615c28 100644
--- a/servconf.c
+++ b/servconf.c
@@ -37,7 +37,10 @@
#include <limits.h>
#include <stdarg.h>
#include <errno.h>
+#include <openssl/fips.h>
#ifdef HAVE_UTIL_H
+#ifdef HAVE_UTIL_H
#include <util.h>
#endif
@@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o)
+#endif
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
@@ -244,11 +247,16 @@ assemble_algorithms(ServerOptions *o)
all_key = sshkey_alg_list(0, 0, 1, ',');
all_sig = sshkey_alg_list(0, 1, 1, ',');
/* remove unsupported algos from default lists */
@ -246,10 +422,150 @@ diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c
--- openssh-8.6p1/ssh.c.fips 2021-05-06 12:08:36.467926637 +0200
+++ openssh-8.6p1/ssh.c 2021-05-06 12:08:36.500926893 +0200
@@ -77,6 +77,7 @@
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index c8caa2221..4bcd9ef81 100644
--- a/ssh-ed25519.c
+++ b/ssh-ed25519.c
@@ -24,6 +24,7 @@
#include <string.h>
#include <stdarg.h>
+#include <openssl/fips.h>
#include "log.h"
#include "sshbuf.h"
@@ -163,6 +164,10 @@ ssh_ed25519_sign(struct sshkey *key,
key->ed25519_sk == NULL ||
datalen >= INT_MAX - crypto_sign_ed25519_BYTES)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
smlen = slen = datalen + crypto_sign_ed25519_BYTES;
if ((sig = malloc(slen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
@@ -244,6 +249,10 @@ ssh_ed25519_verify(const struct sshkey *key,
dlen >= INT_MAX - crypto_sign_ed25519_BYTES ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
diff --git a/ssh-gss.h b/ssh-gss.h
index a894e23c9..329dc9da0 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -88,6 +88,11 @@ extern char **k5users_allowed_cmds;
KEX_GSS_GRP14_SHA1_ID "," \
KEX_GSS_GEX_SHA1_ID
+#define GSS_KEX_DEFAULT_KEX_FIPS \
+ KEX_GSS_GRP14_SHA256_ID "," \
+ KEX_GSS_GRP16_SHA512_ID "," \
+ KEX_GSS_NISTP256_SHA256_ID
+
#include "digest.h" /* SSH_DIGEST_MAX_LENGTH */
typedef struct {
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 3c582a83a..afa279097 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -22,6 +22,7 @@
#include "openbsd-compat/openssl-compat.h"
#include <openssl/bn.h>
#include <openssl/evp.h>
+#include <openssl/fips.h>
#include <openssl/pem.h>
#endif
@@ -68,6 +69,7 @@
#endif
#define DEFAULT_KEY_TYPE_NAME "ed25519"
+#define FIPS_DEFAULT_KEY_TYPE_NAME "rsa"
/*
* Default number of bits in the RSA and ECDSA keys. These value can be
@@ -195,6 +197,10 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
#endif
}
#ifdef WITH_OPENSSL
+ if (FIPS_mode()) {
+ if (type == KEY_ED25519 || type == KEY_ED25519_SK)
+ fatal("ED25519 keys are not allowed in FIPS mode");
+ }
switch (type) {
case KEY_RSA:
if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE)
@@ -248,7 +254,7 @@ ask_filename(struct passwd *pw, const char *prompt)
char *name = NULL;
if (key_type_name == NULL)
- name = _PATH_SSH_CLIENT_ID_ED25519;
+ name = FIPS_mode() ? _PATH_SSH_CLIENT_ID_RSA : _PATH_SSH_CLIENT_ID_ED25519;
else {
switch (sshkey_type_from_shortname(key_type_name)) {
#ifdef OPENSSL_HAS_ECC
@@ -1057,9 +1063,17 @@ do_gen_all_hostkeys(struct passwd *pw)
first = 1;
printf("%s: generating new host keys: ", __progname);
}
+ type = sshkey_type_from_shortname(key_types[i].key_type);
+
+ /* Skip the keys that are not supported in FIPS mode */
+ if (FIPS_mode() && type == KEY_ED25519) {
+ logit("Skipping %s key in FIPS mode",
+ key_types[i].key_type_display);
+ goto next;
+ }
+
printf("%s ", key_types[i].key_type_display);
fflush(stdout);
- type = sshkey_type_from_shortname(key_types[i].key_type);
if ((fd = mkstemp(prv_tmp)) == -1) {
error("Could not save your private key in %s: %s",
prv_tmp, strerror(errno));
@@ -3757,7 +3771,7 @@ main(int argc, char **argv)
}
if (key_type_name == NULL)
- key_type_name = DEFAULT_KEY_TYPE_NAME;
+ key_type_name = FIPS_mode() ? FIPS_DEFAULT_KEY_TYPE_NAME : DEFAULT_KEY_TYPE_NAME;
type = sshkey_type_from_shortname(key_type_name);
type_bits_valid(type, key_type_name, &bits);
diff --git a/ssh-rsa.c b/ssh-rsa.c
index fe1518984..9428df8d1 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -25,6 +25,7 @@
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/err.h>
+#include <openssl/fips.h>
#include <stdarg.h>
#include <string.h>
@@ -142,6 +143,8 @@ ssh_rsa_generate(struct sshkey *k, int bits)
goto out;
}
if (EVP_PKEY_keygen(ctx, &res) <= 0 || res == NULL) {
+ if (FIPS_mode())
+ logit_f("the key length might be unsupported by FIPS mode approved key generation method");
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
diff --git a/ssh.c b/ssh.c
index 8d27f6379..7d6ba516e 100644
--- a/ssh.c
+++ b/ssh.c
@@ -74,6 +74,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#endif
@ -257,7 +573,7 @@ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c
#include "openbsd-compat/openssl-compat.h"
#include "openbsd-compat/sys-queue.h"
@@ -1516,6 +1517,10 @@ main(int ac, char **av)
@@ -1664,6 +1665,10 @@ main(int ac, char **av)
exit(0);
}
@ -268,9 +584,10 @@ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c
/* Expand SecurityKeyProvider if it refers to an environment variable */
if (options.sk_provider != NULL && *options.sk_provider == '$' &&
strlen(options.sk_provider) > 1) {
diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c
--- openssh-8.6p1/sshconnect2.c.fips 2021-05-06 12:08:36.485926777 +0200
+++ openssh-8.6p1/sshconnect2.c 2021-05-06 12:08:36.501926900 +0200
diff --git a/sshconnect2.c b/sshconnect2.c
index b253f991b..fffa66c8d 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -45,6 +45,8 @@
#include <vis.h>
#endif
@ -280,95 +597,48 @@ diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
@@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st
@@ -262,6 +264,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {
- /* Add the GSSAPI mechanisms currently supported on this
- * client to the key exchange algorithm proposal */
- orig = myproposal[PROPOSAL_KEX_ALGS];
-
- if (options.gss_server_identity) {
- gss_host = xstrdup(options.gss_server_identity);
- } else if (options.gss_trust_dns) {
- gss_host = remote_hostname(ssh);
- /* Fall back to specified host if we are using proxy command
- * and can not use DNS on that socket */
- if (strcmp(gss_host, "UNKNOWN") == 0) {
- free(gss_host);
+ if (FIPS_mode()) {
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
+ options.gss_keyex = 0;
+ } else {
+ /* Add the GSSAPI mechanisms currently supported on this
+ * client to the key exchange algorithm proposal */
+ orig = myproposal[PROPOSAL_KEX_ALGS];
+ char * gss_kex_filtered = FIPS_mode() ?
+ match_filter_allowlist(options.gss_kex_algorithms, GSS_KEX_DEFAULT_KEX_FIPS) : xstrdup(options.gss_kex_algorithms);
+
+ if (options.gss_server_identity) {
+ gss_host = xstrdup(options.gss_server_identity);
+ } else if (options.gss_trust_dns) {
+ gss_host = remote_hostname(ssh);
+ /* Fall back to specified host if we are using proxy command
+ * and can not use DNS on that socket */
+ if (strcmp(gss_host, "UNKNOWN") == 0) {
+ free(gss_host);
+ gss_host = xstrdup(host);
+ }
+ } else {
gss_host = xstrdup(host);
}
- } else {
- gss_host = xstrdup(host);
- }
- gss = ssh_gssapi_client_mechanisms(gss_host,
- options.gss_client_identity, options.gss_kex_algorithms);
- if (gss) {
- debug("Offering GSSAPI proposal: %s", gss);
- xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
- "%s,%s", gss, orig);
-
- /* If we've got GSSAPI algorithms, then we also support the
- * 'null' hostkey, as a last resort */
- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
- "%s,null", orig);
+ gss = ssh_gssapi_client_mechanisms(gss_host,
+ options.gss_client_identity, options.gss_kex_algorithms);
+ if (gss) {
+ debug("Offering GSSAPI proposal: %s", gss);
+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
+ "%s,%s", gss, orig);
+
+ /* If we've got GSSAPI algorithms, then we also support the
+ * 'null' hostkey, as a last resort */
+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
+ "%s,null", orig);
+ }
/* Add the GSSAPI mechanisms currently supported on this
* client to the key exchange algorithm proposal */
orig = myproposal[PROPOSAL_KEX_ALGS];
@@ -281,7 +286,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
}
}
#endif
diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
--- openssh-8.6p1/sshd.c.fips 2021-05-06 12:08:36.493926838 +0200
+++ openssh-8.6p1/sshd.c 2021-05-06 12:13:56.501492639 +0200
@@ -66,6 +66,7 @@
#endif
gss = ssh_gssapi_client_mechanisms(gss_host,
- options.gss_client_identity, options.gss_kex_algorithms);
+ options.gss_client_identity, gss_kex_filtered);
+ free(gss_kex_filtered);
+
if (gss) {
debug("Offering GSSAPI proposal: %s", gss);
xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
diff --git a/sshd.c b/sshd.c
index ed7faf96d..de2baa5e4 100644
--- a/sshd.c
+++ b/sshd.c
@@ -44,6 +44,7 @@
#include <poll.h>
#include <pwd.h>
#include <signal.h>
+#include <syslog.h>
#include <stdarg.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
@@ -77,6 +78,7 @@
#include <openssl/dh.h>
#include <openssl/bn.h>
@@ -55,6 +56,7 @@
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
#include <openssl/rand.h>
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
#endif
@@ -1931,6 +1931,13 @@ main(int ac, char **av)
@@ -1613,6 +1615,13 @@ main(int ac, char **av)
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
do_log2_r(r, ll, "Unable to load host key \"%s\"",
options.host_key_files[i]);
@ -382,7 +652,7 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
@@ -2110,6 +2113,10 @@ main(int ac, char **av)
@@ -1836,6 +1845,10 @@ main(int ac, char **av)
/* Reinitialize the log (because of the fork above). */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
@ -393,45 +663,27 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
/*
* Chdir to the root directory so that the current disk can be
* unmounted if desired.
@@ -2494,10 +2501,14 @@ do_ssh2_kex(struct ssh *ssh)
if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
orig = NULL;
- if (options.gss_keyex)
- gss = ssh_gssapi_server_mechanisms();
- else
- gss = NULL;
+ if (options.gss_keyex) {
+ if (FIPS_mode()) {
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
+ options.gss_keyex = 0;
+ } else {
+ gss = ssh_gssapi_server_mechanisms();
+ }
+ }
if (gss && orig)
xasprintf(&newstr, "%s,%s", gss, orig);
diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
--- openssh-8.6p1/sshkey.c.fips 2021-05-06 12:08:36.493926838 +0200
+++ openssh-8.6p1/sshkey.c 2021-05-06 12:08:36.502926908 +0200
diff --git a/sshkey.c b/sshkey.c
index 148fee2b7..394d9b105 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -36,6 +36,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
+#include <openssl/fips.h>
#endif
#include "crypto_api.h"
@@ -57,6 +58,7 @@
@@ -58,6 +59,7 @@
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "match.h"
+#include "log.h"
#include "ssh-sk.h"
#include "ssh-pkcs11.h"
#ifdef WITH_XMSS
@@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai
@@ -386,6 +388,18 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
impl = keyimpls[i];
if (impl->name == NULL || impl->type == KEY_NULL)
continue;
@ -450,7 +702,7 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
if (!include_sigonly && impl->sigonly)
continue;
if ((certs_only && !impl->cert) || (plain_only && impl->cert))
@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c
@@ -1418,6 +1432,20 @@ sshkey_read(struct sshkey *ret, char **cpp)
return SSH_ERR_EC_CURVE_MISMATCH;
}
@ -471,208 +723,29 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
/* Fill in ret from parsed key */
sshkey_free_contents(ret);
*ret = *k;
@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key,
@@ -2251,6 +2279,11 @@ sshkey_sign(struct sshkey *key,
*lenp = 0;
if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ /* Fallthrough */
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ /* Fallthrough */
if ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
if ((r = sshkey_unshield_private(key)) != 0)
@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key,
@@ -2290,6 +2323,10 @@ sshkey_verify(const struct sshkey *key,
*detailsp = NULL;
if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
if ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
return impl->funcs->verify(key, sig, siglen, data, dlen,
diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
--- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200
+++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200
@@ -20,6 +20,7 @@
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
+#include <openssl/fips.h>
#include <openssl/pem.h>
#include "openbsd-compat/openssl-compat.h"
#endif
@@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na
#endif
}
#ifdef WITH_OPENSSL
+ if (FIPS_mode()) {
+ if (type == KEY_DSA)
+ fatal("DSA keys are not allowed in FIPS mode");
+ if (type == KEY_ED25519 || type == KEY_ED25519_SK)
+ fatal("ED25519 keys are not allowed in FIPS mode");
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
switch (type) {
case KEY_DSA:
if (*bitsp != 1024)
@@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw)
first = 1;
printf("%s: generating new host keys: ", __progname);
}
+ type = sshkey_type_from_name(key_types[i].key_type);
+
+ /* Skip the keys that are not supported in FIPS mode */
+ if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) {
+ logit("Skipping %s key in FIPS mode",
+ key_types[i].key_type_display);
+ goto next;
+ }
+
printf("%s ", key_types[i].key_type_display);
fflush(stdout);
- type = sshkey_type_from_name(key_types[i].key_type);
if ((fd = mkstemp(prv_tmp)) == -1) {
error("Could not save your private key in %s: %s",
prv_tmp, strerror(errno));
diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c
--- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200
+++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200
@@ -33,6 +33,7 @@
#include <openssl/err.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
+#include <openssl/fips.h>
#include <stdarg.h>
#include <string.h>
@@ -1705,6 +1707,8 @@ ssh_rsa_generate(u_int bits, RSA
goto out;
if ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
return impl->funcs->verify(key, sig, siglen, data, dlen,
--
2.52.0
if (EVP_PKEY_keygen(ctx, &res) <= 0) {
+ if (FIPS_mode())
+ logit_f("the key length might be unsupported by FIPS mode approved key generation method");
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c
--- openssh-8.7p1/kexgen.c.fips3 2022-07-11 16:11:21.973519913 +0200
+++ openssh-8.7p1/kexgen.c 2022-07-11 16:25:31.172187365 +0200
@@ -31,6 +31,7 @@
#include <stdio.h>
#include <string.h>
#include <signal.h>
+#include <openssl/fips.h>
#include "sshkey.h"
#include "kex.h"
@@ -115,10 +116,20 @@ kex_gen_client(struct ssh *ssh)
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_keypair(kex);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_keypair(kex);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -186,11 +197,21 @@ input_kex_gen_reply(int type, u_int32_t
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_dec(kex, server_blob,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_dec(kex, server_blob,
+ &shared_secret);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -285,12 +306,22 @@ input_kex_gen_init(int type, u_int32_t s
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
+ &shared_secret);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
- &server_pubkey, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
+ &server_pubkey, &shared_secret);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c
--- openssh-8.7p1/ssh-ed25519.c.fips3 2022-07-11 16:53:41.428343304 +0200
+++ openssh-8.7p1/ssh-ed25519.c 2022-07-11 16:56:09.284663661 +0200
@@ -24,6 +24,7 @@
#include <string.h>
#include <stdarg.h>
+#include <openssl/fips.h>
#include "log.h"
#include "sshbuf.h"
@@ -52,6 +53,10 @@ ssh_ed25519_sign(const struct sshkey *ke
key->ed25519_sk == NULL ||
datalen >= INT_MAX - crypto_sign_ed25519_BYTES)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
smlen = slen = datalen + crypto_sign_ed25519_BYTES;
if ((sig = malloc(slen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
@@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey *
dlen >= INT_MAX - crypto_sign_ed25519_BYTES ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;

View file

@ -0,0 +1,47 @@
From 7167a191776dacf7e31cf8a8a2ed89887e49f4ee Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 39/53] openssh-8.7p1-ssh-manpage
---
ssh.1 | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/ssh.1 b/ssh.1
index 6a9fbdc5b..755cdef2b 100644
--- a/ssh.1
+++ b/ssh.1
@@ -510,12 +510,12 @@ For full details of the options listed below, and their possible values, see
.It BatchMode
.It BindAddress
.It BindInterface
-.It CASignatureAlgorithms
.It CanonicalDomains
.It CanonicalizeFallbackLocal
.It CanonicalizeHostname
.It CanonicalizeMaxDots
.It CanonicalizePermittedCNAMEs
+.It CASignatureAlgorithms
.It CertificateFile
.It ChannelTimeout
.It CheckHostIP
@@ -528,6 +528,7 @@ For full details of the options listed below, and their possible values, see
.It ControlPath
.It ControlPersist
.It DynamicForward
+.It EnableSSHKeysign
.It EnableEscapeCommandline
.It EnableSSHKeysign
.It EscapeChar
@@ -588,6 +589,8 @@ For full details of the options listed below, and their possible values, see
.It RemoteCommand
.It RemoteForward
.It RequestTTY
+.It RevokedHostKeys
+.It SecurityKeyProvider
.It RequiredRSASize
.It RevokedHostKeys
.It SecurityKeyProvider
--
2.52.0

View file

@ -1,6 +1,17 @@
diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostkey-agent.sh
--- openssh-9.3p1/regress/hostkey-agent.sh.xxx 2023-05-29 18:15:56.311236887 +0200
+++ openssh-9.3p1/regress/hostkey-agent.sh 2023-05-29 18:16:07.598503551 +0200
From 53e44bd1f669ecd6a7429e94b55beec8e3c0c529 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 40/53] openssh-8.7p1-negotiate-supported-algs
---
regress/hostkey-agent.sh | 32 +++++++++++++++++++++++++-------
sshconnect2.c | 17 +++++++++++++++--
2 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh
index 28dcfe170..b9e716dcd 100644
--- a/regress/hostkey-agent.sh
+++ b/regress/hostkey-agent.sh
@@ -17,8 +17,21 @@ trace "make CA key"
${SSHKEYGEN} -qt ed25519 -f $OBJ/agent-ca -N '' || fatal "ssh-keygen CA"
@ -24,7 +35,7 @@ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostke
${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k"
${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \
-I localhost-with-alias $OBJ/agent-key.$k.pub || \
@@ -32,12 +48,16 @@ rm $OBJ/agent-ca # Don't need CA private
@@ -32,12 +45,16 @@ rm $OBJ/agent-ca # Don't need CA private any more either
unset SSH_AUTH_SOCK
@ -44,10 +55,10 @@ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostke
( printf 'localhost-with-alias,127.0.0.1,::1 ' ;
cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts
SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
@@ -50,15 +70,16 @@ for k in $SSH_KEYTYPES ; do
@@ -50,15 +67,16 @@ for k in $SSH_KEYTYPES ; do
done
SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com'`
SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com' | maybe_filter_sk`
+SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
# Prepare sshd_proxy for certificates.
@ -63,7 +74,7 @@ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostke
echo "Hostkey $OBJ/agent-key.${k}.pub" >> $OBJ/sshd_proxy
echo "HostCertificate $OBJ/agent-key.${k}-cert.pub" >> $OBJ/sshd_proxy
test -f $OBJ/agent-key.${k}.pub || fatal "no $k key"
@@ -70,7 +93,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >>
@@ -70,7 +88,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >> $OBJ/sshd_proxy
( printf '@cert-authority localhost-with-alias ' ;
cat $OBJ/agent-ca.pub) > $OBJ/known_hosts
@ -72,19 +83,20 @@ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostke
verbose "cert type $k"
opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"
SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c
--- openssh-9.3p1/sshconnect2.c.xxx 2023-04-26 17:37:35.100827792 +0200
+++ openssh-9.3p1/sshconnect2.c 2023-04-26 17:50:31.860748877 +0200
@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
diff --git a/sshconnect2.c b/sshconnect2.c
index fffa66c8d..f43c81ad9 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
const struct ssh_conn_info *cinfo)
{
char *myproposal[PROPOSAL_MAX];
- char *s, *all_key, *hkalgs = NULL;
+ char *s, *all_key, *hkalgs = NULL, *filtered_algs = NULL;
- char *all_key, *hkalgs = NULL;
+ char *all_key, *hkalgs = NULL, *filtered_algs = NULL;
int r, use_known_hosts_order = 0;
#if defined(GSSAPI) && defined(WITH_OPENSSL)
@@ -260,9 +260,21 @@ ssh_kex2(struct ssh *ssh, char *host, st
@@ -257,10 +257,22 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
if (use_known_hosts_order)
hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);
@ -100,14 +112,15 @@ diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c
+ options.hostkeyalgorithms, options.pubkey_accepted_algos);
+ }
+
kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers,
options.macs, compression_alg_list(options.compression),
kex_proposal_populate_entries(ssh, myproposal,
options.kex_algorithms, options.ciphers, options.macs,
compression_alg_list(options.compression),
- hkalgs ? hkalgs : options.hostkeyalgorithms);
+ filtered_algs);
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {
@@ -303,6 +315,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
@@ -304,6 +316,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
#endif
free(hkalgs);
@ -115,3 +128,6 @@ diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c
/* start key exchange */
if ((r = kex_setup(ssh, myproposal)) != 0)
--
2.52.0

View file

@ -0,0 +1,616 @@
From 1c0d3b6e9868ef31b97be1679389e3db2616eccd Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 41/53] openssh-9.0p1-evp-fips-kex
---
dh.c | 98 +++++++++++++++++++++++++++++++++-----
kex.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
kex.h | 6 +++
kexdh.c | 52 ++++++++++++++++++--
kexecdh.c | 129 ++++++++++++++++++++++++++++++++++++++++----------
5 files changed, 382 insertions(+), 42 deletions(-)
diff --git a/dh.c b/dh.c
index 8c9a29fa7..ea0a0b093 100644
--- a/dh.c
+++ b/dh.c
@@ -37,6 +37,9 @@
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/fips.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "dh.h"
#include "pathnames.h"
@@ -290,10 +293,15 @@ dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
int
dh_gen_key(DH *dh, int need)
{
- int pbits;
- const BIGNUM *dh_p, *pub_key;
+ const BIGNUM *dh_p, *dh_g;
+ BIGNUM *pub_key = NULL, *priv_key = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ int pbits, r = 0;
- DH_get0_pqg(dh, &dh_p, NULL, NULL);
+ DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
if (need < 0 || dh_p == NULL ||
(pbits = BN_num_bits(dh_p)) <= 0 ||
@@ -301,19 +309,85 @@ dh_gen_key(DH *dh, int need)
return SSH_ERR_INVALID_ARGUMENT;
if (need < 256)
need = 256;
+
+ if ((param_bld = OSSL_PARAM_BLD_new()) == NULL ||
+ (ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL) {
+ OSSL_PARAM_BLD_free(param_bld);
+ return SSH_ERR_ALLOC_FAIL;
+ }
+
+ if (OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_FFC_P, dh_p) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_FFC_G, dh_g) != 1) {
+ error_f("Could not set p,q,g parameters");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
/*
* Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
* so double requested need here.
*/
- if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
- return SSH_ERR_LIBCRYPTO_ERROR;
-
- if (DH_generate_key(dh) == 0)
- return SSH_ERR_LIBCRYPTO_ERROR;
- DH_get0_key(dh, &pub_key, NULL);
- if (!dh_pub_is_valid(dh, pub_key))
- return SSH_ERR_INVALID_FORMAT;
- return 0;
+ if (OSSL_PARAM_BLD_push_int(param_bld,
+ OSSL_PKEY_PARAM_DH_PRIV_LEN,
+ MINIMUM(need * 2, pbits - 1)) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata_init(ctx) != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata(ctx, &pkey,
+ EVP_PKEY_KEY_PARAMETERS, params) != 1) {
+ error_f("Failed key generation");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* reuse context for key generation */
+ EVP_PKEY_CTX_free(ctx);
+ ctx = NULL;
+
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ EVP_PKEY_keygen_init(ctx) != 1) {
+ error_f("Could not create or init context");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_generate(ctx, &pkey) != 1) {
+ error_f("Could not generate keys");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_public_check(ctx) != 1) {
+ error_f("The public key is incorrect");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
+ &pub_key) != 1 ||
+ EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
+ &priv_key) != 1 ||
+ DH_set0_key(dh, pub_key, priv_key) != 1) {
+ error_f("Could not set pub/priv keys to DH struct");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* transferred */
+ pub_key = NULL;
+ priv_key = NULL;
+out:
+ OSSL_PARAM_free(params);
+ OSSL_PARAM_BLD_free(param_bld);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ BN_clear_free(pub_key);
+ BN_clear_free(priv_key);
+ return r;
}
DH *
diff --git a/kex.c b/kex.c
index da2a537ce..56c80395c 100644
--- a/kex.c
+++ b/kex.c
@@ -1613,3 +1613,142 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
return r;
}
+#ifdef WITH_OPENSSL
+/*
+ * Creates an EVP_PKEY from the given parameters and keys.
+ * The private key can be omitted.
+ */
+EVP_PKEY *
+sshkey_create_evp(OSSL_PARAM_BLD *param_bld, EVP_PKEY_CTX *ctx)
+{
+ EVP_PKEY *ret = NULL;
+ OSSL_PARAM *params = NULL;
+ if (param_bld == NULL || ctx == NULL) {
+ debug2_f("param_bld or ctx is NULL");
+ return NULL;
+ }
+ if ((params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ debug2_f("Could not build param list");
+ return NULL;
+ }
+ if (EVP_PKEY_fromdata_init(ctx) != 1 ||
+ EVP_PKEY_fromdata(ctx, &ret, EVP_PKEY_KEYPAIR, params) != 1) {
+ debug2_f("EVP_PKEY_fromdata failed");
+ OSSL_PARAM_free(params);
+ return NULL;
+ }
+ return ret;
+}
+
+int
+kex_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey)
+{
+ OSSL_PARAM_BLD *param_bld = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ BN_CTX *bn_ctx = NULL;
+ uint8_t *pub_ser = NULL;
+ const char *group_name;
+ const EC_POINT *pub = NULL;
+ const BIGNUM *priv = NULL;
+ int ret = 0;
+
+ if (k == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL ||
+ (bn_ctx = BN_CTX_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ if ((group_name = OSSL_EC_curve_nid2name(ecdsa_nid)) == NULL ||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
+ OSSL_PKEY_PARAM_GROUP_NAME,
+ group_name,
+ strlen(group_name)) != 1) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((pub = EC_KEY_get0_public_key(k)) != NULL) {
+ const EC_GROUP *group;
+ size_t len;
+
+ group = EC_KEY_get0_group(k);
+ len = EC_POINT_point2oct(group, pub,
+ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
+ if ((pub_ser = malloc(len)) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ EC_POINT_point2oct(group,
+ pub,
+ POINT_CONVERSION_UNCOMPRESSED,
+ pub_ser,
+ len,
+ bn_ctx);
+ if (OSSL_PARAM_BLD_push_octet_string(param_bld,
+ OSSL_PKEY_PARAM_PUB_KEY,
+ pub_ser,
+ len) != 1) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ }
+ if ((priv = EC_KEY_get0_private_key(k)) != NULL &&
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+out:
+ OSSL_PARAM_BLD_free(param_bld);
+ EVP_PKEY_CTX_free(ctx);
+ BN_CTX_free(bn_ctx);
+ free(pub_ser);
+ return ret;
+}
+
+int
+kex_create_evp_dh(EVP_PKEY **pkey, const BIGNUM *p, const BIGNUM *q,
+ const BIGNUM *g, const BIGNUM *pub, const BIGNUM *priv)
+{
+ OSSL_PARAM_BLD *param_bld = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ int r = 0;
+
+ /* create EVP_PKEY-DH key */
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
+ error_f("EVP_PKEY_CTX or PARAM_BLD init failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_PUB_KEY, pub) != 1) {
+ error_f("Failed pushing params to OSSL_PARAM_BLD");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (priv != NULL &&
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
+ error_f("Failed pushing private key to OSSL_PARAM_BLD");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL)
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+out:
+ OSSL_PARAM_BLD_free(param_bld);
+ EVP_PKEY_CTX_free(ctx);
+ return r;
+}
+#endif /* WITH_OPENSSL */
diff --git a/kex.h b/kex.h
index cb06e85a3..6daafb159 100644
--- a/kex.h
+++ b/kex.h
@@ -37,6 +37,9 @@
# include <openssl/bn.h>
# include <openssl/dh.h>
# include <openssl/ecdsa.h>
+# include <openssl/evp.h>
+# include <openssl/core_names.h>
+# include <openssl/param_build.h>
# ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
# else /* OPENSSL_HAS_ECC */
@@ -316,6 +319,9 @@ int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE],
const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int)
__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
+int kex_create_evp_dh(EVP_PKEY **, const BIGNUM *, const BIGNUM *,
+ const BIGNUM *, const BIGNUM *, const BIGNUM *);
+int kex_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey);
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
void dump_digest(const char *, const u_char *, int);
diff --git a/kexdh.c b/kexdh.c
index 6d5a7813d..b05277aa1 100644
--- a/kexdh.c
+++ b/kexdh.c
@@ -36,6 +36,10 @@
#include "openbsd-compat/openssl-compat.h"
#include <openssl/bn.h>
#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "sshkey.h"
#include "kex.h"
@@ -84,9 +88,12 @@ int
kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out)
{
BIGNUM *shared_secret = NULL;
+ const BIGNUM *pub, *priv, *p, *q, *g;
+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
u_char *kbuf = NULL;
size_t klen = 0;
- int kout, r;
+ int r = 0;
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_pub= ");
@@ -101,24 +108,59 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out)
r = SSH_ERR_MESSAGE_INCOMPLETE;
goto out;
}
- klen = DH_size(kex->dh);
+
+ DH_get0_key(kex->dh, &pub, &priv);
+ DH_get0_pqg(kex->dh, &p, &q, &g);
+ /* import key */
+ r = kex_create_evp_dh(&pkey, p, q, g, pub, priv);
+ if (r != 0) {
+ error_f("Could not create EVP_PKEY for dh");
+ ERR_print_errors_fp(stderr);
+ goto out;
+ }
+ /* import peer key
+ * the parameters should be the same as with pkey
+ */
+ r = kex_create_evp_dh(&dh_pkey, p, q, g, dh_pub, NULL);
+ if (r != 0) {
+ error_f("Could not import peer key for dh");
+ ERR_print_errors_fp(stderr);
+ goto out;
+ }
+
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL) {
+ error_f("Could not init EVP_PKEY_CTX for dh");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (EVP_PKEY_derive_init(ctx) != 1 ||
+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
+ error_f("Could not get key size");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
if ((kbuf = malloc(klen)) == NULL ||
(shared_secret = BN_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((kout = DH_compute_key(kbuf, dh_pub, kex->dh)) < 0 ||
- BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1 ||
+ BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
+ error_f("Could not derive key");
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
+ dump_digest("shared secret", kbuf, klen);
#endif
r = sshbuf_put_bignum2(out, shared_secret);
out:
freezero(kbuf, klen);
BN_clear_free(shared_secret);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(dh_pkey);
+ EVP_PKEY_CTX_free(ctx);
return r;
}
diff --git a/kexecdh.c b/kexecdh.c
index 500ec5725..1a1bae35e 100644
--- a/kexecdh.c
+++ b/kexecdh.c
@@ -36,17 +36,57 @@
#include <openssl/bn.h>
#include <openssl/ecdh.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
+#include <openssl/err.h>
#include "sshkey.h"
#include "kex.h"
#include "sshbuf.h"
#include "digest.h"
#include "ssherr.h"
+#include "log.h"
static int
kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key,
const EC_GROUP *, struct sshbuf **);
+static EC_KEY *
+generate_ec_keys(int ec_nid)
+{
+ EC_KEY *client_key = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ const char *group_name;
+
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL)
+ goto out;
+ if ((group_name = OSSL_EC_curve_nid2name(ec_nid)) == NULL ||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ error_f("Could not create OSSL_PARAM");
+ goto out;
+ }
+ if (EVP_PKEY_keygen_init(ctx) != 1 ||
+ EVP_PKEY_CTX_set_params(ctx, params) != 1 ||
+ EVP_PKEY_generate(ctx, &pkey) != 1 ||
+ (client_key = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
+ error_f("Could not generate ec keys");
+ goto out;
+ }
+out:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_BLD_free(param_bld);
+ OSSL_PARAM_free(params);
+ return client_key;
+}
+
int
kex_ecdh_keypair(struct kex *kex)
{
@@ -56,11 +96,7 @@ kex_ecdh_keypair(struct kex *kex)
struct sshbuf *buf = NULL;
int r;
- if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(client_key) != 1) {
+ if ((client_key = generate_ec_keys(kex->ec_nid)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -102,11 +138,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob,
*server_blobp = NULL;
*shared_secretp = NULL;
- if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(server_key) != 1) {
+ if ((server_key = generate_ec_keys(kex->ec_nid)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -141,11 +173,21 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob,
{
struct sshbuf *buf = NULL;
BIGNUM *shared_secret = NULL;
- EC_POINT *dh_pub = NULL;
- u_char *kbuf = NULL;
- size_t klen = 0;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ u_char *kbuf = NULL, *pub = NULL;
+ size_t klen = 0, publen;
+ const char *group_name;
int r;
+ /* import EC_KEY to EVP_PKEY */
+ if ((r = kex_create_evp_ec(key, kex->ec_nid, &pkey)) != 0) {
+ error_f("Could not create EVP_PKEY");
+ goto out;
+ }
+
*shared_secretp = NULL;
if ((buf = sshbuf_new()) == NULL) {
@@ -154,45 +196,82 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob,
}
if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0)
goto out;
- if ((dh_pub = EC_POINT_new(group)) == NULL) {
+
+ /* the public key is in the buffer in octet string UNCOMPRESSED
+ * format. See sshbuf_put_ec */
+ if ((r = sshbuf_get_string(buf, &pub, &publen)) != 0)
+ goto out;
+ sshbuf_reset(buf);
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_get_ec(buf, dh_pub, group)) != 0) {
+ if ((group_name = OSSL_EC_curve_nid2name(kex->ec_nid)) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (OSSL_PARAM_BLD_push_octet_string(param_bld,
+ OSSL_PKEY_PARAM_PUB_KEY, pub, publen) != 1 ||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ error_f("Failed to set params for dh_pkey");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata_init(ctx) != 1 ||
+ EVP_PKEY_fromdata(ctx, &dh_pkey,
+ EVP_PKEY_PUBLIC_KEY, params) != 1 ||
+ EVP_PKEY_public_check(ctx) != 1) {
+ error_f("Peer public key import failed");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- sshbuf_reset(buf);
#ifdef DEBUG_KEXECDH
fputs("public key:\n", stderr);
- sshkey_dump_ec_point(group, dh_pub);
+ EVP_PKEY_print_public_fp(stderr, dh_pkey, 0, NULL);
#endif
- if (sshkey_ec_validate_public(group, dh_pub) != 0) {
- r = SSH_ERR_MESSAGE_INCOMPLETE;
+ EVP_PKEY_CTX_free(ctx);
+ ctx = NULL;
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ EVP_PKEY_derive_init(ctx) != 1 ||
+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
+ error_f("Failed to get derive information");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- klen = (EC_GROUP_get_degree(group) + 7) / 8;
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
+ if ((kbuf = malloc(klen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen ||
- BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
#ifdef DEBUG_KEXECDH
dump_digest("shared secret", kbuf, klen);
#endif
+ if ((shared_secret = BN_new()) == NULL ||
+ (BN_bin2bn(kbuf, klen, shared_secret) == NULL)) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0)
goto out;
*shared_secretp = buf;
buf = NULL;
out:
- EC_POINT_clear_free(dh_pub);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(dh_pkey);
+ OSSL_PARAM_BLD_free(param_bld);
+ OSSL_PARAM_free(params);
BN_clear_free(shared_secret);
freezero(kbuf, klen);
+ freezero(pub, publen);
sshbuf_free(buf);
return r;
}
--
2.52.0

View file

@ -0,0 +1,332 @@
From 1cd47036353899fe066f5241d3d70778f103c0e0 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 42/53] openssh-8.7p1-nohostsha1proof
---
compat.c | 6 ++++++
compat.h | 2 +-
monitor.c | 27 +++++++++++++++++------
regress/unittests/kex/test_kex.c | 3 ++-
regress/unittests/sshkey/test_file.c | 3 ++-
regress/unittests/sshkey/test_fuzz.c | 3 ++-
regress/unittests/sshkey/test_sshkey.c | 30 ++++++++++++++++----------
serverloop.c | 6 +++++-
ssh-rsa.c | 3 ++-
sshconnect2.c | 8 +++++++
sshd-session.c | 21 ++++++++++++++++++
11 files changed, 88 insertions(+), 24 deletions(-)
diff --git a/compat.c b/compat.c
index b59f0bfc0..4e611dc39 100644
--- a/compat.c
+++ b/compat.c
@@ -42,6 +42,7 @@ void
compat_banner(struct ssh *ssh, const char *version)
{
int i;
+ int forbid_ssh_rsa = 0;
static struct {
char *pat;
int bugs;
@@ -125,16 +126,21 @@ compat_banner(struct ssh *ssh, const char *version)
};
/* process table, return first match */
+ forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA);
ssh->compat = 0;
for (i = 0; check[i].pat; i++) {
if (match_pattern_list(version, check[i].pat, 0) == 1) {
debug_f("match: %s pat %s compat 0x%08x",
version, check[i].pat, check[i].bugs);
ssh->compat = check[i].bugs;
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
return;
}
}
debug_f("no match: %s", version);
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
}
/* Always returns pointer to allocated memory, caller must free. */
diff --git a/compat.h b/compat.h
index 1a19060fc..2e6db5bf9 100644
--- a/compat.h
+++ b/compat.h
@@ -30,7 +30,7 @@
#define SSH_BUG_UTF8TTYMODE 0x00000001
#define SSH_BUG_SIGTYPE 0x00000002
#define SSH_BUG_SIGTYPE74 0x00000004
-/* #define unused 0x00000008 */
+#define SSH_RH_RSASIGSHA 0x00000008
#define SSH_OLD_SESSIONID 0x00000010
/* #define unused 0x00000020 */
#define SSH_BUG_DEBUG 0x00000040
diff --git a/monitor.c b/monitor.c
index b2f501790..6c83739ee 100644
--- a/monitor.c
+++ b/monitor.c
@@ -754,11 +754,12 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m)
struct sshkey *pubkey, *key;
struct sshbuf *sigbuf = NULL;
u_char *p = NULL, *signature = NULL;
- char *alg = NULL;
- size_t datlen, siglen;
- int r, is_proof = 0, keyid;
- u_int compat;
+ char *alg = NULL, *effective_alg;
+ size_t datlen, siglen, alglen;
+ int r, is_proof = 0;
+ u_int keyid, compat;
const char proof_req[] = "hostkeys-prove-00@openssh.com";
+ const char safe_rsa[] = "rsa-sha2-256";
debug3_f("entering");
@@ -816,18 +817,30 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m)
}
if ((key = get_hostkey_by_index(keyid)) != NULL) {
- if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
+ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
+ && (sshkey_type_plain(key->type) == KEY_RSA)) {
+ effective_alg = safe_rsa;
+ } else {
+ effective_alg = alg;
+ }
+ if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, effective_alg,
options.sk_provider, NULL, compat)) != 0)
fatal_fr(r, "sign");
} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
auth_sock > 0) {
+ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
+ && (sshkey_type_plain(key->type) == KEY_RSA)) {
+ effective_alg = safe_rsa;
+ } else {
+ effective_alg = alg;
+ }
if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
- p, datlen, alg, compat)) != 0)
+ p, datlen, effective_alg, compat)) != 0)
fatal_fr(r, "agent sign");
} else
fatal_f("no hostkey from index %d", keyid);
- debug3_f("%s %s signature len=%zu", alg,
+ debug3_f("%s (effective: %s) %s signature len=%zu", alg, effective_alg,
is_proof ? "hostkey proof" : "KEX", siglen);
sshbuf_reset(m);
diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c
index 16c2f2dff..f4700deeb 100644
--- a/regress/unittests/kex/test_kex.c
+++ b/regress/unittests/kex/test_kex.c
@@ -110,7 +110,8 @@ do_kex_with_key(char *kex, char *cipher, char *mac,
kex_params.proposal[PROPOSAL_MAC_ALGS_CTOS] = mac;
kex_params.proposal[PROPOSAL_MAC_ALGS_STOC] = mac;
}
- keyname = strdup(sshkey_ssh_name(private));
+ keyname = (strcmp(sshkey_ssh_name(private), "ssh-rsa")) ?
+ strdup(sshkey_ssh_name(private)) : strdup("rsa-sha2-256");
ASSERT_PTR_NE(keyname, NULL);
kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname;
ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c
index e412b75d8..5b06bc905 100644
--- a/regress/unittests/sshkey/test_file.c
+++ b/regress/unittests/sshkey/test_file.c
@@ -106,6 +106,7 @@ sshkey_file_tests(void)
sshkey_free(k2);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("load RSA cert with SHA1 signature");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0);
ASSERT_PTR_NE(k2, NULL);
@@ -113,7 +114,7 @@ sshkey_file_tests(void)
ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
ASSERT_STRING_EQ(k2->cert->signature_type, "ssh-rsa");
sshkey_free(k2);
- TEST_DONE();
+ TEST_DONE(); */
TEST_START("load RSA cert with SHA512 signature");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0);
diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c
index d0f47d7cf..ba4d506d5 100644
--- a/regress/unittests/sshkey/test_fuzz.c
+++ b/regress/unittests/sshkey/test_fuzz.c
@@ -273,13 +273,14 @@ sshkey_fuzz_tests(void)
TEST_DONE();
#ifdef WITH_OPENSSL
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("fuzz RSA sig");
buf = load_file("rsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
sshbuf_free(buf);
sig_fuzz(k1, "ssh-rsa");
sshkey_free(k1);
- TEST_DONE();
+ TEST_DONE();*/
TEST_START("fuzz RSA SHA256 sig");
buf = load_file("rsa_1");
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c
index d0c46a90b..7b5e51b83 100644
--- a/regress/unittests/sshkey/test_sshkey.c
+++ b/regress/unittests/sshkey/test_sshkey.c
@@ -59,6 +59,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type,
u_char *sigblob;
size_t siglen;
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
+ int expected = (sig_alg == NULL || strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
+
ca_buf = sshbuf_new();
ASSERT_PTR_NE(ca_buf, NULL);
ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
@@ -100,8 +103,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type,
ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
- sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0);
- ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
+ sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), expected);
+ if (expected == 0)
+ ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
free(sigblob);
sshbuf_free(ca_buf);
@@ -118,16 +122,20 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg,
{
size_t len;
u_char *sig;
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT crypto policies */
+ int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 0) : 0;
ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg,
- NULL, NULL, 0), 0);
- ASSERT_SIZE_T_GT(len, 8);
- ASSERT_PTR_NE(sig, NULL);
- ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
- ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
- /* Fuzz test is more comprehensive, this is just a smoke test */
- sig[len - 5] ^= 0x10;
- ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ NULL, NULL, 0), expected);
+ if (expected == 0) {
+ ASSERT_SIZE_T_GT(len, 8);
+ ASSERT_PTR_NE(sig, NULL);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
+ /* Fuzz test is more comprehensive, this is just a smoke test */
+ sig[len - 5] ^= 0x10;
+ ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ }
free(sig);
}
@@ -552,7 +560,7 @@ sshkey_tests(void)
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
NULL), 0);
k3 = get_private("rsa_1");
- build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
+ build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, "rsa-sha2-256");
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
ASSERT_PTR_EQ(k4, NULL);
diff --git a/serverloop.c b/serverloop.c
index 5d3b194d1..55411a6b4 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -76,6 +76,7 @@
#include "auth-options.h"
#include "serverloop.h"
#include "ssherr.h"
+#include "compat.h"
extern ServerOptions options;
@@ -721,7 +722,10 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
sigalg = "rsa-sha2-256";
}
-
+ if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) {
+ sigalg = "rsa-sha2-512";
+ debug3_f("SHA1 signature is not supported, falling back to %s", sigalg);
+ }
debug3_f("sign %s key (index %d) using sigalg %s",
sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
if ((r = sshbuf_put_cstring(sigbuf,
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 9428df8d1..7843f3e26 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -533,7 +533,8 @@ ssh_rsa_verify(const struct sshkey *key,
ret = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- if (hash_alg != want_alg) {
+ if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) {
+ debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg);
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
}
diff --git a/sshconnect2.c b/sshconnect2.c
index f43c81ad9..2d98fc3da 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1434,6 +1434,14 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
retried = 1;
goto retry_pin;
}
+ if ((r == SSH_ERR_LIBCRYPTO_ERROR) && strcmp("ssh-rsa", alg)) {
+ char rsa_safe_alg[] = "rsa-sha2-512";
+ debug3_f("trying to fallback to algorithm %s", rsa_safe_alg);
+
+ if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
+ rsa_safe_alg, options.sk_provider, pin, compat)) != 0)
+ debug_fr(r, "sshkey_sign - RSA fallback");
+ }
goto out;
}
diff --git a/sshd-session.c b/sshd-session.c
index e49e4fb51..a558bbc33 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1288,6 +1288,27 @@ main(int ac, char **av)
check_ip_options(ssh);
+ {
+ struct sshkey *rsakey = NULL;
+ rsakey = get_hostkey_private_by_type(KEY_RSA, 0, ssh);
+ if (rsakey == NULL)
+ rsakey = get_hostkey_private_by_type(KEY_RSA_CERT, 0, ssh);
+
+ if (rsakey != NULL) {
+ size_t sign_size = 0;
+ u_char *tmp = NULL;
+ u_char data[] = "Test SHA1 vector";
+ int res;
+
+ res = sshkey_sign(rsakey, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
+ free(tmp);
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) {
+ verbose_f("SHA1 in signatures is disabled for RSA keys");
+ ssh->compat |= SSH_RH_RSASIGSHA;
+ }
+ }
+ }
+
/* Prepare the channels layer */
channel_init_channels(ssh);
channel_set_af(ssh, options.address_family);
--
2.52.0

View file

@ -0,0 +1,25 @@
From 1799ea7ad21a579b864a536709d732f4a8e533dc Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 43/53] openssh-9.9p1-separate-keysign
---
ssh_config.5 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ssh_config.5 b/ssh_config.5
index 8ac5e1633..a06fbfa11 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -797,7 +797,7 @@ or
This option should be placed in the non-hostspecific section.
See
.Xr ssh-keysign 8
-for more information.
+for more information. ssh-keysign should be installed explicitly.
.It Cm EscapeChar
Sets the escape character (default:
.Ql ~ ) .
--
2.52.0

View file

@ -0,0 +1,402 @@
From 21202362f4ddaeb630d873fb426039004ac82338 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 44/53] openssh-9.9p1-openssl-mlkem
---
kex-names.c | 23 +++-
kexmlkem768x25519.c | 291 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 313 insertions(+), 1 deletion(-)
diff --git a/kex-names.c b/kex-names.c
index 1360a4095..9c96e5cb0 100644
--- a/kex-names.c
+++ b/kex-names.c
@@ -109,6 +109,19 @@ static const struct kexalg gss_kexalgs[] = {
{ NULL, 0, -1, -1, 0},
};
+static int is_mlkem768_available()
+{
+ static int is_fetched = -1;
+
+ if (is_fetched == -1) {
+ EVP_KEM *mlkem768 = EVP_KEM_fetch(NULL, "mlkem768", NULL);
+ is_fetched = mlkem768 != NULL ? 1 : 0;
+ EVP_KEM_free(mlkem768);
+ }
+
+ return is_fetched;
+}
+
static char *
kex_alg_list_internal(char sep, const struct kexalg *algs)
{
@@ -116,8 +129,12 @@ kex_alg_list_internal(char sep, const struct kexalg *algs)
const struct kexalg *k;
char sep_str[2] = {sep, '\0'};
- for (k = kexalgs; k->name != NULL; k++)
+ for (k = kexalgs; k->name != NULL; k++) {
+ if (strcmp(k->name, KEX_MLKEM768X25519_SHA256) == 0
+ && !is_mlkem768_available())
+ continue;
xextendf(&ret, sep_str, "%s", k->name);
+ }
return ret;
}
@@ -139,6 +156,10 @@ kex_alg_by_name(const char *name)
{
const struct kexalg *k;
+ if (strcmp(name, KEX_MLKEM768X25519_SHA256) == 0
+ && !is_mlkem768_available())
+ return NULL;
+
for (k = kexalgs; k->name != NULL; k++) {
if (strcmp(k->name, name) == 0)
return k;
diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c
index 2585d1db3..ab6167221 100644
--- a/kexmlkem768x25519.c
+++ b/kexmlkem768x25519.c
@@ -44,10 +44,127 @@
#ifdef USE_MLKEM768X25519
#include "libcrux_mlkem768_sha3.h"
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <stdio.h>
+
+static int
+mlkem768_keypair_gen(unsigned char *pubkeybuf, unsigned char *privkeybuf)
+{
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *pkey = NULL;
+ int ret = SSH_ERR_INTERNAL_ERROR;
+ size_t pubkey_size = crypto_kem_mlkem768_PUBLICKEYBYTES, privkey_size = crypto_kem_mlkem768_SECRETKEYBYTES;
+
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "mlkem768", NULL);
+ if (ctx == NULL) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto err;
+ }
+
+ if (EVP_PKEY_keygen_init(ctx) <= 0
+ || EVP_PKEY_keygen(ctx, &pkey) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto err;
+ }
+
+ if (EVP_PKEY_get_raw_public_key(pkey, pubkeybuf, &pubkey_size) <= 0
+ || EVP_PKEY_get_raw_private_key(pkey, privkeybuf, &privkey_size) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto err;
+ }
+
+ if (privkey_size != crypto_kem_mlkem768_SECRETKEYBYTES
+ || pubkey_size != crypto_kem_mlkem768_PUBLICKEYBYTES) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto err;
+ }
+ ret = 0;
+
+ err:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+ if (ret == SSH_ERR_LIBCRYPTO_ERROR)
+ ERR_print_errors_fp(stderr);
+ return ret;
+}
+
+static int
+mlkem768_encap_secret(const u_char *pubkeybuf, u_char *secret, u_char *out)
+{
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ size_t outlen = crypto_kem_mlkem768_CIPHERTEXTBYTES,
+ secretlen = crypto_kem_mlkem768_BYTES;
+
+ pkey = EVP_PKEY_new_raw_public_key_ex(NULL, "mlkem768", NULL,
+ pubkeybuf, crypto_kem_mlkem768_PUBLICKEYBYTES);
+ if (pkey == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto err;
+ }
+
+ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+ if (ctx == NULL
+ || EVP_PKEY_encapsulate_init(ctx, NULL) <= 0
+ || EVP_PKEY_encapsulate(ctx, out, &outlen, secret, &secretlen) <= 0
+ || secretlen != crypto_kem_mlkem768_BYTES
+ || outlen != crypto_kem_mlkem768_CIPHERTEXTBYTES) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto err;
+ }
+ r = 0;
+
+ err:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+ if (r == SSH_ERR_LIBCRYPTO_ERROR)
+ ERR_print_errors_fp(stderr);
+
+ return r;
+}
+
+static int
+mlkem768_decap_secret(const u_char *privkeybuf, const u_char *wrapped, u_char *secret)
+{
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ size_t wrappedlen = crypto_kem_mlkem768_CIPHERTEXTBYTES,
+ secretlen = crypto_kem_mlkem768_BYTES;
+
+ pkey = EVP_PKEY_new_raw_private_key_ex(NULL, "mlkem768", NULL,
+ privkeybuf, crypto_kem_mlkem768_SECRETKEYBYTES);
+ if (pkey == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto err;
+ }
+
+ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+ if (ctx == NULL
+ || EVP_PKEY_decapsulate_init(ctx, NULL) <= 0
+ || EVP_PKEY_decapsulate(ctx, secret, &secretlen, wrapped, wrappedlen) <= 0
+ || secretlen != crypto_kem_mlkem768_BYTES) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto err;
+ }
+ r = 0;
+
+ err:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+
+ if (r == SSH_ERR_LIBCRYPTO_ERROR)
+ ERR_print_errors_fp(stderr);
+
+ return r;
+}
int
kex_kem_mlkem768x25519_keypair(struct kex *kex)
{
+#if 0
struct sshbuf *buf = NULL;
u_char rnd[LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN], *cp = NULL;
size_t need;
@@ -82,6 +199,36 @@ kex_kem_mlkem768x25519_keypair(struct kex *kex)
explicit_bzero(rnd, sizeof(rnd));
sshbuf_free(buf);
return r;
+#else
+ struct sshbuf *buf = NULL;
+ u_char *cp = NULL;
+ size_t need;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ if ((buf = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE;
+ if ((r = sshbuf_reserve(buf, need, &cp)) != 0)
+ goto out;
+ if ((r = mlkem768_keypair_gen(cp, kex->mlkem768_client_key)) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("client public key mlkem768:", cp,
+ crypto_kem_mlkem768_PUBLICKEYBYTES);
+#endif
+ cp += crypto_kem_mlkem768_PUBLICKEYBYTES;
+ kexc25519_keygen(kex->c25519_client_key, cp);
+#ifdef DEBUG_KEXECDH
+ dump_digest("client public key c25519:", cp, CURVE25519_SIZE);
+#endif
+ /* success */
+ r = 0;
+ kex->client_pub = buf;
+ buf = NULL;
+ out:
+ sshbuf_free(buf);
+ return r;
+#endif
}
int
@@ -89,6 +236,7 @@ kex_kem_mlkem768x25519_enc(struct kex *kex,
const struct sshbuf *client_blob, struct sshbuf **server_blobp,
struct sshbuf **shared_secretp)
{
+#if 0
struct sshbuf *server_blob = NULL;
struct sshbuf *buf = NULL;
const u_char *client_pub;
@@ -181,12 +329,97 @@ kex_kem_mlkem768x25519_enc(struct kex *kex,
sshbuf_free(server_blob);
sshbuf_free(buf);
return r;
+#else
+ struct sshbuf *server_blob = NULL;
+ struct sshbuf *buf = NULL;
+ const u_char *client_pub;
+ u_char server_pub[CURVE25519_SIZE], server_key[CURVE25519_SIZE];
+ u_char hash[SSH_DIGEST_MAX_LENGTH];
+ size_t need;
+ int r = SSH_ERR_INTERNAL_ERROR;
+ struct libcrux_mlkem768_enc_result enc; /* FIXME */
+
+ *server_blobp = NULL;
+ *shared_secretp = NULL;
+
+ /* client_blob contains both KEM and ECDH client pubkeys */
+ need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE;
+ if (sshbuf_len(client_blob) != need) {
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
+ }
+ client_pub = sshbuf_ptr(client_blob);
+#ifdef DEBUG_KEXECDH
+ dump_digest("client public key mlkem768:", client_pub,
+ crypto_kem_mlkem768_PUBLICKEYBYTES);
+ dump_digest("client public key 25519:",
+ client_pub + crypto_kem_mlkem768_PUBLICKEYBYTES,
+ CURVE25519_SIZE);
+#endif
+
+ /* allocate buffer for concatenation of KEM key and ECDH shared key */
+ /* the buffer will be hashed and the result is the shared secret */
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ /* allocate space for encrypted KEM key and ECDH pub key */
+ if ((server_blob = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (mlkem768_encap_secret(client_pub, enc.snd, enc.fst.value) != 0)
+ goto out;
+
+ /* generate ECDH key pair, store server pubkey after ciphertext */
+ kexc25519_keygen(server_key, server_pub);
+ if ((r = sshbuf_put(buf, enc.snd, sizeof(enc.snd))) != 0 ||
+ (r = sshbuf_put(server_blob, enc.fst.value, sizeof(enc.fst.value))) != 0 ||
+ (r = sshbuf_put(server_blob, server_pub, sizeof(server_pub))) != 0)
+ goto out;
+ /* append ECDH shared key */
+ client_pub += crypto_kem_mlkem768_PUBLICKEYBYTES;
+ if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 1)) < 0)
+ goto out;
+ if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE);
+ dump_digest("server cipher text:",
+ enc.fst.value, sizeof(enc.fst.value));
+ dump_digest("server kem key:", enc.snd, sizeof(enc.snd));
+ dump_digest("concatenation of KEM key and ECDH shared key:",
+ sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ /* string-encoded hash is resulting shared secret */
+ sshbuf_reset(buf);
+ if ((r = sshbuf_put_string(buf, hash,
+ ssh_digest_bytes(kex->hash_alg))) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ /* success */
+ r = 0;
+ *server_blobp = server_blob;
+ *shared_secretp = buf;
+ server_blob = NULL;
+ buf = NULL;
+ out:
+ explicit_bzero(hash, sizeof(hash));
+ explicit_bzero(server_key, sizeof(server_key));
+ explicit_bzero(&enc, sizeof(enc));
+ sshbuf_free(server_blob);
+ sshbuf_free(buf);
+ return r;
+#endif
}
int
kex_kem_mlkem768x25519_dec(struct kex *kex,
const struct sshbuf *server_blob, struct sshbuf **shared_secretp)
{
+#if 0
struct sshbuf *buf = NULL;
u_char mlkem_key[crypto_kem_mlkem768_BYTES];
const u_char *ciphertext, *server_pub;
@@ -254,6 +487,64 @@ kex_kem_mlkem768x25519_dec(struct kex *kex,
explicit_bzero(mlkem_key, sizeof(mlkem_key));
sshbuf_free(buf);
return r;
+#else
+ struct sshbuf *buf = NULL;
+ const u_char *ciphertext, *server_pub;
+ u_char hash[SSH_DIGEST_MAX_LENGTH];
+ u_char decap[crypto_kem_mlkem768_BYTES];
+ size_t need;
+ int r;
+
+ *shared_secretp = NULL;
+
+ need = crypto_kem_mlkem768_CIPHERTEXTBYTES + CURVE25519_SIZE;
+ if (sshbuf_len(server_blob) != need) {
+ r = SSH_ERR_SIGNATURE_INVALID;
+ goto out;
+ }
+ ciphertext = sshbuf_ptr(server_blob);
+ server_pub = ciphertext + crypto_kem_mlkem768_CIPHERTEXTBYTES;
+ /* hash concatenation of KEM key and ECDH shared key */
+ if ((buf = sshbuf_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+#ifdef DEBUG_KEXECDH
+ dump_digest("server cipher text:", ciphertext, crypto_kem_mlkem768_CIPHERTEXTBYTES);
+ dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE);
+#endif
+ if ((r = mlkem768_decap_secret(kex->mlkem768_client_key, ciphertext, decap)) != 0)
+ goto out;
+ if ((r = sshbuf_put(buf, decap, sizeof(decap))) != 0)
+ goto out;
+ if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub,
+ buf, 1)) < 0)
+ goto out;
+ if ((r = ssh_digest_buffer(kex->hash_alg, buf,
+ hash, sizeof(hash))) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("client kem key:", decap, sizeof(decap));
+ dump_digest("concatenation of KEM key and ECDH shared key:",
+ sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ sshbuf_reset(buf);
+ if ((r = sshbuf_put_string(buf, hash,
+ ssh_digest_bytes(kex->hash_alg))) != 0)
+ goto out;
+#ifdef DEBUG_KEXECDH
+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+ /* success */
+ r = 0;
+ *shared_secretp = buf;
+ buf = NULL;
+ out:
+ explicit_bzero(hash, sizeof(hash));
+ explicit_bzero(decap, sizeof(decap));
+ sshbuf_free(buf);
+ return r;
+#endif
}
#else /* USE_MLKEM768X25519 */
int
--
2.52.0

View file

@ -0,0 +1,25 @@
From edbbdc306c1710dae777ef315a0d2c5f43134d33 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Fri, 16 May 2025 14:53:54 +0200
Subject: [PATCH 45/53] openssh-9.9p2-error_processing
---
ssh-agent.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/ssh-agent.c b/ssh-agent.c
index df241379c..dc246066d 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1346,6 +1346,8 @@ process_add_identity(SocketEntry *e)
if ((r = sshkey_private_deserialize(e->request, &k)) != 0 ||
k == NULL ||
(r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
+ if (!r) /* k == NULL */
+ r = SSH_ERR_INTERNAL_ERROR;
error_fr(r, "parse");
goto out;
}
--
2.52.0

View file

@ -0,0 +1,27 @@
From 0772377e00b13f5afaa1b146ce32d0218e9f0d24 Mon Sep 17 00:00:00 2001
From: Zoltan Fridrich <zfridric@redhat.com>
Date: Wed, 16 Apr 2025 15:11:59 +0200
Subject: [PATCH 46/53] Provide better error for non-supported private keys
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
---
sshkey.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sshkey.c b/sshkey.c
index 394d9b105..eba55ef92 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -3539,6 +3539,9 @@ translate_libcrypto_error(unsigned long pem_err)
return SSH_ERR_LIBCRYPTO_ERROR;
}
case ERR_LIB_ASN1:
+#ifdef ERR_LIB_OSSL_DECODER
+ case ERR_LIB_OSSL_DECODER:
+#endif
return SSH_ERR_INVALID_FORMAT;
}
return SSH_ERR_LIBCRYPTO_ERROR;
--
2.52.0

View file

@ -0,0 +1,86 @@
From d458a65ccac2283563c0fc0962519bb5a9bbd315 Mon Sep 17 00:00:00 2001
From: Zoltan Fridrich <zfridric@redhat.com>
Date: Mon, 5 May 2025 11:52:25 +0200
Subject: [PATCH 47/53] Ignore bad hostkeys in known_hosts file
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
---
hostfile.c | 15 +++++++++++++++
hostfile.h | 1 +
ssh.c | 2 ++
3 files changed, 18 insertions(+)
diff --git a/hostfile.c b/hostfile.c
index 4cec57da5..652d15762 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -63,6 +63,14 @@
#include "hmac.h"
#include "sshbuf.h"
+static int required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
+
+void
+hostfile_set_minimum_rsa_size(int size)
+{
+ required_rsa_size = size;
+}
+
/* XXX hmac is too easy to dictionary attack; use bcrypt? */
static int
@@ -233,6 +241,7 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
struct load_callback_ctx *ctx = (struct load_callback_ctx *)_ctx;
struct hostkeys *hostkeys = ctx->hostkeys;
struct hostkey_entry *tmp;
+ int r = 0;
if (l->status == HKF_STATUS_INVALID) {
/* XXX make this verbose() in the future */
@@ -241,6 +250,12 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
return 0;
}
+ if ((r = sshkey_check_rsa_length(l->key, required_rsa_size)) != 0) {
+ debug2_f("%s:%ld: ignoring hostkey: %s",
+ l->path, l->linenum, ssh_err(r));
+ return 0;
+ }
+
debug3_f("found %skey type %s in file %s:%lu",
l->marker == MRK_NONE ? "" :
(l->marker == MRK_CA ? "ca " : "revoked "),
diff --git a/hostfile.h b/hostfile.h
index a24a4e329..0e9b1a19a 100644
--- a/hostfile.h
+++ b/hostfile.h
@@ -119,5 +119,6 @@ int hostkeys_foreach_file(const char *path, FILE *f,
const char *host, const char *ip, u_int options, u_int note);
void hostfile_create_user_ssh_dir(const char *, int);
+void hostfile_set_minimum_rsa_size(int);
#endif
diff --git a/ssh.c b/ssh.c
index 7d6ba516e..320ac6834 100644
--- a/ssh.c
+++ b/ssh.c
@@ -106,6 +106,7 @@
#include "ssherr.h"
#include "myproposal.h"
#include "utf8.h"
+#include "hostfile.h"
#ifdef ENABLE_PKCS11
#include "ssh-pkcs11.h"
@@ -1409,6 +1410,7 @@ main(int ac, char **av)
options.update_hostkeys = 0;
}
}
+ hostfile_set_minimum_rsa_size(options.required_rsa_size);
if (options.connection_attempts <= 0)
fatal("Invalid number of ConnectionAttempts");
--
2.52.0

View file

@ -0,0 +1,450 @@
From 1cf5e40e14d707de2318747758b012fc7245cb7b Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 10 Jun 2024 23:00:03 +0300
Subject: [PATCH 48/53] support authentication indicators in GSSAPI
RFC 6680 defines a set of GSSAPI extensions to handle attributes
associated with the GSSAPI names. MIT Kerberos and FreeIPA use
name attributes to add information about pre-authentication methods used
to acquire the initial Kerberos ticket. The attribute 'auth-indicators'
may contain list of strings that KDC has associated with the ticket
issuance process.
Use authentication indicators to authorise or deny access to SSH server.
GSSAPIIndicators setting allows to specify a list of possible indicators
that a Kerberos ticket presented must or must not contain. More details
on the syntax are provided in sshd_config(5) man page.
Fixes: https://bugzilla.mindrot.org/show_bug.cgi?id=2696
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
---
configure.ac | 1 +
gss-serv-krb5.c | 64 +++++++++++++++++++++++++++---
gss-serv.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++-
servconf.c | 15 ++++++-
servconf.h | 2 +
ssh-gss.h | 7 ++++
sshd_config.5 | 44 +++++++++++++++++++++
7 files changed, 228 insertions(+), 8 deletions(-)
diff --git a/configure.ac b/configure.ac
index 805be4b5e..9d3b19925 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5050,6 +5050,7 @@ AC_ARG_WITH([kerberos5],
AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h])
AC_CHECK_HEADERS([gssapi_krb5.h gssapi/gssapi_krb5.h])
AC_CHECK_HEADERS([gssapi_generic.h gssapi/gssapi_generic.h])
+ AC_CHECK_HEADERS([gssapi_ext.h gssapi/gssapi_ext.h])
AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1],
[Define this if you want to use libkafs' AFS support])])
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index 03188d9b3..2c786ef14 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -43,6 +43,7 @@
#include "log.h"
#include "misc.h"
#include "servconf.h"
+#include "match.h"
#include "ssh-gss.h"
@@ -87,6 +88,32 @@ ssh_gssapi_krb5_init(void)
return 1;
}
+/* Check if any of the indicators in the Kerberos ticket match
+ * 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
+ */
+
+static int
+ssh_gssapi_check_indicators(ssh_gssapi_client *client, int *matched)
+{
+ int ret;
+ u_int i;
+
+ /* 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) {
+ *matched = i;
+ return ret;
+ }
+ }
+ /* No rule matched */
+ return 0;
+}
+
/* Check if this user is OK to login. This only works with krb5 - other
* GSSAPI mechanisms will need their own.
* Returns true if the user is OK to log in, otherwise returns 0
@@ -193,7 +220,7 @@ static int
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
{
krb5_principal princ;
- int retval;
+ int retval, matched;
const char *errmsg;
int k5login_exists;
@@ -216,17 +243,42 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
if (k5login_exists &&
ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)) {
retval = 1;
- logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
- name, (char *)client->displayname.value);
+ errmsg = "krb5_kuserok";
} else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value,
name, k5login_exists)) {
retval = 1;
- logit("Authorized to %s, krb5 principal %s "
- "(ssh_gssapi_krb5_cmdok)",
- name, (char *)client->displayname.value);
+ errmsg = "ssh_gssapi_krb5_cmdok";
} else
retval = 0;
+ if ((retval == 1) && (options.gss_indicators != NULL)) {
+ /* At this point the configuration enforces presence of indicators
+ * so we drop the authorization result again */
+ retval = 0;
+ if (client->indicators) {
+ matched = -1;
+ retval = ssh_gssapi_check_indicators(client, &matched);
+ if (retval != 0) {
+ retval = (retval == 1);
+ logit("Ticket contains indicator %s, "
+ "krb5 principal %s is %s",
+ client->indicators[matched],
+ (char *)client->displayname.value,
+ retval ? "allowed" : "denied");
+ goto cont;
+ }
+ }
+ if (retval == 0) {
+ logit("GSSAPI authentication indicators enforced "
+ "but not matched. krb5 principal %s denied",
+ (char *)client->displayname.value);
+ }
+ }
+cont:
+ if (retval == 1) {
+ logit("Authorized to %s, krb5 principal %s (%s)",
+ name, (char *)client->displayname.value, errmsg);
+ }
krb5_free_principal(krb_context, princ);
return retval;
}
diff --git a/gss-serv.c b/gss-serv.c
index d2bc03486..be80e17ca 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -54,7 +54,7 @@ extern ServerOptions options;
static ssh_gssapi_client gssapi_client =
{ GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL,
- GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0};
+ GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0, NULL};
ssh_gssapi_mech gssapi_null_mech =
{ NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL};
@@ -296,6 +296,92 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
return GSS_S_COMPLETE;
}
+
+/* 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.
+ * Each indicator is a utf8 string. */
+
+#define AUTH_INDICATORS_TAG "auth-indicators"
+
+/* Privileged (called from accept_secure_ctx) */
+static OM_uint32
+ssh_gssapi_getindicators(Gssctxt *ctx, gss_name_t gss_name, ssh_gssapi_client *client)
+{
+ gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET;
+ gss_buffer_desc value = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc display_value = GSS_C_EMPTY_BUFFER;
+ int is_mechname, authenticated, complete, more;
+ size_t count, i;
+
+ ctx->major = gss_inquire_name(&ctx->minor, gss_name,
+ &is_mechname, NULL, &attrs);
+ if (ctx->major != GSS_S_COMPLETE) {
+ return (ctx->major);
+ }
+
+ if (attrs == GSS_C_NO_BUFFER_SET) {
+ /* No indicators in the ticket */
+ return (0);
+ }
+
+ count = 0;
+ for (i = 0; i < attrs->count; i++) {
+ /* skip anything but auth-indicators */
+ if (((sizeof(AUTH_INDICATORS_TAG) - 1) != attrs->elements[i].length) ||
+ strncmp(AUTH_INDICATORS_TAG,
+ attrs->elements[i].value,
+ sizeof(AUTH_INDICATORS_TAG) - 1) != 0)
+ continue;
+ count++;
+ }
+
+ if (count == 0) {
+ /* No auth-indicators in the ticket */
+ (void) gss_release_buffer_set(&ctx->minor, &attrs);
+ return (0);
+ }
+
+ client->indicators = recallocarray(NULL, 0, count + 1, sizeof(char*));
+ count = 0;
+ 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) ||
+ strncmp(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);
+ if (ctx->major != GSS_S_COMPLETE) {
+ goto out;
+ }
+
+ if ((value.value != NULL) && authenticated) {
+ client->indicators[count] = xmalloc(value.length + 1);
+ memcpy(client->indicators[count], value.value, value.length);
+ client->indicators[count][value.length] = '\0';
+ count++;
+ }
+ }
+ }
+
+out:
+ (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);
+}
+
+
/* Extract the client details from a given context. This can only reliably
* be called once for a context */
@@ -385,6 +471,12 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
}
gss_release_buffer(&ctx->minor, &ename);
+ /* Retrieve authentication indicators, if they exist */
+ if ((ctx->major = ssh_gssapi_getindicators(ctx,
+ ctx->client, client))) {
+ ssh_gssapi_error(ctx);
+ return (ctx->major);
+ }
/* We can't copy this structure, so we just move the pointer to it */
client->creds = ctx->client_creds;
@@ -447,6 +539,7 @@ int
ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
{
OM_uint32 lmin;
+ size_t i;
(void) kex; /* used in privilege separation */
@@ -465,6 +558,14 @@ ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
gss_release_buffer(&lmin, &gssapi_client.displayname);
gss_release_buffer(&lmin, &gssapi_client.exportedname);
gss_release_cred(&lmin, &gssapi_client.creds);
+
+ if (gssapi_client.indicators != NULL) {
+ for(i = 0; gssapi_client.indicators[i] != NULL; i++) {
+ free(gssapi_client.indicators[i]);
+ }
+ free(gssapi_client.indicators);
+ }
+
explicit_bzero(&gssapi_client,
sizeof(ssh_gssapi_client));
return 0;
diff --git a/servconf.c b/servconf.c
index f78615c28..e53e8ea30 100644
--- a/servconf.c
+++ b/servconf.c
@@ -146,6 +146,7 @@ initialize_server_options(ServerOptions *options)
options->gss_strict_acceptor = -1;
options->gss_store_rekey = -1;
options->gss_kex_algorithms = NULL;
+ options->gss_indicators = NULL;
options->use_kuserok = -1;
options->enable_k5users = -1;
options->password_authentication = -1;
@@ -591,7 +592,7 @@ typedef enum {
sPerSourcePenalties, sPerSourcePenaltyExemptList,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
- sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
+ sGssKeyEx, sGssIndicators, sGssKexAlgorithms, sGssStoreRekey,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
@@ -687,6 +688,7 @@ static struct {
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
+ { "gssapiindicators", sGssIndicators, SSHCFG_ALL },
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
@@ -696,6 +698,7 @@ static struct {
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
{ "gssapienablek5users", sUnsupported, SSHCFG_ALL },
+ { "gssapiindicators", sUnsupported, SSHCFG_ALL },
#endif
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
@@ -1722,6 +1725,15 @@ process_server_config_line_depth(ServerOptions *options, char *line,
options->gss_kex_algorithms = xstrdup(arg);
break;
+ case sGssIndicators:
+ arg = argv_next(&ac, &av);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: %s missing argument.",
+ filename, linenum, keyword);
+ if (options->gss_indicators == NULL)
+ options->gss_indicators = xstrdup(arg);
+ break;
+
case sPasswordAuthentication:
intptr = &options->password_authentication;
goto parse_flag;
@@ -3344,6 +3356,7 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms);
+ dump_cfg_string(sGssIndicators, o->gss_indicators);
#endif
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
dump_cfg_fmtint(sKbdInteractiveAuthentication,
diff --git a/servconf.h b/servconf.h
index c08cf6a7a..c7cec5ece 100644
--- a/servconf.h
+++ b/servconf.h
@@ -179,6 +179,7 @@ typedef struct {
char **allow_groups;
u_int num_deny_groups;
char **deny_groups;
+ char *gss_indicators;
u_int num_subsystems;
char **subsystem_name;
@@ -308,6 +309,7 @@ TAILQ_HEAD(include_list, include_item);
M_CP_STROPT(routing_domain); \
M_CP_STROPT(permit_user_env_allowlist); \
M_CP_STROPT(pam_service_name); \
+ M_CP_STROPT(gss_indicators); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
M_CP_STRARRAYOPT(deny_users, num_deny_users); \
diff --git a/ssh-gss.h b/ssh-gss.h
index 329dc9da0..1506719a9 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -34,6 +34,12 @@
#include <gssapi/gssapi.h>
#endif
+#ifdef HAVE_GSSAPI_EXT_H
+#include <gssapi_ext.h>
+#elif defined(HAVE_GSSAPI_GSSAPI_EXT_H)
+#include <gssapi/gssapi_ext.h>
+#endif
+
#ifdef KRB5
# ifndef HEIMDAL
# ifdef HAVE_GSSAPI_GENERIC_H
@@ -112,6 +118,7 @@ typedef struct {
ssh_gssapi_ccache store;
int used;
int updated;
+ char **indicators; /* auth indicators */
} ssh_gssapi_client;
typedef struct ssh_gssapi_mech_struct {
diff --git a/sshd_config.5 b/sshd_config.5
index c172d5aab..676d6d4d2 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -785,6 +785,50 @@ gss-nistp256-sha256-
gss-curve25519-sha256-
.Ed
This option only applies to connections using GSSAPI.
+.It Cm GSSAPIIndicators
+Specifies whether to accept or deny GSSAPI authenticated access if Kerberos
+mechanism is used and Kerberos ticket contains a particular set of
+authentication indicators. The values can be specified as a comma-separated list
+.Cm [!]name1,[!]name2,... .
+When indicator's name is prefixed with !, the authentication indicator 'name'
+will deny access to the system. Otherwise, one of non-negated authentication
+indicators must be present in the Kerberos ticket to allow access. If
+.Cm GSSAPIIndicators
+is defined, a Kerberos ticket that has indicators but does not match the
+policy will get denial. If at least one indicator is configured, whether for
+access or denial, tickets without authentication indicators will be explicitly
+rejected.
+.Pp
+By default systems using MIT Kerberos 1.17 or later will not assign any
+indicators. SPAKE and PKINIT methods add authentication indicators
+to all successful authentications. The SPAKE pre-authentication method is
+preferred over an encrypted timestamp pre-authentication when passwords used to
+authenticate user principals. Kerberos KDCs built with Heimdal Kerberos
+(including Samba AD DC built with Heimdal) do not add authentication
+indicators. However, OpenSSH built against Heimdal Kerberos library is able to
+inquire authentication indicators and thus can be used to check for their presence.
+.Pp
+Indicator name is case-sensitive and depends on the configuration of a
+particular Kerberos deployment. Indicators available in MIT Kerberos and
+FreeIPA environments:
+.Pp
+.Bl -tag -width XXXX -offset indent -compact
+.It Cm hardened
+SPAKE or encrypted timestamp pre-authentication mechanisms in MIT Kerberos and FreeIPA
+.It Cm pkinit
+smartcard or PKCS11 token-based pre-authentication in MIT Kerberos and FreeIPA
+.It Cm radius
+pre-authentication based on a RADIUS server in MIT Kerberos and FreeIPA
+.It Cm otp
+TOTP/HOTP-based two-factor pre-authentication in FreeIPA
+.It Cm idp
+OAuth2-based pre-authentication in FreeIPA using an external identity provider
+and device authorization grant flow
+.It Cm passkey
+FIDO2-based pre-authentication in FreeIPA, using FIDO2 USB and NFC tokens
+.El
+.Pp
+The default is to not use GSSAPI authentication indicators for access decisions.
.It Cm HostbasedAcceptedAlgorithms
The default is handled system-wide by
.Xr crypto-policies 7 .
--
2.52.0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,139 @@
From 71190d3d862113d97708a42b4a7daa7aa3c4e0ec Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Fri, 5 Dec 2025 14:55:38 +0100
Subject: [PATCH 50/53] Provide a way to disable GSSAPIDelegateCredentials
server-side
---
gss-serv.c | 5 +++++
servconf.c | 13 ++++++++++++-
servconf.h | 1 +
sshd_config.0 | 3 +++
sshd_config.5 | 3 +++
5 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/gss-serv.c b/gss-serv.c
index be80e17ca..165484db0 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -509,6 +509,11 @@ ssh_gssapi_cleanup_creds(void)
int
ssh_gssapi_storecreds(void)
{
+ if (options.gss_deleg_creds == 0) {
+ debug_f("delegate credential is disabled, doing nothing");
+ return 0;
+ }
+
if (gssapi_client.mech && gssapi_client.mech->storecreds) {
return (*gssapi_client.mech->storecreds)(&gssapi_client);
} else
diff --git a/servconf.c b/servconf.c
index e53e8ea30..fb1d150cd 100644
--- a/servconf.c
+++ b/servconf.c
@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions *options)
options->gss_authentication=-1;
options->gss_keyex = -1;
options->gss_cleanup_creds = -1;
+ options->gss_deleg_creds = -1;
options->gss_strict_acceptor = -1;
options->gss_store_rekey = -1;
options->gss_kex_algorithms = NULL;
@@ -396,6 +397,8 @@ fill_default_server_options(ServerOptions *options)
options->gss_keyex = 0;
if (options->gss_cleanup_creds == -1)
options->gss_cleanup_creds = 1;
+ if (options->gss_deleg_creds == -1)
+ options->gss_deleg_creds = 1;
if (options->gss_strict_acceptor == -1)
options->gss_strict_acceptor = 1;
if (options->gss_store_rekey == -1)
@@ -591,7 +594,8 @@ typedef enum {
sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
sPerSourcePenalties, sPerSourcePenaltyExemptList,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
- sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
+ sGssAuthentication, sGssCleanupCreds, sGssDelegateCreds,
+ sGssEnablek5users, sGssStrictAcceptor,
sGssKeyEx, sGssIndicators, sGssKexAlgorithms, sGssStoreRekey,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
@@ -683,6 +687,7 @@ static struct {
{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
{ "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
+ { "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
@@ -693,6 +698,7 @@ static struct {
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
+ { "gssapidelegatecredentials", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
@@ -1705,6 +1711,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
intptr = &options->gss_cleanup_creds;
goto parse_flag;
+ case sGssDelegateCreds:
+ intptr = &options->gss_deleg_creds;
+ goto parse_flag;
+
case sGssStrictAcceptor:
intptr = &options->gss_strict_acceptor;
goto parse_flag;
@@ -3352,6 +3362,7 @@ dump_config(ServerOptions *o)
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
+ dump_cfg_fmtint(sGssDelegateCreds, o->gss_deleg_creds);
dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
diff --git a/servconf.h b/servconf.h
index c7cec5ece..9b1a73b8d 100644
--- a/servconf.h
+++ b/servconf.h
@@ -156,6 +156,7 @@ typedef struct {
int gss_authentication; /* If true, permit GSSAPI authentication */
int gss_keyex; /* If true, permit GSSAPI key exchange */
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
+ int gss_deleg_creds; /* If true, accept delegated GSS credentials */
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */
int gss_store_rekey;
char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */
diff --git a/sshd_config.0 b/sshd_config.0
index 8c5217c0b..cda9c9182 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -453,6 +453,9 @@ DESCRIPTION
Specifies whether to automatically destroy the user's credentials
cache on logout. The default is yes.
+ GSSAPIDelegateCredentials
+ Accept delegated credentials on the server side. The default is yes.
+
GSSAPIStrictAcceptorCheck
Determines whether to be strict about the identity of the GSSAPI
acceptor a client authenticates against. If set to yes then the
diff --git a/sshd_config.5 b/sshd_config.5
index 676d6d4d2..4ae4bebee 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -733,6 +733,9 @@ Specifies whether to automatically destroy the user's credentials cache
on logout.
The default is
.Cm yes .
+.It Cm GSSAPIDelegateCredentials
+Accept delegated credentials on the server side. The default is
+.CM yes .
.It Cm GSSAPIEnablek5users
Specifies whether to look at .k5users file for GSSAPI authentication
access control. Further details are described in
--
2.52.0

View file

@ -1,18 +1,22 @@
diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c
--- openssh-7.4p1/channels.c.x11max 2016-12-23 15:46:32.071506625 +0100
+++ openssh-7.4p1/channels.c 2016-12-23 15:46:32.139506636 +0100
@@ -152,8 +152,8 @@ static int all_opens_permitted = 0;
#define FWD_PERMIT_ANY_HOST "*"
/* -- X11 forwarding */
-/* Maximum number of fake X11 displays to try. */
-#define MAX_DISPLAYS 1000
+/* Minimum port number for X11 forwarding */
+#define X11_PORT_MIN 6000
/* Per-channel callback for pre/post IO actions */
typedef void chan_fn(struct ssh *, Channel *c);
@@ -4228,7 +4228,7 @@ channel_send_window_changes(void)
From 763c65f6f349a7bab344a58991246891700e4fa0 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Fri, 12 Dec 2025 15:35:14 +0100
Subject: [PATCH 51/53] openssh-7.3p1-x11-max-displays
---
channels.c | 9 ++++++---
channels.h | 2 +-
servconf.c | 12 +++++++++++-
servconf.h | 2 ++
session.c | 5 +++--
sshd_config.5 | 7 +++++++
6 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/channels.c b/channels.c
index 26ed9945f..c26380e25 100644
--- a/channels.c
+++ b/channels.c
@@ -5067,7 +5067,7 @@ rdynamic_connect_finish(struct ssh *ssh, Channel *c)
*/
int
x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
@ -21,66 +25,33 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c
u_int *display_numberp, int **chanids)
{
Channel *nc = NULL;
@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_
if (chanids == NULL)
@@ -5080,8 +5080,11 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS)
return -1;
+ /* Try to bind ports starting at 6000+X11DisplayOffset */
+ x11_max_displays = x11_max_displays + x11_display_offset;
+
for (display_number = x11_display_offset;
- display_number < MAX_DISPLAYS;
- display_number < x11_display_offset + MAX_DISPLAYS;
+ display_number < x11_max_displays;
display_number++) {
- port = 6000 + display_number;
+ port = X11_PORT_MIN + display_number;
+ if (port < X11_PORT_MIN) /* overflow */
+ break;
port = X11_BASE_PORT + display_number;
memset(&hints, 0, sizeof(hints));
hints.ai_family = ssh->chanctxt->IPv4or6;
hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
@@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_
@@ -5146,7 +5149,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
if (num_socks > 0)
break;
}
- if (display_number >= MAX_DISPLAYS) {
+ if (display_number >= x11_max_displays || port < X11_PORT_MIN ) {
- if (display_number >= x11_display_offset + MAX_DISPLAYS) {
+ if (display_number >= x11_max_displays || port < X11_BASE_PORT ) {
error("Failed to allocate internet-domain X11 display socket.");
return -1;
}
@@ -4441,7 +4447,7 @@ x11_connect_display(void)
memset(&hints, 0, sizeof(hints));
hints.ai_family = ssh->chanctxt->IPv4or6;
hints.ai_socktype = SOCK_STREAM;
- snprintf(strport, sizeof strport, "%u", 6000 + display_number);
+ snprintf(strport, sizeof strport, "%u", X11_PORT_MIN + display_number);
if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
error("%.100s: unknown host. (%s)", buf,
ssh_gai_strerror(gaierr));
@@ -4457,7 +4463,7 @@ x11_connect_display(void)
/* Connect it to the display. */
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
debug2("connect %.100s port %u: %.100s", buf,
- 6000 + display_number, strerror(errno));
+ X11_PORT_MIN + display_number, strerror(errno));
close(sock);
continue;
}
@@ -4466,8 +4472,8 @@ x11_connect_display(void)
}
freeaddrinfo(aitop);
if (!ai) {
- error("connect %.100s port %u: %.100s", buf,
- 6000 + display_number, strerror(errno));
+ error("connect %.100s port %u: %.100s", buf,
+ X11_PORT_MIN + display_number, strerror(errno));
return -1;
}
set_nodelay(sock);
diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h
--- openssh-7.4p1/channels.h.x11max 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/channels.h 2016-12-23 15:46:32.139506636 +0100
@@ -293,7 +293,7 @@ int permitopen_port(const char *);
diff --git a/channels.h b/channels.h
index 7456541f8..754bd98ee 100644
--- a/channels.h
+++ b/channels.h
@@ -389,7 +389,7 @@ int permitopen_port(const char *);
void channel_set_x11_refuse_time(struct ssh *, time_t);
int x11_connect_display(struct ssh *);
@ -88,11 +59,12 @@ diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h
+int x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **);
void x11_request_forwarding_with_spoofing(struct ssh *, int,
const char *, const char *, const char *, int);
diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
--- openssh-7.4p1/servconf.c.x11max 2016-12-23 15:46:32.133506635 +0100
+++ openssh-7.4p1/servconf.c 2016-12-23 15:47:27.320519121 +0100
@@ -95,6 +95,7 @@ initialize_server_options(ServerOptions
int x11_channel_used_recently(struct ssh *ssh);
diff --git a/servconf.c b/servconf.c
index fb1d150cd..956205f6d 100644
--- a/servconf.c
+++ b/servconf.c
@@ -118,6 +118,7 @@ initialize_server_options(ServerOptions *options)
options->print_lastlog = -1;
options->x11_forwarding = -1;
options->x11_display_offset = -1;
@ -100,7 +72,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
options->x11_use_localhost = -1;
options->permit_tty = -1;
options->permit_user_rc = -1;
@@ -243,6 +244,8 @@ fill_default_server_options(ServerOption
@@ -357,6 +358,8 @@ fill_default_server_options(ServerOptions *options)
options->x11_forwarding = 0;
if (options->x11_display_offset == -1)
options->x11_display_offset = 10;
@ -109,16 +81,16 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
if (options->x11_use_localhost == -1)
options->x11_use_localhost = 1;
if (options->xauth_location == NULL)
@@ -419,7 +422,7 @@ typedef enum {
sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
@@ -582,7 +585,7 @@ typedef enum {
sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
- sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
+ sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost,
sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
@@ -540,6 +543,7 @@ static struct {
@@ -725,6 +728,7 @@ static struct {
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
@ -126,7 +98,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
@@ -1316,6 +1320,10 @@ process_server_config_line(ServerOptions
@@ -1775,6 +1779,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
*intptr = value;
break;
@ -137,7 +109,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
case sX11UseLocalhost:
intptr = &options->x11_use_localhost;
goto parse_flag;
@@ -2063,6 +2071,7 @@ copy_set_server_options(ServerOptions *d
@@ -3037,6 +3045,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
M_CP_INTOPT(x11_display_offset);
M_CP_INTOPT(x11_forwarding);
@ -145,7 +117,7 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
M_CP_INTOPT(x11_use_localhost);
M_CP_INTOPT(permit_tty);
M_CP_INTOPT(permit_user_rc);
@@ -2315,6 +2324,7 @@ dump_config(ServerOptions *o)
@@ -3332,6 +3341,7 @@ dump_config(ServerOptions *o)
#endif
dump_cfg_int(sLoginGraceTime, o->login_grace_time);
dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
@ -153,10 +125,11 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
dump_cfg_int(sMaxAuthTries, o->max_authtries);
dump_cfg_int(sMaxSessions, o->max_sessions);
dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h
--- openssh-7.4p1/servconf.h.x11max 2016-12-23 15:46:32.133506635 +0100
+++ openssh-7.4p1/servconf.h 2016-12-23 15:46:32.140506636 +0100
@@ -55,6 +55,7 @@
diff --git a/servconf.h b/servconf.h
index 9b1a73b8d..6bfdf6305 100644
--- a/servconf.h
+++ b/servconf.h
@@ -38,6 +38,7 @@
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
@ -164,7 +137,7 @@ diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h
/* Magic name for internal sftp-server */
#define INTERNAL_SFTP_NAME "internal-sftp"
@@ -85,6 +86,7 @@ typedef struct {
@@ -114,6 +115,7 @@ typedef struct {
int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */
int x11_display_offset; /* What DISPLAY number to start
* searching at */
@ -172,13 +145,14 @@ diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h
int x11_use_localhost; /* If true, use localhost for fake X11 server. */
char *xauth_location; /* Location of xauth program */
int permit_tty; /* If false, deny pty allocation */
diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c
--- openssh-7.4p1/session.c.x11max 2016-12-23 15:46:32.136506636 +0100
+++ openssh-7.4p1/session.c 2016-12-23 15:46:32.141506636 +0100
@@ -2518,8 +2518,9 @@ session_setup_x11fwd(Session *s)
diff --git a/session.c b/session.c
index 80282dfd8..e53d044a0 100644
--- a/session.c
+++ b/session.c
@@ -2681,8 +2681,9 @@ session_setup_x11fwd(struct ssh *ssh, Session *s)
return 0;
}
if (x11_create_display_inet(ssh, options.x11_display_offset,
if (x11_create_display_inet(ssh, options.x11_display_offset,
- options.x11_use_localhost, s->single_connection,
- &s->display_number, &s->x11_chanids) == -1) {
+ options.x11_use_localhost, options.x11_max_displays,
@ -187,10 +161,11 @@ diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c
debug("x11_create_display_inet failed.");
return 0;
}
diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5
--- openssh-7.4p1/sshd_config.5.x11max 2016-12-23 15:46:32.134506635 +0100
+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:46:32.141506636 +0100
@@ -1133,6 +1133,7 @@ Available keywords are
diff --git a/sshd_config.5 b/sshd_config.5
index 4ae4bebee..3dbce55fc 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1403,6 +1403,7 @@ Available keywords are
.Cm TrustedUserCAKeys ,
.Cm UnusedConnectionTimeout ,
.Cm X11DisplayOffset ,
@ -198,7 +173,7 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5
.Cm X11Forwarding
and
.Cm X11UseLocalhost .
@@ -1566,6 +1567,12 @@ Specifies the first display number avail
@@ -2112,6 +2113,12 @@ Specifies the first display number available for
X11 forwarding.
This prevents sshd from interfering with real X11 servers.
The default is 10.
@ -211,3 +186,6 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5
.It Cm X11Forwarding
Specifies whether X11 forwarding is permitted.
The argument must be
--
2.52.0

View file

@ -0,0 +1,229 @@
From aecc5861e1cf7094a32f893ae4bfd8409b77e5cd Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Fri, 12 Dec 2025 14:25:41 +0100
Subject: [PATCH 53/53] openssh-6.7p1-coverity
---
auth-krb5.c | 2 ++
gss-genr.c | 3 ++-
krl.c | 3 +++
loginrec.c | 2 ++
misc.c | 3 +++
monitor.c | 4 ++--
openbsd-compat/bindresvport.c | 2 +-
openbsd-compat/bsd-pselect.c | 8 ++++----
readconf.c | 1 +
servconf.c | 5 +++--
serverloop.c | 2 +-
11 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/auth-krb5.c b/auth-krb5.c
index b9c261a24..a37be93c3 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -427,6 +427,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm
umask(old_umask);
if (tmpfd == -1) {
logit("mkstemp(): %.100s", strerror(oerrno));
+ free(ccname);
return oerrno;
}
@@ -434,6 +435,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm
oerrno = errno;
logit("fchmod(): %.100s", strerror(oerrno));
close(tmpfd);
+ free(ccname);
return oerrno;
}
/* make sure the KRB5CCNAME is set for non-standard location */
diff --git a/gss-genr.c b/gss-genr.c
index f2d6f59e5..91602e045 100644
--- a/gss-genr.c
+++ b/gss-genr.c
@@ -178,8 +178,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
enclen = __b64_ntop(digest,
ssh_digest_bytes(SSH_DIGEST_MD5), encoded,
ssh_digest_bytes(SSH_DIGEST_MD5) * 2);
-
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
cp = strncpy(s, kex, strlen(kex));
+#pragma GCC diagnostic pop
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (sshbuf_len(buf) != 0 &&
diff --git a/krl.c b/krl.c
index bea5b1b98..4dd8a24a9 100644
--- a/krl.c
+++ b/krl.c
@@ -1205,6 +1205,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
return r;
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
free(rb.blob);
+ rb.blob = NULL; /* make coverity happy */
if (erb != NULL) {
KRL_DBG(("revoked by key SHA1"));
return SSH_ERR_KEY_REVOKED;
@@ -1215,6 +1216,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
return r;
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb);
free(rb.blob);
+ rb.blob = NULL; /* make coverity happy */
if (erb != NULL) {
KRL_DBG(("revoked by key SHA256"));
return SSH_ERR_KEY_REVOKED;
@@ -1226,6 +1228,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
return r;
erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
free(rb.blob);
+ rb.blob = NULL; /* make coverity happy */
if (erb != NULL) {
KRL_DBG(("revoked by explicit key"));
return SSH_ERR_KEY_REVOKED;
diff --git a/loginrec.c b/loginrec.c
index 7d1c9dd43..a017e173b 100644
--- a/loginrec.c
+++ b/loginrec.c
@@ -677,9 +677,11 @@ construct_utmp(struct logininfo *li,
*/
/* Use strncpy because we don't necessarily want null termination */
+ /* coverity[buffer_size_warning : FALSE] */
strncpy(ut->ut_name, li->username,
MIN_SIZEOF(ut->ut_name, li->username));
# ifdef HAVE_HOST_IN_UTMP
+ /* coverity[buffer_size_warning : FALSE] */
strncpy(ut->ut_host, li->hostname,
MIN_SIZEOF(ut->ut_host, li->hostname));
# endif
diff --git a/misc.c b/misc.c
index 2fd14159d..d4c4e4164 100644
--- a/misc.c
+++ b/misc.c
@@ -1573,6 +1573,8 @@ sanitise_stdfd(void)
}
if (nullfd > STDERR_FILENO)
close(nullfd);
+ /* coverity[leaked_handle : FALSE]*/
+ /* coverity[leaked_handle : FALSE]*/
}
char *
@@ -2773,6 +2775,7 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr)
}
if (devnull > STDERR_FILENO)
close(devnull);
+ /* coverity[leaked_handle : FALSE]*/
return ret;
}
diff --git a/monitor.c b/monitor.c
index 2f154a3d7..f959e0124 100644
--- a/monitor.c
+++ b/monitor.c
@@ -405,7 +405,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
mm_get_keystate(ssh, pmonitor);
/* Drain any buffered messages from the child */
- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
;
/* Wait for the child's exit status */
@@ -1819,7 +1819,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m)
s->ptymaster = s->ptyfd;
debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd);
-
+ /* coverity[leaked_handle : FALSE] */
return (0);
error:
diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c
index 346c7fe56..f42792fde 100644
--- a/openbsd-compat/bindresvport.c
+++ b/openbsd-compat/bindresvport.c
@@ -59,7 +59,7 @@ bindresvport_sa(int sd, struct sockaddr *sa)
struct sockaddr_in6 *in6;
u_int16_t *portp;
u_int16_t port;
- socklen_t salen;
+ socklen_t salen = sizeof(struct sockaddr_storage);
int i;
if (sa == NULL) {
diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c
index 26bdc3e08..8e2939b95 100644
--- a/openbsd-compat/bsd-pselect.c
+++ b/openbsd-compat/bsd-pselect.c
@@ -85,13 +85,13 @@ pselect_notify_setup(void)
static void
pselect_notify_parent(void)
{
- if (notify_pipe[1] != -1)
+ if (notify_pipe[1] >= 0)
(void)write(notify_pipe[1], "", 1);
}
static void
pselect_notify_prepare(fd_set *readset)
{
- if (notify_pipe[0] != -1)
+ if (notify_pipe[0] >= 0)
FD_SET(notify_pipe[0], readset);
}
static void
@@ -99,8 +99,8 @@ pselect_notify_done(fd_set *readset)
{
char c;
- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) {
- while (read(notify_pipe[0], &c, 1) != -1)
+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) {
+ while (read(notify_pipe[0], &c, 1) >= 0)
debug2_f("reading");
FD_CLR(notify_pipe[0], readset);
}
diff --git a/readconf.c b/readconf.c
index b6ad47b49..75e1c953c 100644
--- a/readconf.c
+++ b/readconf.c
@@ -2170,6 +2170,7 @@ parse_pubkey_algos:
} else if (r != 0) {
error("%.200s line %d: glob failed for %s.",
filename, linenum, arg2);
+ free(arg2);
goto out;
}
free(arg2);
diff --git a/servconf.c b/servconf.c
index 956205f6d..1093dcbac 100644
--- a/servconf.c
+++ b/servconf.c
@@ -2307,8 +2307,9 @@ process_server_config_line_depth(ServerOptions *options, char *line,
if (*activep && *charptr == NULL) {
*charptr = tilde_expand_filename(arg, getuid());
/* increase optional counter */
- if (intptr != NULL)
- *intptr = *intptr + 1;
+ /* DEAD CODE intptr is still NULL ;)
+ if (intptr != NULL)
+ *intptr = *intptr + 1; */
}
break;
diff --git a/serverloop.c b/serverloop.c
index 55411a6b4..acc721cd1 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -533,7 +533,7 @@ server_request_tun(struct ssh *ssh)
debug_f("invalid tun");
goto done;
}
- if (auth_opts->force_tun_device != -1) {
+ if (auth_opts->force_tun_device >= 0) {
if (tun != SSH_TUNID_ANY &&
auth_opts->force_tun_device != (int)tun)
goto done;
--
2.52.0

View file

@ -1,14 +0,0 @@
diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c
--- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200
+++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200
@@ -715,6 +715,9 @@ main(int argc, char **argv)
if (maxfd > fdlim_get(0))
fdlim_set(maxfd);
fdcon = xcalloc(maxfd, sizeof(con));
+
+ signal(SIGPIPE, SIG_IGN);
+
read_wait = xcalloc(maxfd, sizeof(struct pollfd));
for (j = 0; j < maxfd; j++)
read_wait[j].fd = -1;

View file

@ -1,16 +0,0 @@
diff --git a/scp.c b/scp.c
index d98fa67..25d347b 100644
--- a/scp.c
+++ b/scp.c
@@ -638,7 +638,10 @@ toremote(char *targ, int argc, char **argv)
addargs(&alist, "%s", ssh_program);
addargs(&alist, "-x");
addargs(&alist, "-oClearAllForwardings=yes");
- addargs(&alist, "-n");
+ if (isatty(fileno(stdin)))
+ addargs(&alist, "-t");
+ else
+ addargs(&alist, "-n");
for (j = 0; j < remote_remote_args.num; j++) {
addargs(&alist, "%s",
remote_remote_args.list[j]);

View file

@ -1,14 +0,0 @@
--- a/scp.c
+++ a/scp.c
@@ -1084,6 +1084,10 @@ sink(int argc, char **argv)
free(vect[0]);
continue;
}
+ if (buf[0] == 'C' && ! exists && np[strlen(np)-1] == '/') {
+ errno = ENOTDIR;
+ goto bad;
+ }
omode = mode;
mode |= S_IWUSR;
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) {
--

View file

@ -1,133 +0,0 @@
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
index 8f32464..18a2ca4 100644
--- a/openbsd-compat/port-linux-sshd.c
+++ b/openbsd-compat/port-linux-sshd.c
@@ -32,6 +32,7 @@
#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */
#include "servconf.h"
#include "port-linux.h"
+#include "misc.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
@@ -445,7 +446,7 @@ sshd_selinux_setup_exec_context(char *pwname)
void
sshd_selinux_copy_context(void)
{
- security_context_t *ctx;
+ char *ctx;
if (!sshd_selinux_enabled())
return;
@@ -461,6 +462,72 @@ sshd_selinux_copy_context(void)
}
}
+void
+sshd_selinux_change_privsep_preauth_context(void)
+{
+ int len;
+ char line[1024], *preauth_context = NULL, *cp, *arg;
+ const char *contexts_path;
+ FILE *contexts_file;
+ struct stat sb;
+
+ contexts_path = selinux_openssh_contexts_path();
+ if (contexts_path == NULL) {
+ debug3_f("Failed to get the path to SELinux context");
+ return;
+ }
+
+ if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
+ debug_f("Failed to open SELinux context file");
+ return;
+ }
+
+ if (fstat(fileno(contexts_file), &sb) != 0 ||
+ sb.st_uid != 0 || (sb.st_mode & 022) != 0) {
+ logit_f("SELinux context file needs to be owned by root"
+ " and not writable by anyone else");
+ fclose(contexts_file);
+ return;
+ }
+
+ while (fgets(line, sizeof(line), contexts_file)) {
+ /* Strip trailing whitespace */
+ for (len = strlen(line) - 1; len > 0; len--) {
+ if (strchr(" \t\r\n", line[len]) == NULL)
+ break;
+ line[len] = '\0';
+ }
+
+ if (line[0] == '\0')
+ continue;
+
+ cp = line;
+ arg = strdelim(&cp);
+ if (arg && *arg == '\0')
+ arg = strdelim(&cp);
+
+ if (arg && strcmp(arg, "privsep_preauth") == 0) {
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\0') {
+ debug_f("privsep_preauth is empty");
+ fclose(contexts_file);
+ return;
+ }
+ preauth_context = xstrdup(arg);
+ }
+ }
+ fclose(contexts_file);
+
+ if (preauth_context == NULL) {
+ debug_f("Unable to find 'privsep_preauth' option in"
+ " SELinux context file");
+ return;
+ }
+
+ ssh_selinux_change_context(preauth_context);
+ free(preauth_context);
+}
+
#endif
#endif
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index 22ea8ef..1fc963d 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname)
strlcpy(newctx + len, newname, newlen - len);
if ((cx = index(cx + 1, ':')))
strlcat(newctx, cx, newlen);
- debug3("%s: setting context from '%s' to '%s'", __func__,
+ debug_f("setting context from '%s' to '%s'",
oldctx, newctx);
if (setcon(newctx) < 0)
do_log2(log_level, "%s: setcon %s from %s failed with %s",
__func__, newctx, oldctx, strerror(errno));
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index cb51f99..8b7cda2 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -29,6 +29,7 @@ int sshd_selinux_enabled(void);
void sshd_selinux_copy_context(void);
void sshd_selinux_setup_exec_context(char *);
int sshd_selinux_setup_env_variables(void);
+void sshd_selinux_change_privsep_preauth_context(void);
#endif
#ifdef LINUX_OOM_ADJUST
diff --git a/sshd.c b/sshd.c
index 2871fe9..39b9c08 100644
--- a/sshd.c
+++ b/sshd.c
@@ -629,7 +629,7 @@ privsep_preauth_child(void)
demote_sensitive_data();
#ifdef WITH_SELINUX
- ssh_selinux_change_context("sshd_net_t");
+ sshd_selinux_change_privsep_preauth_context();
#endif
/* Demote the child */

View file

@ -1,121 +0,0 @@
diff -up openssh-7.4p1/openbsd-compat/port-linux.h.privsep-selinux openssh-7.4p1/openbsd-compat/port-linux.h
--- openssh-7.4p1/openbsd-compat/port-linux.h.privsep-selinux 2016-12-23 18:58:52.972122201 +0100
+++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 18:58:52.974122201 +0100
@@ -23,6 +23,7 @@ void ssh_selinux_setup_pty(char *, const
void ssh_selinux_change_context(const char *);
void ssh_selinux_setfscreatecon(const char *);
+void sshd_selinux_copy_context(void);
void sshd_selinux_setup_exec_context(char *);
#endif
diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh-7.4p1/openbsd-compat/port-linux-sshd.c
--- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux 2016-12-23 18:58:52.973122201 +0100
+++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2016-12-23 18:58:52.974122201 +0100
@@ -419,6 +419,28 @@ sshd_selinux_setup_exec_context(char *pw
debug3_f("done");
}
+void
+sshd_selinux_copy_context(void)
+{
+ security_context_t *ctx;
+
+ if (!ssh_selinux_enabled())
+ return;
+
+ if (getexeccon((security_context_t *)&ctx) != 0) {
+ logit_f("getexeccon failed with %s", strerror(errno));
+ return;
+ }
+ if (ctx != NULL) {
+ /* unset exec context before we will lose this capabililty */
+ if (setexeccon(NULL) != 0)
+ fatal_f("setexeccon failed with %s", strerror(errno));
+ if (setcon(ctx) != 0)
+ fatal_f("setcon failed with %s", strerror(errno));
+ freecon(ctx);
+ }
+}
+
#endif
#endif
diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c
--- openssh-7.4p1/session.c.privsep-selinux 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/session.c 2016-12-23 18:58:52.974122201 +0100
@@ -1331,7 +1331,7 @@ do_setusercontext(struct passwd *pw)
platform_setusercontext(pw);
- if (platform_privileged_uidswap()) {
+ 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) {
@@ -1361,6 +1361,9 @@ do_setusercontext(struct passwd *pw)
(unsigned long long)pw->pw_uid);
chroot_path = percent_expand(tmp, "h", pw->pw_dir,
"u", pw->pw_name, "U", uidstr, (char *)NULL);
+#ifdef WITH_SELINUX
+ sshd_selinux_copy_context();
+#endif
safely_chroot(chroot_path, pw->pw_uid);
free(tmp);
free(chroot_path);
@@ -1396,6 +1399,11 @@ do_setusercontext(struct passwd *pw)
/* Permanently switch to the desired uid. */
permanently_set_uid(pw);
#endif
+
+#ifdef WITH_SELINUX
+ if (in_chroot == 0)
+ sshd_selinux_copy_context();
+#endif
} else if (options.chroot_directory != NULL &&
strcasecmp(options.chroot_directory, "none") != 0) {
fatal("server lacks privileges to chroot to ChrootDirectory");
@@ -1413,9 +1421,6 @@ do_pwchange(Session *s)
if (s->ttyfd != -1) {
fprintf(stderr,
"You must change your password now and login again!\n");
-#ifdef WITH_SELINUX
- setexeccon(NULL);
-#endif
#ifdef PASSWD_NEEDS_USERNAME
execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
(char *)NULL);
@@ -1625,9 +1630,6 @@ do_child(Session *s, const char *command
argv[i] = NULL;
optind = optreset = 1;
__progname = argv[0];
-#ifdef WITH_SELINUX
- ssh_selinux_change_context("sftpd_t");
-#endif
exit(sftp_server_main(i, argv, s->pw));
}
diff -up openssh-7.4p1/sshd.c.privsep-selinux openssh-7.4p1/sshd.c
--- openssh-7.4p1/sshd.c.privsep-selinux 2016-12-23 18:58:52.973122201 +0100
+++ openssh-7.4p1/sshd.c 2016-12-23 18:59:13.808124269 +0100
@@ -540,6 +540,10 @@ privsep_preauth_child(void)
/* Demote the private keys to public keys. */
demote_sensitive_data();
+#ifdef WITH_SELINUX
+ ssh_selinux_change_context("sshd_net_t");
+#endif
+
/* Demote the child */
if (privsep_chroot) {
/* Change our root directory */
@@ -633,6 +637,9 @@ privsep_postauth(Authctxt *authctxt)
{
#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

View file

@ -1,351 +0,0 @@
diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c
--- openssh-8.5p1/auth-krb5.c.coverity 2021-03-24 12:03:33.724967756 +0100
+++ openssh-8.5p1/auth-krb5.c 2021-03-24 12:03:33.782968159 +0100
@@ -426,6 +426,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx,
umask(old_umask);
if (tmpfd == -1) {
logit("mkstemp(): %.100s", strerror(oerrno));
+ free(ccname);
return oerrno;
}
@@ -433,6 +434,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx,
oerrno = errno;
logit("fchmod(): %.100s", strerror(oerrno));
close(tmpfd);
+ free(ccname);
return oerrno;
}
/* make sure the KRB5CCNAME is set for non-standard location */
diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c
--- openssh-8.5p1/auth-options.c.coverity 2021-03-02 11:31:47.000000000 +0100
+++ openssh-8.5p1/auth-options.c 2021-03-24 12:03:33.782968159 +0100
@@ -706,6 +708,7 @@ serialise_array(struct sshbuf *m, char *
return r;
}
/* success */
+ sshbuf_free(b);
return 0;
}
diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c
--- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100
+++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100
@@ -167,8 +167,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
enclen = __b64_ntop(digest,
ssh_digest_bytes(SSH_DIGEST_MD5), encoded,
ssh_digest_bytes(SSH_DIGEST_MD5) * 2);
-
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
cp = strncpy(s, kex, strlen(kex));
+#pragma pop
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (sshbuf_len(buf) != 0 &&
diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c
--- openssh-8.5p1/krl.c.coverity 2021-03-02 11:31:47.000000000 +0100
+++ openssh-8.5p1/krl.c 2021-03-24 12:03:33.783968166 +0100
@@ -1209,6 +1209,7 @@ ssh_krl_from_blob(struct sshbuf *buf, st
sshkey_free(key);
sshbuf_free(copy);
sshbuf_free(sect);
+ /* coverity[leaked_storage : FALSE] */
return r;
}
@@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons
return r;
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
free(rb.blob);
+ rb.blob = NULL; /* make coverity happy */
if (erb != NULL) {
KRL_DBG(("revoked by key SHA1"));
return SSH_ERR_KEY_REVOKED;
@@ -1271,6 +1273,7 @@ is_key_revoked(struct ssh_krl *krl, cons
return r;
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb);
free(rb.blob);
+ rb.blob = NULL; /* make coverity happy */
if (erb != NULL) {
KRL_DBG(("revoked by key SHA256"));
return SSH_ERR_KEY_REVOKED;
@@ -1282,6 +1285,7 @@ is_key_revoked(struct ssh_krl *krl, cons
return r;
erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
free(rb.blob);
+ rb.blob = NULL; /* make coverity happy */
if (erb != NULL) {
KRL_DBG(("revoked by explicit key"));
return SSH_ERR_KEY_REVOKED;
diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c
--- openssh-8.5p1/loginrec.c.coverity 2021-03-24 13:18:53.793225885 +0100
+++ openssh-8.5p1/loginrec.c 2021-03-24 13:21:27.948404751 +0100
@@ -690,9 +690,11 @@ construct_utmp(struct logininfo *li,
*/
/* Use strncpy because we don't necessarily want null termination */
+ /* coverity[buffer_size_warning : FALSE] */
strncpy(ut->ut_name, li->username,
MIN_SIZEOF(ut->ut_name, li->username));
# ifdef HAVE_HOST_IN_UTMP
+ /* coverity[buffer_size_warning : FALSE] */
strncpy(ut->ut_host, li->hostname,
MIN_SIZEOF(ut->ut_host, li->hostname));
# endif
@@ -1690,6 +1692,7 @@ record_failed_login(struct ssh *ssh, con
memset(&ut, 0, sizeof(ut));
/* strncpy because we don't necessarily want nul termination */
+ /* coverity[buffer_size_warning : FALSE] */
strncpy(ut.ut_user, username, sizeof(ut.ut_user));
strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line));
@@ -1699,6 +1702,7 @@ record_failed_login(struct ssh *ssh, con
ut.ut_pid = getpid();
/* strncpy because we don't necessarily want nul termination */
+ /* coverity[buffer_size_warning : FALSE] */
strncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
if (ssh_packet_connection_is_on_socket(ssh) &&
diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c
--- openssh-8.5p1/misc.c.coverity 2021-03-24 12:03:33.745967902 +0100
+++ openssh-8.5p1/misc.c 2021-03-24 13:31:47.037079617 +0100
@@ -1425,6 +1425,8 @@ sanitise_stdfd(void)
}
if (nullfd > STDERR_FILENO)
close(nullfd);
+ /* coverity[leaked_handle : FALSE]*/
+ /* coverity[leaked_handle : FALSE]*/
}
char *
@@ -2511,6 +2513,7 @@ stdfd_devnull(int do_stdin, int do_stdou
}
if (devnull > STDERR_FILENO)
close(devnull);
+ /* coverity[leaked_handle : FALSE]*/
return ret;
}
diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c
--- openssh-7.4p1/monitor.c.coverity 2016-12-23 16:40:26.888788688 +0100
+++ openssh-7.4p1/monitor.c 2016-12-23 16:40:26.900788691 +0100
@@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx
mm_get_keystate(ssh, pmonitor);
/* Drain any buffered messages from the child */
- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
;
if (pmonitor->m_recvfd >= 0)
@@ -1678,7 +1678,7 @@ mm_answer_pty(struct ssh *ssh, int sock,
s->ptymaster = s->ptyfd;
debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd);
-
+ /* coverity[leaked_handle : FALSE] */
return (0);
error:
diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c
--- openssh-7.4p1/monitor_wrap.c.coverity 2016-12-23 16:40:26.892788689 +0100
+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:40:26.900788691 +0100
@@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd,
if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
(tmp2 = dup(pmonitor->m_recvfd)) == -1) {
error_f("cannot allocate fds for pty");
- if (tmp1 > 0)
+ if (tmp1 >= 0)
close(tmp1);
- if (tmp2 > 0)
- close(tmp2);
+ /*DEAD CODE if (tmp2 >= 0)
+ close(tmp2);*/
return 0;
}
close(tmp1);
diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c
--- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/openbsd-compat/bindresvport.c 2016-12-23 16:40:26.901788691 +0100
@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr
struct sockaddr_in6 *in6;
u_int16_t *portp;
u_int16_t port;
- socklen_t salen;
+ socklen_t salen = sizeof(struct sockaddr_storage);
int i;
if (sa == NULL) {
diff -up openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity openssh-8.7p1/openbsd-compat/bsd-pselect.c
--- openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity 2021-08-30 16:36:11.357288009 +0200
+++ openssh-8.7p1/openbsd-compat/bsd-pselect.c 2021-08-30 16:37:21.791897976 +0200
@@ -113,13 +113,13 @@ pselect_notify_setup(void)
static void
pselect_notify_parent(void)
{
- if (notify_pipe[1] != -1)
+ if (notify_pipe[1] >= 0)
(void)write(notify_pipe[1], "", 1);
}
static void
pselect_notify_prepare(fd_set *readset)
{
- if (notify_pipe[0] != -1)
+ if (notify_pipe[0] >= 0)
FD_SET(notify_pipe[0], readset);
}
static void
@@ -127,8 +127,8 @@ pselect_notify_done(fd_set *readset)
{
char c;
- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) {
- while (read(notify_pipe[0], &c, 1) != -1)
+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) {
+ while (read(notify_pipe[0], &c, 1) >= 0)
debug2_f("reading");
FD_CLR(notify_pipe[0], readset);
}
diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c
--- openssh-8.5p1/readconf.c.coverity 2021-03-24 12:03:33.778968131 +0100
+++ openssh-8.5p1/readconf.c 2021-03-24 12:03:33.785968180 +0100
@@ -1847,6 +1847,7 @@ parse_pubkey_algos:
} else if (r != 0) {
error("%.200s line %d: glob failed for %s.",
filename, linenum, arg2);
+ free(arg2);
goto out;
}
free(arg2);
diff -up openssh-8.7p1/scp.c.coverity openssh-8.7p1/scp.c
--- openssh-8.7p1/scp.c.coverity 2021-08-30 16:23:35.389741329 +0200
+++ openssh-8.7p1/scp.c 2021-08-30 16:27:04.854555296 +0200
@@ -186,11 +186,11 @@ killchild(int signo)
{
if (do_cmd_pid > 1) {
kill(do_cmd_pid, signo ? signo : SIGTERM);
- waitpid(do_cmd_pid, NULL, 0);
+ (void) waitpid(do_cmd_pid, NULL, 0);
}
if (do_cmd_pid2 > 1) {
kill(do_cmd_pid2, signo ? signo : SIGTERM);
- waitpid(do_cmd_pid2, NULL, 0);
+ (void) waitpid(do_cmd_pid2, NULL, 0);
}
if (signo)
diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c
--- openssh-7.4p1/servconf.c.coverity 2016-12-23 16:40:26.896788690 +0100
+++ openssh-7.4p1/servconf.c 2016-12-23 16:40:26.901788691 +0100
@@ -1638,8 +1638,9 @@ process_server_config_line(ServerOptions
if (*activep && *charptr == NULL) {
*charptr = tilde_expand_filename(arg, getuid());
/* increase optional counter */
- if (intptr != NULL)
- *intptr = *intptr + 1;
+ /* DEAD CODE intptr is still NULL ;)
+ if (intptr != NULL)
+ *intptr = *intptr + 1; */
}
break;
diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c
--- openssh-8.7p1/serverloop.c.coverity 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/serverloop.c 2021-08-30 16:28:22.416226981 +0200
@@ -547,7 +547,7 @@ server_request_tun(struct ssh *ssh)
debug_f("invalid tun");
goto done;
}
- if (auth_opts->force_tun_device != -1) {
+ if (auth_opts->force_tun_device >= 0) {
if (tun != SSH_TUNID_ANY &&
auth_opts->force_tun_device != (int)tun)
goto done;
diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
--- openssh-7.4p1/sftp.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/sftp.c 2016-12-23 16:40:26.903788691 +0100
@@ -224,7 +224,7 @@ killchild(int signo)
pid = sshpid;
if (pid > 1) {
kill(pid, SIGTERM);
- waitpid(pid, NULL, 0);
+ (void) waitpid(pid, NULL, 0);
}
_exit(1);
diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c
--- openssh-7.4p1/ssh-agent.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/ssh-agent.c 2016-12-23 16:40:26.903788691 +0100
@@ -869,6 +869,7 @@ sanitize_pkcs11_provider(const char *pro
if (pkcs11_uri_parse(provider, uri) != 0) {
error("Failed to parse PKCS#11 URI");
+ pkcs11_uri_cleanup(uri);
return NULL;
}
/* validate also provider from URI */
@@ -1220,8 +1220,8 @@ main(int ac, char **av)
sanitise_stdfd();
/* drop */
- setegid(getgid());
- setgid(getgid());
+ (void) setegid(getgid());
+ (void) setgid(getgid());
platform_disable_tracing(0); /* strict=no */
diff -up openssh-8.5p1/ssh.c.coverity openssh-8.5p1/ssh.c
--- openssh-8.5p1/ssh.c.coverity 2021-03-24 12:03:33.779968138 +0100
+++ openssh-8.5p1/ssh.c 2021-03-24 12:03:33.786968187 +0100
@@ -1746,6 +1746,7 @@ control_persist_detach(void)
close(muxserver_sock);
muxserver_sock = -1;
options.control_master = SSHCTL_MASTER_NO;
+ /* coverity[leaked_handle: FALSE]*/
muxclient(options.control_path);
/* muxclient() doesn't return on success. */
fatal("Failed to connect to new control master");
diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
--- openssh-7.4p1/sshd.c.coverity 2016-12-23 16:40:26.897788690 +0100
+++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100
@@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt)
privsep_preauth_child(ssh);
setproctitle("%s", "[net]");
- if (box != NULL)
+ if (box != NULL) {
ssh_sandbox_child(box);
+ free(box);
+ }
return 0;
}
@@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh)
if (newstr)
myproposal[PROPOSAL_KEX_ALGS] = newstr;
- else
+ else {
fatal("No supported key exchange algorithms");
+ free(gss);
+ }
+ /* coverity[leaked_storage: FALSE]*/
}
#endif
diff -up openssh-8.5p1/ssh-keygen.c.coverity openssh-8.5p1/ssh-keygen.c
--- openssh-8.5p1/ssh-keygen.c.coverity 2021-03-24 12:03:33.780968145 +0100
+++ openssh-8.5p1/ssh-keygen.c 2021-03-24 12:03:33.787968194 +0100
@@ -2332,6 +2332,9 @@ update_krl_from_file(struct passwd *pw,
r = ssh_krl_revoke_key_sha256(krl, blob, blen);
if (r != 0)
fatal_fr(r, "revoke key failed");
+ freezero(blob, blen);
+ blob = NULL;
+ blen = 0;
} else {
if (strncasecmp(cp, "key:", 4) == 0) {
cp += 4;

View file

@ -1,12 +0,0 @@
diff -up openssh/servconf.c.sshdt openssh/servconf.c
--- openssh/servconf.c.sshdt 2015-06-24 11:42:29.041078704 +0200
+++ openssh/servconf.c 2015-06-24 11:44:39.734745802 +0200
@@ -2317,7 +2317,7 @@ dump_config(ServerOptions *o)
dump_cfg_string(sXAuthLocation, o->xauth_location);
dump_cfg_string(sCiphers, o->ciphers);
dump_cfg_string(sMacs, o->macs);
- dump_cfg_string(sBanner, o->banner);
+ dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none");
dump_cfg_string(sForceCommand, o->adm_forced_command);
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);

View file

@ -1,98 +0,0 @@
commit 0e22b79bfde45a7cf7a2e51a68ec11c4285f3b31
Author: Jakub Jelen <jjelen@redhat.com>
Date: Mon Nov 21 15:04:06 2016 +0100
systemd stuff
diff --git a/configure.ac b/configure.ac
index 2ffc369..162ce92 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4265,6 +4265,30 @@ AC_ARG_WITH([kerberos5],
AC_SUBST([K5LIBS])
AC_SUBST([CHANNELLIBS])
+# Check whether user wants systemd support
+SYSTEMD_MSG="no"
+AC_ARG_WITH(systemd,
+ [ --with-systemd Enable systemd support],
+ [ if test "x$withval" != "xno" ; then
+ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])
+ if test "$PKGCONFIG" != "no"; then
+ AC_MSG_CHECKING([for libsystemd])
+ if $PKGCONFIG --exists libsystemd; then
+ SYSTEMD_CFLAGS=`$PKGCONFIG --cflags libsystemd`
+ SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd`
+ CPPFLAGS="$CPPFLAGS $SYSTEMD_CFLAGS"
+ SSHDLIBS="$SSHDLIBS $SYSTEMD_LIBS"
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if you want systemd support.])
+ SYSTEMD_MSG="yes"
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ fi ]
+)
+
+
# Looking for programs, paths and files
PRIVSEP_PATH=/var/empty
@@ -5097,6 +5121,7 @@ echo " libedit support: $LIBEDIT_MSG"
echo " Solaris process contract support: $SPC_MSG"
echo " Solaris project support: $SP_MSG"
echo " Solaris privilege support: $SPP_MSG"
+echo " systemd support: $SYSTEMD_MSG"
echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
echo " BSD Auth support: $BSD_AUTH_MSG"
diff --git a/contrib/sshd.service b/contrib/sshd.service
new file mode 100644
index 0000000..e0d4923
--- /dev/null
+++ b/contrib/sshd.service
@@ -0,0 +1,16 @@
+[Unit]
+Description=OpenSSH server daemon
+Documentation=man:sshd(8) man:sshd_config(5)
+After=network.target
+
+[Service]
+Type=notify
+ExecStart=/usr/sbin/sshd -D $OPTIONS
+ExecReload=/bin/kill -HUP $MAINPID
+KillMode=process
+Restart=on-failure
+RestartPreventExitStatus=255
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/sshd.c b/sshd.c
index 816611c..b8b9d13 100644
--- a/sshd.c
+++ b/sshd.c
@@ -85,6 +85,10 @@
#include <prot.h>
#endif
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
@@ -1888,6 +1892,11 @@ main(int ac, char **av)
}
}
+#ifdef HAVE_SYSTEMD
+ /* Signal systemd that we are ready to accept connections */
+ sd_notify(0, "READY=1");
+#endif
+
/* Accept a connection and return in a forked child */
server_accept_loop(&sock_in, &sock_out,
&newsock, config_s);

View file

@ -1,86 +0,0 @@
In order to use the OpenSSL-ibmpkcs11 engine it is needed to allow flock
and ipc calls, because this engine calls OpenCryptoki (a PKCS#11
implementation) which calls the libraries that will communicate with the
crypto cards. OpenCryptoki makes use of flock and ipc and, as of now,
this is only need on s390 architecture.
Signed-off-by: Eduardo Barretto <ebarretto@xxxxxxxxxxxxxxxxxx>
---
sandbox-seccomp-filter.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index ca75cc7..6e7de31 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -166,6 +166,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_exit_group
SC_ALLOW(__NR_exit_group),
#endif
+#if defined(__NR_flock) && defined(__s390__)
+ SC_ALLOW(__NR_flock),
+#endif
#ifdef __NR_futex
SC_FUTEX(__NR_futex),
#endif
@@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_gettimeofday
SC_ALLOW(__NR_gettimeofday),
#endif
+#if defined(__NR_ipc) && defined(__s390__)
+ SC_ALLOW(__NR_ipc),
+#endif
#ifdef __NR_getuid
SC_ALLOW(__NR_getuid),
#endif
--
1.9.1
getuid and geteuid are needed when using an openssl engine that calls a
crypto card, e.g. ICA (libica).
Those syscalls are also needed by the distros for audit code.
Signed-off-by: Eduardo Barretto <ebarretto@xxxxxxxxxxxxxxxxxx>
---
sandbox-seccomp-filter.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index 6e7de31..e86aa2c 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -175,6 +175,18 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_getpid
SC_ALLOW(__NR_getpid),
#endif
+#ifdef __NR_getuid
+ SC_ALLOW(__NR_getuid),
+#endif
+#ifdef __NR_getuid32
+ SC_ALLOW(__NR_getuid32),
+#endif
+#ifdef __NR_geteuid
+ SC_ALLOW(__NR_geteuid),
+#endif
+#ifdef __NR_geteuid32
+ SC_ALLOW(__NR_geteuid32),
+#endif
#ifdef __NR_getrandom
SC_ALLOW(__NR_getrandom),
#endif
-- 1.9.1
1.9.1
diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-seccomp-filter.c
--- openssh-7.6p1/sandbox-seccomp-filter.c.sandbox 2017-12-12 13:59:30.563874059 +0100
+++ openssh-7.6p1/sandbox-seccomp-filter.c 2017-12-12 13:59:14.842784083 +0100
@@ -190,6 +190,9 @@ static const struct sock_filter preauth_
#ifdef __NR_geteuid32
SC_ALLOW(__NR_geteuid32),
#endif
+#ifdef __NR_gettid
+ SC_ALLOW(__NR_gettid),
+#endif
#ifdef __NR_getrandom
SC_ALLOW(__NR_getrandom),
#endif

View file

@ -1,26 +0,0 @@
diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c
--- openssh-8.6p1/sshd.c.log-usepam-no 2021-04-19 14:00:45.099735129 +0200
+++ openssh-8.6p1/sshd.c 2021-04-19 14:03:21.140920974 +0200
@@ -1749,6 +1749,10 @@ main(int ac, char **av)
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
cfg, &includes, NULL, rexeced_flag);
+ /* 'UsePAM no' is not supported in Fedora */
+ if (! options.use_pam)
+ logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems.");
+
#ifdef WITH_OPENSSL
if (options.moduli_file != NULL)
dh_set_moduli_file(options.moduli_file);
diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config
--- openssh-8.6p1/sshd_config.log-usepam-no 2021-04-19 14:00:45.098735121 +0200
+++ openssh-8.6p1/sshd_config 2021-04-19 14:00:45.099735129 +0200
@@ -87,6 +87,8 @@ AuthorizedKeysFile .ssh/authorized_keys
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
+# WARNING: 'UsePAM no' is not supported in Fedora and may cause several
+# problems.
#UsePAM no
#AllowAgentForwarding yes

View file

@ -1,12 +0,0 @@
diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c
--- openssh-8.0p1/ssh-keygen.c.strip-doseol 2021-03-18 17:41:34.472404994 +0100
+++ openssh-8.0p1/ssh-keygen.c 2021-03-18 17:41:55.255538761 +0100
@@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw)
while (getline(&line, &linesize, f) != -1) {
lnum++;
cp = line;
- cp[strcspn(cp, "\n")] = '\0';
+ cp[strcspn(cp, "\r\n")] = '\0';
/* Trim leading space and comments */
cp = line + strspn(line, " \t");
if (*cp == '#' || *cp == '\0')

View file

@ -1,137 +0,0 @@
commit 2c3ef499bfffce3cfd315edeebf202850ba4e00a
Author: Jakub Jelen <jjelen@redhat.com>
Date: Tue Apr 16 15:35:18 2019 +0200
Use the new OpenSSL KDF
diff --git a/configure.ac b/configure.ac
index 2a455e4e..e01c3d43 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2712,6 +2712,7 @@ if test "x$openssl" = "xyes" ; then
HMAC_CTX_init \
RSA_generate_key_ex \
RSA_get_default_method \
+ EVP_KDF_CTX_new_id \
])
# OpenSSL_add_all_algorithms may be a macro.
diff --git a/kex.c b/kex.c
index b6f041f4..1fbce2bb 100644
--- a/kex.c
+++ b/kex.c
@@ -38,6 +38,9 @@
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
#include <openssl/dh.h>
+# ifdef HAVE_EVP_KDF_CTX_NEW_ID
+# include <openssl/kdf.h>
+# endif
#endif
#include "ssh.h"
@@ -942,6 +945,95 @@ kex_choose_conf(struct ssh *ssh)
return r;
}
+#ifdef HAVE_EVP_KDF_CTX_NEW_ID
+static const EVP_MD *
+digest_to_md(int digest_type)
+{
+ switch (digest_type) {
+ case SSH_DIGEST_SHA1:
+ return EVP_sha1();
+ case SSH_DIGEST_SHA256:
+ return EVP_sha256();
+ case SSH_DIGEST_SHA384:
+ return EVP_sha384();
+ case SSH_DIGEST_SHA512:
+ return EVP_sha512();
+ }
+ return NULL;
+}
+
+static int
+derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
+ const struct sshbuf *shared_secret, u_char **keyp)
+{
+ struct kex *kex = ssh->kex;
+ EVP_KDF_CTX *ctx = NULL;
+ u_char *key = NULL;
+ int r, key_len;
+
+ if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+ key_len = ROUNDUP(need, key_len);
+ if ((key = calloc(1, key_len)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
+ if (!ctx) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest_to_md(kex->hash_alg));
+ if (r != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY,
+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret));
+ if (r != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, hash, hashlen);
+ if (r != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, id);
+ if (r != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
+ sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id));
+ if (r != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ r = EVP_KDF_derive(ctx, key, key_len);
+ if (r != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+#ifdef DEBUG_KEX
+ fprintf(stderr, "key '%c'== ", id);
+ dump_digest("key", key, key_len);
+#endif
+ *keyp = key;
+ key = NULL;
+ r = 0;
+
+out:
+ free (key);
+ EVP_KDF_CTX_free(ctx);
+ if (r < 0) {
+ return r;
+ }
+ return 0;
+}
+#else
static int
derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
const struct sshbuf *shared_secret, u_char **keyp)
@@ -1004,6 +1096,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
ssh_digest_free(hashctx);
return r;
}
+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */
#define NKEYS 6
int

View file

@ -1,11 +0,0 @@
--- openssh-8.7p1/openbsd-compat/bsd-closefrom.c.orig 2022-04-12 15:47:03.815044607 +0200
+++ openssh-8.7p1/openbsd-compat/bsd-closefrom.c 2022-04-12 15:48:12.464963511 +0200
@@ -16,7 +16,7 @@
#include "includes.h"
-#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM)
+#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__)
#include <sys/types.h>
#include <unistd.h>

View file

@ -1,24 +0,0 @@
diff --git a/readconf.c b/readconf.c
index 7f26c680..42be690b 100644
--- a/readconf.c
+++ b/readconf.c
@@ -320,6 +320,7 @@ static struct {
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
{ "requiredrsasize", oRequiredRSASize },
+ { "rsaminsize", oRequiredRSASize }, /* alias */
{ "enableescapecommandline", oEnableEscapeCommandline },
{ NULL, oBadOption }
diff --git a/servconf.c b/servconf.c
index 29df0463..423772b1 100644
--- a/servconf.c
+++ b/servconf.c
@@ -676,6 +680,7 @@ static struct {
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
+ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */
{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },
{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
{ NULL, sBadOption, 0 }

View file

@ -1,402 +0,0 @@
diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c
--- openssh-8.7p1/compat.c.sshrsacheck 2023-01-12 13:29:06.338710923 +0100
+++ openssh-8.7p1/compat.c 2023-01-12 13:29:06.357711165 +0100
@@ -43,6 +43,7 @@ void
compat_banner(struct ssh *ssh, const char *version)
{
int i;
+ int forbid_ssh_rsa = 0;
static struct {
char *pat;
int bugs;
@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha
};
/* process table, return first match */
+ forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA);
ssh->compat = 0;
for (i = 0; check[i].pat; i++) {
if (match_pattern_list(version, check[i].pat, 0) == 1) {
debug_f("match: %s pat %s compat 0x%08x",
version, check[i].pat, check[i].bugs);
ssh->compat = check[i].bugs;
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
return;
}
}
debug_f("no match: %s", version);
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
}
/* Always returns pointer to allocated memory, caller must free. */
diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h
--- openssh-8.7p1/compat.h.sshrsacheck 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/compat.h 2023-01-12 13:29:06.358711178 +0100
@@ -30,7 +30,7 @@
#define SSH_BUG_UTF8TTYMODE 0x00000001
#define SSH_BUG_SIGTYPE 0x00000002
#define SSH_BUG_SIGTYPE74 0x00000004
-/* #define unused 0x00000008 */
+#define SSH_RH_RSASIGSHA 0x00000008
#define SSH_OLD_SESSIONID 0x00000010
/* #define unused 0x00000020 */
#define SSH_BUG_DEBUG 0x00000040
diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c
--- openssh-8.7p1/monitor.c.sshrsacheck 2023-01-20 13:07:54.279676981 +0100
+++ openssh-8.7p1/monitor.c 2023-01-20 15:01:07.007821379 +0100
@@ -660,11 +660,12 @@ mm_answer_sign(struct ssh *ssh, int sock
struct sshkey *key;
struct sshbuf *sigbuf = NULL;
u_char *p = NULL, *signature = NULL;
- char *alg = NULL;
+ char *alg = NULL, *effective_alg;
size_t datlen, siglen, alglen;
int r, is_proof = 0;
u_int keyid, compat;
const char proof_req[] = "hostkeys-prove-00@openssh.com";
+ const char safe_rsa[] = "rsa-sha2-256";
debug3_f("entering");
@@ -719,18 +720,30 @@ mm_answer_sign(struct ssh *ssh, int sock
}
if ((key = get_hostkey_by_index(keyid)) != NULL) {
- if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
+ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
+ && (sshkey_type_plain(key->type) == KEY_RSA)) {
+ effective_alg = safe_rsa;
+ } else {
+ effective_alg = alg;
+ }
+ if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, effective_alg,
options.sk_provider, NULL, compat)) != 0)
fatal_fr(r, "sign");
} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
auth_sock > 0) {
+ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
+ && (sshkey_type_plain(key->type) == KEY_RSA)) {
+ effective_alg = safe_rsa;
+ } else {
+ effective_alg = alg;
+ }
if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
- p, datlen, alg, compat)) != 0)
+ p, datlen, effective_alg, compat)) != 0)
fatal_fr(r, "agent sign");
} else
fatal_f("no hostkey from index %d", keyid);
- debug3_f("%s %s signature len=%zu", alg,
+ debug3_f("%s (effective: %s) %s signature len=%zu", alg, effective_alg,
is_proof ? "hostkey proof" : "KEX", siglen);
sshbuf_reset(m);
diff -up openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck openssh-8.7p1/regress/cert-userkey.sh
--- openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck 2023-01-25 14:26:52.885963113 +0100
+++ openssh-8.7p1/regress/cert-userkey.sh 2023-01-25 14:27:25.757219800 +0100
@@ -7,7 +7,8 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
-PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
+#ssh-dss keys are incompatible with DEFAULT crypto policy
+PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss' | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
EXTRA_TYPES=""
rsa=""
diff -up openssh-8.7p1/regress/Makefile.sshrsacheck openssh-8.7p1/regress/Makefile
--- openssh-8.7p1/regress/Makefile.sshrsacheck 2023-01-20 13:07:54.169676051 +0100
+++ openssh-8.7p1/regress/Makefile 2023-01-20 13:07:54.290677074 +0100
@@ -2,7 +2,8 @@
tests: prep file-tests t-exec unit
-REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12
+#ssh-dss tests will not pass on DEFAULT crypto-policy because of SHA1, skipping
+REGRESS_TARGETS= t1 t2 t3 t4 t5 t7 t8 t9 t10 t11 t12
# File based tests
file-tests: $(REGRESS_TARGETS)
diff -up openssh-8.7p1/regress/test-exec.sh.sshrsacheck openssh-8.7p1/regress/test-exec.sh
--- openssh-8.7p1/regress/test-exec.sh.sshrsacheck 2023-01-25 14:24:54.778040819 +0100
+++ openssh-8.7p1/regress/test-exec.sh 2023-01-25 14:26:39.500858590 +0100
@@ -581,8 +581,9 @@ maybe_filter_sk() {
fi
}
-SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk`
-SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk`
+#ssh-dss keys are incompatible with DEFAULT crypto policy
+SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'`
+SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'`
for t in ${SSH_KEYTYPES}; do
# generate user key
diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p1/regress/unittests/kex/test_kex.c
--- openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck 2023-01-26 13:34:52.645743677 +0100
+++ openssh-8.7p1/regress/unittests/kex/test_kex.c 2023-01-26 13:36:56.220745823 +0100
@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype,
memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
if (kex != NULL)
kex_params.proposal[PROPOSAL_KEX_ALGS] = kex;
- keyname = strdup(sshkey_ssh_name(private));
+ keyname = (strcmp(sshkey_ssh_name(private), "ssh-rsa")) ?
+ strdup(sshkey_ssh_name(private)) : strdup("rsa-sha2-256");
ASSERT_PTR_NE(keyname, NULL);
kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname;
ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
@@ -180,7 +181,7 @@ do_kex(char *kex)
{
#ifdef WITH_OPENSSL
do_kex_with_key(kex, KEY_RSA, 2048);
- do_kex_with_key(kex, KEY_DSA, 1024);
+ /* do_kex_with_key(kex, KEY_DSA, 1024); */
#ifdef OPENSSL_HAS_ECC
do_kex_with_key(kex, KEY_ECDSA, 256);
#endif /* OPENSSL_HAS_ECC */
diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_file.c
--- openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck 2023-01-26 12:04:55.946343408 +0100
+++ openssh-8.7p1/regress/unittests/sshkey/test_file.c 2023-01-26 12:06:35.235164432 +0100
@@ -110,6 +110,7 @@ sshkey_file_tests(void)
sshkey_free(k2);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("load RSA cert with SHA1 signature");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0);
ASSERT_PTR_NE(k2, NULL);
@@ -117,7 +118,7 @@ sshkey_file_tests(void)
ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
ASSERT_STRING_EQ(k2->cert->signature_type, "ssh-rsa");
sshkey_free(k2);
- TEST_DONE();
+ TEST_DONE(); */
TEST_START("load RSA cert with SHA512 signature");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0);
diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c
--- openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck 2023-01-26 12:10:37.533168013 +0100
+++ openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c 2023-01-26 12:15:35.637631860 +0100
@@ -333,13 +333,14 @@ sshkey_fuzz_tests(void)
TEST_DONE();
#ifdef WITH_OPENSSL
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("fuzz RSA sig");
buf = load_file("rsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
sshbuf_free(buf);
sig_fuzz(k1, "ssh-rsa");
sshkey_free(k1);
- TEST_DONE();
+ TEST_DONE();*/
TEST_START("fuzz RSA SHA256 sig");
buf = load_file("rsa_1");
@@ -357,6 +358,7 @@ sshkey_fuzz_tests(void)
sshkey_free(k1);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("fuzz DSA sig");
buf = load_file("dsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
@@ -364,6 +366,7 @@ sshkey_fuzz_tests(void)
sig_fuzz(k1, NULL);
sshkey_free(k1);
TEST_DONE();
+ */
#ifdef OPENSSL_HAS_ECC
TEST_START("fuzz ECDSA sig");
diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c
--- openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck 2023-01-26 11:02:52.339413463 +0100
+++ openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c 2023-01-26 11:58:42.324253896 +0100
@@ -60,6 +60,9 @@ build_cert(struct sshbuf *b, struct sshk
u_char *sigblob;
size_t siglen;
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
+ int expected = (sig_alg == NULL || strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
+
ca_buf = sshbuf_new();
ASSERT_PTR_NE(ca_buf, NULL);
ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
@@ -101,8 +104,9 @@ build_cert(struct sshbuf *b, struct sshk
ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
- sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0);
- ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
+ sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), expected);
+ if (expected == 0)
+ ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
free(sigblob);
sshbuf_free(ca_buf);
@@ -119,16 +123,22 @@ signature_test(struct sshkey *k, struct
{
size_t len;
u_char *sig;
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
+ int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
+ if (k && (sshkey_type_plain(k->type) == KEY_DSA || sshkey_type_plain(k->type) == KEY_DSA_CERT))
+ expected = SSH_ERR_LIBCRYPTO_ERROR;
ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg,
- NULL, NULL, 0), 0);
- ASSERT_SIZE_T_GT(len, 8);
- ASSERT_PTR_NE(sig, NULL);
- ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
- ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
- /* Fuzz test is more comprehensive, this is just a smoke test */
- sig[len - 5] ^= 0x10;
- ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ NULL, NULL, 0), expected);
+ if (expected == 0) {
+ ASSERT_SIZE_T_GT(len, 8);
+ ASSERT_PTR_NE(sig, NULL);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
+ /* Fuzz test is more comprehensive, this is just a smoke test */
+ sig[len - 5] ^= 0x10;
+ ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ }
free(sig);
}
@@ -514,7 +524,7 @@ sshkey_tests(void)
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
NULL), 0);
k3 = get_private("rsa_1");
- build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
+ build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, "rsa-sha2-256");
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
ASSERT_PTR_EQ(k4, NULL);
diff -up openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck openssh-8.7p1/regress/unittests/sshsig/tests.c
--- openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck 2023-01-26 12:19:23.659513651 +0100
+++ openssh-8.7p1/regress/unittests/sshsig/tests.c 2023-01-26 12:20:28.021044803 +0100
@@ -102,9 +102,11 @@ tests(void)
check_sig("rsa.pub", "rsa.sig", msg, namespace);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("check DSA signature");
check_sig("dsa.pub", "dsa.sig", msg, namespace);
TEST_DONE();
+ */
#ifdef OPENSSL_HAS_ECC
TEST_START("check ECDSA signature");
diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c
--- openssh-8.7p1/serverloop.c.sshrsacheck 2023-01-12 14:57:08.118400073 +0100
+++ openssh-8.7p1/serverloop.c 2023-01-12 14:59:17.330470518 +0100
@@ -80,6 +80,7 @@
#include "auth-options.h"
#include "serverloop.h"
#include "ssherr.h"
+#include "compat.h"
extern ServerOptions options;
@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh *
else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
sigalg = "rsa-sha2-256";
}
+ if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) {
+ sigalg = "rsa-sha2-512";
+ debug3_f("SHA1 signature is not supported, falling back to %s", sigalg);
+ }
debug3_f("sign %s key (index %d) using sigalg %s",
sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
if ((r = sshbuf_put_cstring(sigbuf,
diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c
--- openssh-8.7p1/sshconnect2.c.sshrsacheck 2023-01-25 15:33:29.140353651 +0100
+++ openssh-8.7p1/sshconnect2.c 2023-01-25 15:59:34.225364883 +0100
@@ -1461,6 +1464,14 @@ identity_sign(struct identity *id, u_cha
retried = 1;
goto retry_pin;
}
+ if ((r == SSH_ERR_LIBCRYPTO_ERROR) && strcmp("ssh-rsa", alg)) {
+ char rsa_safe_alg[] = "rsa-sha2-512";
+ debug3_f("trying to fallback to algorithm %s", rsa_safe_alg);
+
+ if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
+ rsa_safe_alg, options.sk_provider, pin, compat)) != 0)
+ debug_fr(r, "sshkey_sign - RSA fallback");
+ }
goto out;
}
diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c
--- openssh-8.7p1/sshd.c.sshrsacheck 2023-01-12 13:29:06.355711140 +0100
+++ openssh-8.7p1/sshd.c 2023-01-12 13:29:06.358711178 +0100
@@ -1640,6 +1651,7 @@ main(int ac, char **av)
Authctxt *authctxt;
struct connection_info *connection_info = NULL;
sigset_t sigmask;
+ int forbid_ssh_rsa = 0;
#ifdef HAVE_SECUREWARE
(void)set_auth_parameters(ac, av);
@@ -1938,6 +1950,33 @@ main(int ac, char **av)
key = NULL;
continue;
}
+ if (key && (sshkey_type_plain(key->type) == KEY_RSA || sshkey_type_plain(key->type) == KEY_RSA_CERT)) {
+ size_t sign_size = 0;
+ u_char *tmp = NULL;
+ u_char data[] = "Test SHA1 vector";
+ int res;
+
+ res = sshkey_sign(key, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
+ free(tmp);
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) {
+ verbose_f("sshd: SHA1 in signatures is disabled for RSA keys");
+ forbid_ssh_rsa = 1;
+ }
+ }
+ if (key && (sshkey_type_plain(key->type) == KEY_DSA || sshkey_type_plain(key->type) == KEY_DSA_CERT)) {
+ size_t sign_size = 0;
+ u_char *tmp = NULL;
+ u_char data[] = "Test SHA1 vector";
+ int res;
+
+ res = sshkey_sign(key, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
+ free(tmp);
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) {
+ logit_f("sshd: ssh-dss is disabled, skipping key file %s", options.host_key_files[i]);
+ key = NULL;
+ continue;
+ }
+ }
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
@@ -2275,6 +2306,9 @@ main(int ac, char **av)
check_ip_options(ssh);
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
+
/* Prepare the channels layer */
channel_init_channels(ssh);
channel_set_af(ssh, options.address_family);
diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c
--- openssh-8.7p1/ssh-rsa.c.sshrsacheck 2023-01-20 13:07:54.180676144 +0100
+++ openssh-8.7p1/ssh-rsa.c 2023-01-20 13:07:54.290677074 +0100
@@ -254,7 +254,8 @@ ssh_rsa_verify(const struct sshkey *key,
ret = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- if (hash_alg != want_alg) {
+ if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) {
+ debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg);
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
}

View file

@ -1,181 +0,0 @@
diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c
--- openssh-8.7p1/scp.c.scp-sftpdirs 2022-02-07 12:31:07.407740407 +0100
+++ openssh-8.7p1/scp.c 2022-02-07 12:31:07.409740424 +0100
@@ -1324,7 +1324,7 @@ source_sftp(int argc, char *src, char *t
if (src_is_dir && iamrecursive) {
if (upload_dir(conn, src, abs_dst, pflag,
- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) {
error("failed to upload directory %s to %s", src, targ);
errs = 1;
}
diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c
--- openssh-8.7p1/sftp-client.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/sftp-client.c 2022-02-07 12:47:59.117516131 +0100
@@ -971,7 +971,7 @@ do_fsetstat(struct sftp_conn *conn, cons
/* Implements both the realpath and expand-path operations */
static char *
-do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
+do_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir)
{
struct sshbuf *msg;
u_int expected_id, count, id;
@@ -1033,11 +1033,43 @@ do_realpath_expand(struct sftp_conn *con
if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
fatal_fr(r, "parse status");
- error("%s %s: %s", expand ? "expand" : "realpath",
- path, *errmsg == '\0' ? fx2txt(status) : errmsg);
- free(errmsg);
- sshbuf_free(msg);
- return NULL;
+ if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) {
+ memset(&a, '\0', sizeof(a));
+ if ((r = do_mkdir(conn, path, &a, 0)) != 0) {
+ sshbuf_free(msg);
+ return NULL;
+ }
+ debug2("Sending SSH2_FXP_REALPATH \"%s\" - create dir", path);
+ send_string_request(conn, id, SSH2_FXP_REALPATH,
+ path, strlen(path));
+
+ get_msg(conn, msg);
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+ (r = sshbuf_get_u32(msg, &id)) != 0)
+ fatal_fr(r, "parse");
+
+ if (id != expected_id)
+ fatal("ID mismatch (%u != %u)", id, expected_id);
+
+ if (type == SSH2_FXP_STATUS) {
+ free(errmsg);
+
+ if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
+ (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
+ fatal_fr(r, "parse status");
+ error("%s %s: %s", expand ? "expand" : "realpath",
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+ free(errmsg);
+ sshbuf_free(msg);
+ return NULL;
+ }
+ } else {
+ error("%s %s: %s", expand ? "expand" : "realpath",
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+ free(errmsg);
+ sshbuf_free(msg);
+ return NULL;
+ }
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
@@ -1039,9 +1067,9 @@ do_realpath_expand(struct sftp_conn *con
}
char *
-do_realpath(struct sftp_conn *conn, const char *path)
+do_realpath(struct sftp_conn *conn, const char *path, int create_dir)
{
- return do_realpath_expand(conn, path, 0);
+ return do_realpath_expand(conn, path, 0, create_dir);
}
int
@@ -1055,9 +1083,9 @@ do_expand_path(struct sftp_conn *conn, c
{
if (!can_expand_path(conn)) {
debug3_f("no server support, fallback to realpath");
- return do_realpath_expand(conn, path, 0);
+ return do_realpath_expand(conn, path, 0, 0);
}
- return do_realpath_expand(conn, path, 1);
+ return do_realpath_expand(conn, path, 1, 0);
}
int
@@ -1807,7 +1835,7 @@ download_dir(struct sftp_conn *conn, con
char *src_canon;
int ret;
- if ((src_canon = do_realpath(conn, src)) == NULL) {
+ if ((src_canon = do_realpath(conn, src, 0)) == NULL) {
error("download \"%s\": path canonicalization failed", src);
return -1;
}
@@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co
int
upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
int preserve_flag, int print_flag, int resume, int fsync_flag,
- int follow_link_flag, int inplace_flag)
+ int follow_link_flag, int inplace_flag, int create_dir)
{
char *dst_canon;
int ret;
- if ((dst_canon = do_realpath(conn, dst)) == NULL) {
+ if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) {
error("upload \"%s\": path canonicalization failed", dst);
return -1;
}
@@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st
char *from_path_canon;
int ret;
- if ((from_path_canon = do_realpath(from, from_path)) == NULL) {
+ if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) {
error("crossload \"%s\": path canonicalization failed",
from_path);
return -1;
diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h
--- openssh-8.7p1/sftp-client.h.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/sftp-client.h 2022-02-07 12:31:07.410740433 +0100
@@ -111,7 +111,7 @@ int do_fsetstat(struct sftp_conn *, cons
int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
/* Canonicalise 'path' - caller must free result */
-char *do_realpath(struct sftp_conn *, const char *);
+char *do_realpath(struct sftp_conn *, const char *, int);
/* Canonicalisation with tilde expansion (requires server extension) */
char *do_expand_path(struct sftp_conn *, const char *);
@@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const
* times if 'pflag' is set
*/
int upload_dir(struct sftp_conn *, const char *, const char *,
- int, int, int, int, int, int);
+ int, int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to
diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c
--- openssh-8.7p1/sftp.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/sftp.c 2022-02-07 12:31:07.411740442 +0100
@@ -760,7 +760,7 @@ process_put(struct sftp_conn *conn, cons
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
- fflag || global_fflag, 0, 0) == -1)
+ fflag || global_fflag, 0, 0, 0) == -1)
err = -1;
} else {
if (do_upload(conn, g.gl_pathv[i], abs_dst,
@@ -1577,7 +1577,7 @@ parse_dispatch_command(struct sftp_conn
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
path1 = make_absolute(path1, *pwd);
- if ((tmp = do_realpath(conn, path1)) == NULL) {
+ if ((tmp = do_realpath(conn, path1, 0)) == NULL) {
err = 1;
break;
}
@@ -2160,7 +2160,7 @@ interactive_loop(struct sftp_conn *conn,
}
#endif /* USE_LIBEDIT */
- remote_path = do_realpath(conn, ".");
+ remote_path = do_realpath(conn, ".", 0);
if (remote_path == NULL)
fatal("Need cwd");
startdir = xstrdup(remote_path);

View file

@ -1,53 +0,0 @@
diff --color -ru a/ssh.1 b/ssh.1
--- a/ssh.1 2022-07-12 11:47:51.307295880 +0200
+++ b/ssh.1 2022-07-12 11:50:28.793363263 +0200
@@ -493,6 +493,7 @@
.It AddressFamily
.It BatchMode
.It BindAddress
+.It BindInterface
.It CanonicalDomains
.It CanonicalizeFallbackLocal
.It CanonicalizeHostname
@@ -510,6 +511,7 @@
.It ControlPath
.It ControlPersist
.It DynamicForward
+.It EnableSSHKeysign
.It EnableEscapeCommandline
.It EscapeChar
.It ExitOnForwardFailure
@@ -538,6 +540,8 @@
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
+.It IgnoreUnknown
+.It Include
.It IPQoS
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
@@ -546,6 +550,7 @@
.It LocalCommand
.It LocalForward
.It LogLevel
+.It LogVerbose
.It MACs
.It Match
.It NoHostAuthenticationForLocalhost
@@ -566,6 +571,8 @@
.It RemoteCommand
.It RemoteForward
.It RequestTTY
+.It RevokedHostKeys
+.It SecurityKeyProvider
.It RequiredRSASize
.It SendEnv
.It ServerAliveInterval
@@ -575,6 +582,7 @@
.It StreamLocalBindMask
.It StreamLocalBindUnlink
.It StrictHostKeyChecking
+.It SyslogFacility
.It TCPKeepAlive
.It Tunnel
.It TunnelDevice

View file

@ -1,119 +0,0 @@
diff -up openssh-9.0p1/audit-bsm.c.patch openssh-9.0p1/audit-bsm.c
--- openssh-9.0p1/audit-bsm.c.patch 2022-10-24 15:02:16.544858331 +0200
+++ openssh-9.0p1/audit-bsm.c 2022-10-24 14:51:43.685766639 +0200
@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li
}
int
-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv)
+audit_keyusage(struct ssh *ssh, int host_user, char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv)
{
/* not implemented */
}
diff -up openssh-9.0p1/audit.c.patch openssh-9.0p1/audit.c
--- openssh-9.0p1/audit.c.patch 2022-10-24 15:02:16.544858331 +0200
+++ openssh-9.0p1/audit.c 2022-10-24 15:20:38.854548226 +0200
@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev)
void
audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key)
{
- char *fp;
+ char *key_fp = NULL;
+ char *issuer_fp = NULL;
+ struct sshkey_cert *cert = NULL;
- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0)
+ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
+ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) {
+ cert = key->cert;
+ issuer_fp = sshkey_fingerprint(cert->signature_key,
+ options.fingerprint_hash, SSH_FP_DEFAULT);
+ }
+ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0)
*rv = -SSH_ERR_INTERNAL_ERROR;
- free(fp);
+ if (key_fp)
+ free(key_fp);
+ if (issuer_fp)
+ free(issuer_fp);
}
void
diff -up openssh-9.0p1/audit.h.patch openssh-9.0p1/audit.h
--- openssh-9.0p1/audit.h.patch 2022-10-24 15:02:16.544858331 +0200
+++ openssh-9.0p1/audit.h 2022-10-24 14:58:20.887565518 +0200
@@ -64,7 +64,7 @@ void audit_session_close(struct logininf
int audit_run_command(struct ssh *, const char *);
void audit_end_command(struct ssh *, int, const char *);
ssh_audit_event_t audit_classify_auth(const char *);
-int audit_keyusage(struct ssh *, int, char *, int);
+int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int);
void audit_key(struct ssh *, int, int *, const struct sshkey *);
void audit_unsupported(struct ssh *, int);
void audit_kex(struct ssh *, int, char *, char *, char *, char *);
diff -up openssh-9.0p1/audit-linux.c.patch openssh-9.0p1/audit-linux.c
--- openssh-9.0p1/audit-linux.c.patch 2022-10-24 15:02:16.544858331 +0200
+++ openssh-9.0p1/audit-linux.c 2022-10-24 15:21:58.165303951 +0200
@@ -137,10 +137,12 @@ fatal_report:
}
int
-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv)
+audit_keyusage(struct ssh *ssh, int host_user, const char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv)
{
char buf[AUDIT_LOG_SIZE];
int audit_fd, rc, saved_errno;
+ const char *rip;
+ u_int i;
audit_fd = audit_open();
if (audit_fd < 0) {
@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host
else
return 0; /* Must prevent login */
}
+ rip = ssh_remote_ipaddr(ssh);
snprintf(buf, sizeof(buf), "%s_auth grantors=auth-key", host_user ? "pubkey" : "hostbased");
rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
- buf, audit_username(), -1, NULL, ssh_remote_ipaddr(ssh), NULL, rv);
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
goto out;
- snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", fp);
+ snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", key_fp);
rc = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, buf, NULL,
- ssh_remote_ipaddr(ssh), NULL, rv);
+ rip, NULL, rv);
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
+ goto out;
+
+ if (cert) {
+ char *pbuf;
+
+ pbuf = audit_encode_nv_string("key_id", cert->key_id, 0);
+ if (pbuf == NULL)
+ goto out;
+ snprintf(buf, sizeof(buf), "cert %s cert_serial=%llu cert_issuer_alg=\"%s\" cert_issuer_fp=\"%s\"",
+ pbuf, (unsigned long long)cert->serial, sshkey_type(cert->signature_key), issuer_fp);
+ free(pbuf);
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
+ goto out;
+
+ for (i = 0; cert->principals != NULL && i < cert->nprincipals; i++) {
+ pbuf = audit_encode_nv_string("cert_principal", cert->principals[i], 0);
+ if (pbuf == NULL)
+ goto out;
+ snprintf(buf, sizeof(buf), "principal %s", pbuf);
+ free(pbuf);
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
+ goto out;
+ }
+ }
out:
saved_errno = errno;
audit_close(audit_fd);

View file

@ -1,292 +0,0 @@
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/dh.c openssh-9.0p1-patched/dh.c
--- openssh-9.0p1/dh.c 2023-05-25 09:24:28.730868316 +0200
+++ openssh-9.0p1-patched/dh.c 2023-05-25 09:23:44.841379532 +0200
@@ -37,6 +37,9 @@
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/fips.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "dh.h"
#include "pathnames.h"
@@ -290,10 +293,15 @@
int
dh_gen_key(DH *dh, int need)
{
- int pbits;
- const BIGNUM *dh_p, *pub_key;
+ const BIGNUM *dh_p, *dh_g;
+ BIGNUM *pub_key = NULL, *priv_key = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ int pbits, r = 0;
- DH_get0_pqg(dh, &dh_p, NULL, NULL);
+ DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
if (need < 0 || dh_p == NULL ||
(pbits = BN_num_bits(dh_p)) <= 0 ||
@@ -301,19 +309,85 @@
return SSH_ERR_INVALID_ARGUMENT;
if (need < 256)
need = 256;
+
+ if ((param_bld = OSSL_PARAM_BLD_new()) == NULL ||
+ (ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL) {
+ OSSL_PARAM_BLD_free(param_bld);
+ return SSH_ERR_ALLOC_FAIL;
+ }
+
+ if (OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_FFC_P, dh_p) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_FFC_G, dh_g) != 1) {
+ error_f("Could not set p,q,g parameters");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
/*
* Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
* so double requested need here.
*/
- if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
- return SSH_ERR_LIBCRYPTO_ERROR;
-
- if (DH_generate_key(dh) == 0)
- return SSH_ERR_LIBCRYPTO_ERROR;
- DH_get0_key(dh, &pub_key, NULL);
- if (!dh_pub_is_valid(dh, pub_key))
- return SSH_ERR_INVALID_FORMAT;
- return 0;
+ if (OSSL_PARAM_BLD_push_int(param_bld,
+ OSSL_PKEY_PARAM_DH_PRIV_LEN,
+ MINIMUM(need * 2, pbits - 1)) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata_init(ctx) != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata(ctx, &pkey,
+ EVP_PKEY_KEY_PARAMETERS, params) != 1) {
+ error_f("Failed key generation");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* reuse context for key generation */
+ EVP_PKEY_CTX_free(ctx);
+ ctx = NULL;
+
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ EVP_PKEY_keygen_init(ctx) != 1) {
+ error_f("Could not create or init context");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_generate(ctx, &pkey) != 1) {
+ error_f("Could not generate keys");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_public_check(ctx) != 1) {
+ error_f("The public key is incorrect");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
+ &pub_key) != 1 ||
+ EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
+ &priv_key) != 1 ||
+ DH_set0_key(dh, pub_key, priv_key) != 1) {
+ error_f("Could not set pub/priv keys to DH struct");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* transferred */
+ pub_key = NULL;
+ priv_key = NULL;
+out:
+ OSSL_PARAM_free(params);
+ OSSL_PARAM_BLD_free(param_bld);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ BN_clear_free(pub_key);
+ BN_clear_free(priv_key);
+ return r;
}
DH *
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.c openssh-9.0p1-patched/kex.c
--- openssh-9.0p1/kex.c 2023-05-25 09:24:28.731868327 +0200
+++ openssh-9.0p1-patched/kex.c 2023-05-25 09:23:44.841379532 +0200
@@ -1623,3 +1623,47 @@
return r;
}
+#ifdef WITH_OPENSSL
+/*
+ * Creates an EVP_PKEY from the given parameters and keys.
+ * The private key can be omitted.
+ */
+int
+kex_create_evp_dh(EVP_PKEY **pkey, const BIGNUM *p, const BIGNUM *q,
+ const BIGNUM *g, const BIGNUM *pub, const BIGNUM *priv)
+{
+ OSSL_PARAM_BLD *param_bld = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ int r = 0;
+
+ /* create EVP_PKEY-DH key */
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
+ error_f("EVP_PKEY_CTX or PARAM_BLD init failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_PUB_KEY, pub) != 1) {
+ error_f("Failed pushing params to OSSL_PARAM_BLD");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (priv != NULL &&
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
+ error_f("Failed pushing private key to OSSL_PARAM_BLD");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL)
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+out:
+ OSSL_PARAM_BLD_free(param_bld);
+ EVP_PKEY_CTX_free(ctx);
+ return r;
+}
+#endif /* WITH_OPENSSL */
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kexdh.c openssh-9.0p1-patched/kexdh.c
--- openssh-9.0p1/kexdh.c 2023-05-25 09:24:28.674867692 +0200
+++ openssh-9.0p1-patched/kexdh.c 2023-05-25 09:25:28.494533889 +0200
@@ -35,6 +35,10 @@
#include "openbsd-compat/openssl-compat.h"
#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "sshkey.h"
#include "kex.h"
@@ -83,9 +87,12 @@
kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out)
{
BIGNUM *shared_secret = NULL;
+ const BIGNUM *pub, *priv, *p, *q, *g;
+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
u_char *kbuf = NULL;
size_t klen = 0;
- int kout, r;
+ int kout, r = 0;
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_pub= ");
@@ -100,24 +107,59 @@
r = SSH_ERR_MESSAGE_INCOMPLETE;
goto out;
}
- klen = DH_size(kex->dh);
+
+ DH_get0_key(kex->dh, &pub, &priv);
+ DH_get0_pqg(kex->dh, &p, &q, &g);
+ /* import key */
+ r = kex_create_evp_dh(&pkey, p, q, g, pub, priv);
+ if (r != 0) {
+ error_f("Could not create EVP_PKEY for dh");
+ ERR_print_errors_fp(stderr);
+ goto out;
+ }
+ /* import peer key
+ * the parameters should be the same as with pkey
+ */
+ r = kex_create_evp_dh(&dh_pkey, p, q, g, dh_pub, NULL);
+ if (r != 0) {
+ error_f("Could not import peer key for dh");
+ ERR_print_errors_fp(stderr);
+ goto out;
+ }
+
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL) {
+ error_f("Could not init EVP_PKEY_CTX for dh");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (EVP_PKEY_derive_init(ctx) != 1 ||
+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
+ error_f("Could not get key size");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
if ((kbuf = malloc(klen)) == NULL ||
(shared_secret = BN_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((kout = DH_compute_key(kbuf, dh_pub, kex->dh)) < 0 ||
- BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1 ||
+ BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
+ error_f("Could not derive key");
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
+ dump_digest("shared secret", kbuf, klen);
#endif
r = sshbuf_put_bignum2(out, shared_secret);
out:
freezero(kbuf, klen);
BN_clear_free(shared_secret);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(dh_pkey);
+ EVP_PKEY_CTX_free(ctx);
return r;
}
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.h openssh-9.0p1-patched/kex.h
--- openssh-9.0p1/kex.h 2023-05-25 09:24:28.725868260 +0200
+++ openssh-9.0p1-patched/kex.h 2023-05-25 09:23:44.841379532 +0200
@@ -33,6 +33,9 @@
# include <openssl/bn.h>
# include <openssl/dh.h>
# include <openssl/ecdsa.h>
+# include <openssl/evp.h>
+# include <openssl/core_names.h>
+# include <openssl/param_build.h>
# ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
# else /* OPENSSL_HAS_ECC */
@@ -283,6 +286,8 @@
const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int)
__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
+int kex_create_evp_dh(EVP_PKEY **, const BIGNUM *, const BIGNUM *,
+ const BIGNUM *, const BIGNUM *, const BIGNUM *);
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
void dump_digest(const char *, const u_char *, int);

View file

@ -1,207 +0,0 @@
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../openssh-8.7p1/kexecdh.c ./kexecdh.c
--- ../openssh-8.7p1/kexecdh.c 2021-08-20 06:03:49.000000000 +0200
+++ ./kexecdh.c 2023-04-13 14:30:14.882449593 +0200
@@ -35,17 +35,57 @@
#include <signal.h>
#include <openssl/ecdh.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
+#include <openssl/err.h>
#include "sshkey.h"
#include "kex.h"
#include "sshbuf.h"
#include "digest.h"
#include "ssherr.h"
+#include "log.h"
static int
kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key,
const EC_GROUP *, struct sshbuf **);
+static EC_KEY *
+generate_ec_keys(int ec_nid)
+{
+ EC_KEY *client_key = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ const char *group_name;
+
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL)
+ goto out;
+ if ((group_name = OSSL_EC_curve_nid2name(ec_nid)) == NULL ||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ error_f("Could not create OSSL_PARAM");
+ goto out;
+ }
+ if (EVP_PKEY_keygen_init(ctx) != 1 ||
+ EVP_PKEY_CTX_set_params(ctx, params) != 1 ||
+ EVP_PKEY_generate(ctx, &pkey) != 1 ||
+ (client_key = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
+ error_f("Could not generate ec keys");
+ goto out;
+ }
+out:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_BLD_free(param_bld);
+ OSSL_PARAM_free(params);
+ return client_key;
+}
+
int
kex_ecdh_keypair(struct kex *kex)
{
@@ -55,11 +95,7 @@
struct sshbuf *buf = NULL;
int r;
- if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(client_key) != 1) {
+ if ((client_key = generate_ec_keys(kex->ec_nid)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -101,11 +137,7 @@
*server_blobp = NULL;
*shared_secretp = NULL;
- if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(server_key) != 1) {
+ if ((server_key = generate_ec_keys(kex->ec_nid)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -140,11 +172,21 @@
{
struct sshbuf *buf = NULL;
BIGNUM *shared_secret = NULL;
- EC_POINT *dh_pub = NULL;
- u_char *kbuf = NULL;
- size_t klen = 0;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ u_char *kbuf = NULL, *pub = NULL;
+ size_t klen = 0, publen;
+ const char *group_name;
int r;
+ /* import EC_KEY to EVP_PKEY */
+ if ((r = ssh_create_evp_ec(key, kex->ec_nid, &pkey)) != 0) {
+ error_f("Could not create EVP_PKEY");
+ goto out;
+ }
+
*shared_secretp = NULL;
if ((buf = sshbuf_new()) == NULL) {
@@ -153,45 +195,82 @@
}
if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0)
goto out;
- if ((dh_pub = EC_POINT_new(group)) == NULL) {
+
+ /* the public key is in the buffer in octet string UNCOMPRESSED
+ * format. See sshbuf_put_ec */
+ if ((r = sshbuf_get_string(buf, &pub, &publen)) != 0)
+ goto out;
+ sshbuf_reset(buf);
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_get_ec(buf, dh_pub, group)) != 0) {
+ if ((group_name = OSSL_EC_curve_nid2name(kex->ec_nid)) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (OSSL_PARAM_BLD_push_octet_string(param_bld,
+ OSSL_PKEY_PARAM_PUB_KEY, pub, publen) != 1 ||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ error_f("Failed to set params for dh_pkey");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata_init(ctx) != 1 ||
+ EVP_PKEY_fromdata(ctx, &dh_pkey,
+ EVP_PKEY_PUBLIC_KEY, params) != 1 ||
+ EVP_PKEY_public_check(ctx) != 1) {
+ error_f("Peer public key import failed");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- sshbuf_reset(buf);
#ifdef DEBUG_KEXECDH
fputs("public key:\n", stderr);
- sshkey_dump_ec_point(group, dh_pub);
+ EVP_PKEY_print_public_fp(stderr, dh_pkey, 0, NULL);
#endif
- if (sshkey_ec_validate_public(group, dh_pub) != 0) {
- r = SSH_ERR_MESSAGE_INCOMPLETE;
+ EVP_PKEY_CTX_free(ctx);
+ ctx = NULL;
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ EVP_PKEY_derive_init(ctx) != 1 ||
+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
+ error_f("Failed to get derive information");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- klen = (EC_GROUP_get_degree(group) + 7) / 8;
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
+ if ((kbuf = malloc(klen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen ||
- BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
#ifdef DEBUG_KEXECDH
dump_digest("shared secret", kbuf, klen);
#endif
+ if ((shared_secret = BN_new()) == NULL ||
+ (BN_bin2bn(kbuf, klen, shared_secret) == NULL)) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0)
goto out;
*shared_secretp = buf;
buf = NULL;
out:
- EC_POINT_clear_free(dh_pub);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(dh_pkey);
+ OSSL_PARAM_BLD_free(param_bld);
+ OSSL_PARAM_free(params);
BN_clear_free(shared_secret);
freezero(kbuf, klen);
+ freezero(pub, publen);
sshbuf_free(buf);
return r;
}

File diff suppressed because it is too large Load diff

View file

@ -1,40 +0,0 @@
--- openssh-9.3p1/openbsd-compat/openssl-compat.c 2023-03-15 22:28:19.000000000 +0100
+++ /home/dbelyavs/work/upstream/openssh-portable/openbsd-compat/openssl-compat.c 2023-05-25 14:19:42.870841944 +0200
@@ -33,10 +33,10 @@
/*
* OpenSSL version numbers: MNNFFPPS: major minor fix patch status
- * We match major, minor, fix and status (not patch) for <1.0.0.
- * After that, we acceptable compatible fix versions (so we
- * allow 1.0.1 to work with 1.0.0). Going backwards is only allowed
- * within a patch series.
+ * Versions >=3 require only major versions to match.
+ * For versions <3, we accept compatible fix versions (so we allow 1.0.1
+ * to work with 1.0.0). Going backwards is only allowed within a patch series.
+ * See https://www.openssl.org/policies/releasestrat.html
*/
int
@@ -48,15 +48,17 @@
if (headerver == libver)
return 1;
- /* for versions < 1.0.0, major,minor,fix,status must match */
- if (headerver < 0x1000000f) {
- mask = 0xfffff00fL; /* major,minor,fix,status */
+ /*
+ * For versions >= 3.0, only the major and status must match.
+ */
+ if (headerver >= 0x3000000f) {
+ mask = 0xf000000fL; /* major,status */
return (headerver & mask) == (libver & mask);
}
/*
- * For versions >= 1.0.0, major,minor,status must match and library
- * fix version must be equal to or newer than the header.
+ * For versions >= 1.0.0, but <3, major,minor,status must match and
+ * library fix version must be equal to or newer than the header.
*/
mask = 0xfff0000fL; /* major,minor,status */
hfix = (headerver & 0x000ff000) >> 12;

View file

@ -1,130 +0,0 @@
diff --git a/ssh-agent.c b/ssh-agent.c
index 618bb198..8ea831f4 100644
diff -up openssh-9.3p1/ssh-agent.c.cve openssh-9.3p1/ssh-agent.c
--- openssh-9.3p1/ssh-agent.c.cve 2023-07-21 15:38:13.237276580 +0200
+++ openssh-9.3p1/ssh-agent.c 2023-07-21 15:41:30.269943569 +0200
@@ -169,6 +169,12 @@ char socket_dir[PATH_MAX];
/* Pattern-list of allowed PKCS#11/Security key paths */
static char *allowed_providers;
+/*
+ * Allows PKCS11 providers or SK keys that use non-internal providers to
+ * be added over a remote connection (identified by session-bind@openssh.com).
+ */
+static int remote_add_provider;
+
/* locking */
#define LOCK_SIZE 32
#define LOCK_SALT_SIZE 16
@@ -1228,6 +1234,12 @@ process_add_identity(SocketEntry *e)
if (strcasecmp(sk_provider, "internal") == 0) {
debug_f("internal provider");
} else {
+ if (e->nsession_ids != 0 && !remote_add_provider) {
+ verbose("failed add of SK provider \"%.100s\": "
+ "remote addition of providers is disabled",
+ sk_provider);
+ goto out;
+ }
if (realpath(sk_provider, canonical_provider) == NULL) {
verbose("failed provider \"%.100s\": "
"realpath: %s", sk_provider,
@@ -1368,7 +1380,7 @@ no_identities(SocketEntry *e)
#ifdef ENABLE_PKCS11
static char *
-sanitize_pkcs11_provider(const char *provider)
+sanitize_pkcs11_provider(SocketEntry *e, const char *provider)
{
struct pkcs11_uri *uri = NULL;
char *sane_uri, *module_path = NULL; /* default path */
@@ -1399,6 +1411,11 @@ sanitize_pkcs11_provider(const char *pro
module_path = strdup(provider); /* simple path */
if (module_path != NULL) { /* do not validate default NULL path in URI */
+ if (e->nsession_ids != 0 && !remote_add_provider) {
+ verbose("failed PKCS#11 add of \"%.100s\": remote addition of "
+ "providers is disabled", provider);
+ return NULL;
+ }
if (realpath(module_path, canonical_provider) == NULL) {
verbose("failed PKCS#11 provider \"%.100s\": realpath: %s",
module_path, strerror(errno));
@@ -1455,7 +1472,7 @@ process_add_smartcard_key(SocketEntry *e
goto send;
}
- sane_uri = sanitize_pkcs11_provider(provider);
+ sane_uri = sanitize_pkcs11_provider(e, provider);
if (sane_uri == NULL)
goto send;
@@ -1516,7 +1533,7 @@ process_remove_smartcard_key(SocketEntry
}
free(pin);
- sane_uri = sanitize_pkcs11_provider(provider);
+ sane_uri = sanitize_pkcs11_provider(e, provider);
if (sane_uri == NULL)
goto send;
@@ -2108,7 +2125,9 @@ main(int ac, char **av)
break;
case 'O':
if (strcmp(optarg, "no-restrict-websafe") == 0)
- restrict_websafe = 0;
+ restrict_websafe = 0;
+ else if (strcmp(optarg, "allow-remote-pkcs11") == 0)
+ remote_add_provider = 1;
else
fatal("Unknown -O option");
break;
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index 6be647ec..ebddf6c3 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1537,10 +1537,8 @@ pkcs11_register_provider(char *provider_id, char *pin,
error("dlopen %s failed: %s", provider_module, dlerror());
goto fail;
}
- if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) {
- error("dlsym(C_GetFunctionList) failed: %s", dlerror());
- goto fail;
- }
+ if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL)
+ fatal("dlsym(C_GetFunctionList) failed: %s", dlerror());
p->module->handle = handle;
/* setup the pkcs11 callbacks */
--- a/ssh-agent.1 2023-03-15 22:28:19.000000000 +0100
+++ b/ssh-agent.1 2023-07-19 21:39:17.981406432 +0200
@@ -107,9 +107,27 @@
.It Fl O Ar option
Specify an option when starting
.Nm .
-Currently only one option is supported:
+Currently two options are supported:
+.Cm allow-remote-pkcs11
+and
.Cm no-restrict-websafe .
-This instructs
+.Pp
+The
+.Cm allow-remote-pkcs11
+option allows clients of a forwarded
+.Nm
+to load PKCS#11 or FIDO provider libraries.
+By default only local clients may perform this operation.
+Note that signalling that a
+.Nm
+client remote is performed by
+.Xr ssh 1 ,
+and use of other tools to forward access to the agent socket may circumvent
+this restriction.
+.Pp
+The
+.Cm no-restrict-websafe ,
+instructs
.Nm
to permit signatures using FIDO keys that might be web authentication
requests.

View file

@ -2,9 +2,7 @@
addFilter(r'openssh-askpass.x86_64: W: non-conffile-in-etc /etc/profile.d/gnome-ssh-askpass.c?sh')
# The ssh-keysign is not supposed to have standard permissions
addFilter(r'openssh.x86_64: E: non-standard-executable-perm /usr/libexec/openssh/ssh-keysign 2555')
addFilter(r'openssh.x86_64: E: setgid-binary /usr/libexec/openssh/ssh-keysign ssh_keys 2555')
addFilter(r'openssh.x86_64: W: non-standard-gid /usr/libexec/openssh/ssh-keysign ssh_keys')
addFilter(r'openssh.x86_64: E: non-standard-executable-perm /usr/libexec/openssh/ssh-keysign 4555')
# The -cavs subpackage is internal without documentation
# The -askpass is not intended to be used directly so it is missing documentation

View file

@ -25,13 +25,6 @@
# Do we want libedit support
%global libedit 1
# Whether to build pam_ssh_agent_auth
%if 0%{?!nopam:1}
%global pam_ssh_agent 1
%else
%global pam_ssh_agent 0
%endif
# Reserve options to override askpass settings with:
# rpm -ba|--rebuild --define 'skip_xxx 1'
%{?skip_gnome_askpass:%global no_gnome_askpass 1}
@ -45,24 +38,17 @@
# rpm -ba|--rebuild --define "static_openssl 1"
%{?static_openssl:%global static_libcrypto 1}
# Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1
%global openssh_ver 9.3p1
%global openssh_rel 13
%global pam_ssh_agent_ver 0.10.4
%global pam_ssh_agent_rel 9
%global openssh_ver 10.2p1
Summary: An open source implementation of SSH protocol version 2
Name: openssh
Version: %{openssh_ver}
Release: %{openssh_rel}%{?dist}.1
Release: 1%{?dist}
URL: http://www.openssh.com/portable.html
#URL1: https://github.com/jbeverly/pam_ssh_agent_auth/
Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
Source1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc
Source2: sshd.pam
Source3: gpgkey-736060BA.gpg
Source4: https://github.com/jbeverly/pam_ssh_agent_auth/archive/pam_ssh_agent_auth-%{pam_ssh_agent_ver}.tar.gz
Source5: pam_ssh_agent-rmheaders
Source6: ssh-keycat.pam
Source7: sshd.sysconfig
Source9: sshd@.service
@ -76,164 +62,123 @@ Source17: ssh-agent.socket
Source19: openssh-server-systemd-sysusers.conf
Source20: ssh-host-keys-migration.sh
Source21: ssh-host-keys-migration.service
#https://bugzilla.mindrot.org/show_bug.cgi?id=2581
Patch100: openssh-6.7p1-coverity.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1402
# https://bugzilla.redhat.com/show_bug.cgi?id=1171248
# record pfs= field in CRYPTO_SESSION audit event
Patch200: openssh-7.6p1-audit.patch
# Audit race condition in forked child (#1310684)
Patch201: openssh-7.1p2-audit-race-condition.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2049947
Patch202: openssh-9.0p1-audit-log.patch
# --- pam_ssh-agent ---
# make it build reusing the openssh sources
Patch300: pam_ssh_agent_auth-0.9.3-build.patch
# check return value of seteuid()
# https://sourceforge.net/p/pamsshagentauth/bugs/23/
Patch301: pam_ssh_agent_auth-0.10.3-seteuid.patch
# explicitly make pam callbacks visible
Patch302: pam_ssh_agent_auth-0.9.2-visibility.patch
# update to current version of agent structure
Patch305: pam_ssh_agent_auth-0.9.3-agent_structure.patch
# remove prefixes to be able to build against current openssh library
Patch306: pam_ssh_agent_auth-0.10.2-compat.patch
# Fix NULL dereference from getpwuid() return value
# https://sourceforge.net/p/pamsshagentauth/bugs/22/
Patch307: pam_ssh_agent_auth-0.10.2-dereference.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2070113
Patch308: pam_ssh_agent_auth-0.10.4-rsasha2.patch
Patch309: pam_ssh_agent-configure-c99.patch
Source22: parallel_test.sh
Source23: parallel_test.Makefile
#https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
Patch400: openssh-7.8p1-role-mls.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=781634
Patch404: openssh-6.6p1-privsep-selinux.patch
#?
Patch502: openssh-6.6p1-keycat.patch
Patch0001: 0001-openssh-7.8p1-role-mls.patch
Patch0002: 0002-openssh-6.6p1-keycat.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1644
Patch601: openssh-6.6p1-allow-ip-opts.patch
Patch0003: 0003-openssh-6.6p1-allow-ip-opts.patch
#(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925
Patch606: openssh-5.9p1-ipv6man.patch
#?
Patch607: openssh-5.8p2-sigpipe.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1789
Patch609: openssh-7.2p2-x11.patch
#?
Patch700: openssh-7.7p1-fips.patch
#?
Patch702: openssh-5.1p1-askpass-progress.patch
Patch0004: 0004-openssh-5.9p1-ipv6man.patch
Patch0005: 0005-openssh-5.8p2-sigpipe.patch
Patch0006: 0006-openssh-7.2p2-x11.patch
Patch0007: 0007-openssh-5.1p1-askpass-progress.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=198332
Patch703: openssh-4.3p2-askpass-grab-info.patch
Patch0008: 0008-openssh-4.3p2-askpass-grab-info.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
Patch707: openssh-7.7p1-redhat.patch
Patch0009: 0009-openssh-8.7p1-redhat.patch
# warn users for unsupported UsePAM=no (#757545)
Patch711: openssh-7.8p1-UsePAM-warning.patch
Patch0010: 0010-openssh-7.8p1-UsePAM-warning.patch
# GSSAPI Key Exchange (RFC 4462 + RFC 8732)
# from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master
# and
# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures
# upstream MR:
# https://github.com/openssh-gsskex/openssh-gsskex/pull/21
Patch800: openssh-8.0p1-gssapi-keyex.patch
Patch0011: 0011-openssh-9.6p1-gssapi-keyex.patch
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
Patch801: openssh-6.6p1-force_krb.patch
# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843)
# CVE-2014-9278
Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch
Patch0012: 0012-openssh-6.6p1-force_krb.patch
# Improve ccache handling in openssh (#991186, #1199363, #1566494)
# https://bugzilla.mindrot.org/show_bug.cgi?id=2775
Patch804: openssh-7.7p1-gssapi-new-unique.patch
Patch0013: 0013-openssh-7.7p1-gssapi-new-unique.patch
# Respect k5login_directory option in krk5.conf (#1328243)
Patch805: openssh-7.2p2-k5login_directory.patch
Patch0014: 0014-openssh-7.2p2-k5login_directory.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
Patch901: openssh-6.6p1-kuserok.patch
Patch0015: 0015-openssh-6.6p1-kuserok.patch
# Use tty allocation for a remote scp (#985650)
Patch906: openssh-6.4p1-fromto-remote.patch
# privsep_preauth: use SELinux context from selinux-policy (#1008580)
Patch916: openssh-6.6.1p1-selinux-contexts.patch
Patch0016: 0016-openssh-6.4p1-fromto-remote.patch
# log via monitor in chroots without /dev/log (#2681)
Patch918: openssh-6.6.1p1-log-in-chroot.patch
Patch0017: 0017-openssh-6.6.1p1-log-in-chroot.patch
# scp file into non-existing directory (#1142223)
Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch
Patch0018: 0018-openssh-6.6.1p1-scp-non-existing-directory.patch
# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843)
# CVE-2014-9278
Patch0019: 0019-openssh-6.6p1-GSSAPIEnablek5users.patch
# apply upstream patch and make sshd -T more consistent (#1187521)
Patch922: openssh-6.8p1-sshdT-output.patch
Patch0020: 0020-openssh-6.8p1-sshdT-output.patch
# Add sftp option to force mode of created files (#1191055)
Patch926: openssh-6.7p1-sftp-force-permission.patch
Patch0021: 0021-openssh-6.7p1-sftp-force-permission.patch
# make s390 use /dev/ crypto devices -- ignore closefrom
Patch939: openssh-7.2p2-s390-closefrom.patch
# Move MAX_DISPLAYS to a configuration option (#1341302)
Patch944: openssh-7.3p1-x11-max-displays.patch
# Help systemd to track the running service
Patch948: openssh-7.4p1-systemd.patch
Patch0022: 0022-openssh-7.2p2-s390-closefrom.patch
# Pass inetd flags for SELinux down to openbsd compat level
Patch949: openssh-7.6p1-cleanup-selinux.patch
Patch0023: 0023-openssh-7.6p1-cleanup-selinux.patch
# Sandbox adjustments for s390 and audit
Patch950: openssh-7.5p1-sandbox.patch
# PKCS#11 URIs (upstream #2817, 2nd iteration)
# https://github.com/Jakuje/openssh-portable/commits/jjelen-pkcs11
# git show > ~/devel/fedora/openssh/openssh-8.0p1-pkcs11-uri.patch
Patch951: openssh-8.0p1-pkcs11-uri.patch
Patch0024: 0024-openssh-7.5p1-sandbox.patch
# Unbreak scp between two IPv6 hosts (#1620333)
Patch953: openssh-7.8p1-scp-ipv6.patch
Patch0025: 0025-openssh-7.8p1-scp-ipv6.patch
# Mention crypto-policies in manual pages (#1668325)
# clarify rhbz#2068423 on the man page of ssh_config
Patch962: openssh-8.0p1-crypto-policies.patch
# Use OpenSSL high-level API to produce and verify signatures (#1707485)
# TODO fix the comment above ^
Patch963: openssh-9.3p1-merged-openssl-evp.patch
Patch0026: 0026-openssh-8.0p1-crypto-policies.patch
# Use OpenSSL KDF (#1631761)
Patch964: openssh-8.0p1-openssl-kdf.patch
Patch0027: 0027-openssh-8.0p1-openssl-kdf.patch
# sk-dummy.so built with -fvisibility=hidden does not work
Patch965: openssh-8.2p1-visibility.patch
Patch0028: 0028-openssh-8.2p1-visibility.patch
# Do not break X11 without IPv6
Patch966: openssh-8.2p1-x11-without-ipv6.patch
# ssh-keygen printing fingerprint issue with Windows keys (#1901518)
Patch974: openssh-8.0p1-keygen-strip-doseol.patch
Patch0029: 0029-openssh-8.2p1-x11-without-ipv6.patch
# sshd provides PAM an incorrect error code (#1879503)
Patch975: openssh-8.0p1-preserve-pam-errors.patch
Patch0030: 0030-openssh-8.0p1-preserve-pam-errors.patch
# Implement kill switch for SCP protocol
Patch977: openssh-8.7p1-scp-kill-switch.patch
Patch0031: 0031-openssh-8.7p1-scp-kill-switch.patch
# Workaround for lack of sftp_realpath in older versions of RHEL
# https://bugzilla.redhat.com/show_bug.cgi?id=2038854
# https://github.com/openssh/openssh-portable/pull/299
# downstream only
Patch981: openssh-8.7p1-recursive-scp.patch
# https://github.com/djmdjm/openssh-wip/pull/13
Patch982: openssh-8.7p1-minrsabits.patch
Patch0032: 0032-openssh-8.7p1-recursive-scp.patch
# Downstream alias for MinRSABits
Patch0033: 0033-openssh-8.7p1-minrsabits.patch
# downstream only, IBMCA tentative fix
# From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14
Patch984: openssh-8.7p1-ibmca.patch
Patch0034: 0034-openssh-8.7p1-ibmca.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1402
# https://bugzilla.redhat.com/show_bug.cgi?id=1171248
# record pfs= field in CRYPTO_SESSION audit event
Patch0035: 0035-openssh-7.6p1-audit.patch
# Audit race condition in forked child (#1310684)
Patch0036: 0036-openssh-7.1p2-audit-race-condition.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2049947
Patch0037: 0037-openssh-9.0p1-audit-log.patch
Patch0038: 0038-openssh-7.7p1-fips.patch
# Add missing options from ssh_config into ssh manpage
# upstream bug:
# https://bugzilla.mindrot.org/show_bug.cgi?id=3455
Patch1002: openssh-8.7p1-ssh-manpage.patch
Patch0039: 0039-openssh-8.7p1-ssh-manpage.patch
# Don't propose disallowed algorithms during hostkey negotiation
# upstream MR:
# https://github.com/openssh/openssh-portable/pull/323
Patch1006: openssh-8.7p1-negotiate-supported-algs.patch
Patch1012: openssh-9.0p1-evp-fips-dh.patch
Patch1013: openssh-9.0p1-evp-fips-ecdh.patch
Patch1014: openssh-8.7p1-nohostsha1proof.patch
Patch1015: openssh-9.3p1-upstream-cve-2023-38408.patch
# upstream b7afd8a4ecaca8afd3179b55e9db79c0ff210237
Patch1016: openssh-9.3p1-openssl-compat.patch
Patch0040: 0040-openssh-8.7p1-negotiate-supported-algs.patch
Patch0041: 0041-openssh-9.0p1-evp-fips-kex.patch
Patch0042: 0042-openssh-8.7p1-nohostsha1proof.patch
Patch0043: 0043-openssh-9.9p1-separate-keysign.patch
Patch0044: 0044-openssh-9.9p1-openssl-mlkem.patch
# https://www.openwall.com/lists/oss-security/2025/02/22/1
Patch0045: 0045-openssh-9.9p2-error_processing.patch
# https://github.com/openssh/openssh-portable/pull/564
Patch0046: 0046-Provide-better-error-for-non-supported-private-keys.patch
# https://github.com/openssh/openssh-portable/pull/567
Patch0047: 0047-Ignore-bad-hostkeys-in-known_hosts-file.patch
# https://github.com/openssh/openssh-portable/pull/500
Patch0048: 0048-support-authentication-indicators-in-GSSAPI.patch
Patch0049: 0049-NIST-curves-hybrid-KEX-implementation.patch
# landed upstream, to be removed after 10.3
Patch0050: 0050-Provide-a-way-to-disable-GSSAPIDelegateCredentials-s.patch
# Move MAX_DISPLAYS to a configuration option (#1341302)
Patch0051: 0051-openssh-7.3p1-x11-max-displays.patch
# PKCS#11 URIs (upstream #2817, seriously reworked on rebasing to 10.2)
# https://github.com/Jakuje/openssh-portable/commits/jjelen-pkcs11
Patch0052: 0052-openssh-10.2p1-pkcs11-uri.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=2581
Patch1000: 1000-openssh-6.7p1-coverity.patch
License: BSD-3-Clause AND BSD-2-Clause AND ISC AND SSH-OpenSSH AND ssh-keyscan AND sprintf AND LicenseRef-Fedora-Public-Domain AND X11-distribute-modifications-variant
Requires: /sbin/nologin
Requires: openssl-libs >= 3.5.0
%if ! %{no_gnome_askpass}
BuildRequires: libX11-devel
@ -248,13 +193,14 @@ BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel
BuildRequires: audit-libs-devel >= 2.0.5
BuildRequires: util-linux, groff
BuildRequires: pam-devel
BuildRequires: openssl-devel >= 0.9.8j
BuildRequires: openssl-devel >= 3.5.0
BuildRequires: perl-podlators
BuildRequires: systemd-devel
BuildRequires: systemd-rpm-macros
BuildRequires: gcc make
BuildRequires: p11-kit-devel
BuildRequires: libfido2-devel
BuildRequires: libxcrypt-devel
Recommends: p11-kit
Obsoletes: openssh-ldap < 8.3p1-4
Obsoletes: openssh-cavs < 8.4p1-5
@ -283,6 +229,10 @@ Summary: An open source SSH client applications
Requires: openssh = %{version}-%{release}
Requires: crypto-policies >= 20220824-1
%package keysign
Summary: A helper program used for host-based authentication
Requires: openssh = %{version}-%{release}
%package server
Summary: An open source SSH server daemon
Requires: openssh = %{version}-%{release}
@ -303,12 +253,6 @@ Requires: openssh = %{version}-%{release}
Summary: OpenSSH SK driver for test purposes
Requires: openssh = %{version}-%{release}
%package -n pam_ssh_agent_auth
Summary: PAM module for authentication with ssh-agent
Version: %{pam_ssh_agent_ver}
Release: %{pam_ssh_agent_rel}.%{openssh_rel}%{?dist}.1
License: BSD-3-Clause AND BSD-2-Clause AND ISC AND SSH-OpenSSH AND ssh-keyscan AND sprintf AND LicenseRef-Fedora-Public-Domain AND X11-distribute-modifications-variant AND OpenSSL
%description
SSH (Secure SHell) is a program for logging into and executing
commands on a remote machine. SSH is intended to replace rlogin and
@ -328,6 +272,11 @@ OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. This package includes
the clients necessary to make encrypted connections to SSH servers.
%description keysign
OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. ssh-keysign is a
helper program used for host-based authentication disabled by default.
%description server
OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. This package contains
@ -346,108 +295,14 @@ an X11 passphrase dialog for OpenSSH.
%description sk-dummy
This package contains a test SK driver used for OpenSSH test purposes
%description -n pam_ssh_agent_auth
This package contains a PAM module which can be used to authenticate
users using ssh keys stored in a ssh-agent. Through the use of the
forwarding of ssh-agent connection it also allows to authenticate with
remote ssh-agent instance.
The module is most useful for su and sudo service stacks.
%prep
gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%setup -q -a 4
%if %{pam_ssh_agent}
pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
%patch -P 300 -p2 -b .psaa-build
%patch -P 301 -p2 -b .psaa-seteuid
%patch -P 302 -p2 -b .psaa-visibility
%patch -P 306 -p2 -b .psaa-compat
%patch -P 305 -p2 -b .psaa-agent
%patch -P 307 -p2 -b .psaa-deref
%patch -P 308 -p2 -b .rsasha2
%patch -P 309 -p1 -b .psaa-configure-c99
# Remove duplicate headers and library files
rm -f $(cat %{SOURCE5})
popd
%endif
%patch -P 400 -p1 -b .role-mls
%patch -P 404 -p1 -b .privsep-selinux
%patch -P 502 -p1 -b .keycat
%patch -P 601 -p1 -b .ip-opts
%patch -P 606 -p1 -b .ipv6man
%patch -P 607 -p1 -b .sigpipe
%patch -P 609 -p1 -b .x11
%patch -P 702 -p1 -b .progress
%patch -P 703 -p1 -b .grab-info
%patch -P 707 -p1 -b .redhat
%patch -P 711 -p1 -b .log-usepam-no
#
%patch -P 800 -p1 -b .gsskex
%patch -P 801 -p1 -b .force_krb
%patch -P 804 -p1 -b .ccache_name
%patch -P 805 -p1 -b .k5login
#
%patch -P 901 -p1 -b .kuserok
%patch -P 906 -p1 -b .fromto-remote
%patch -P 916 -p1 -b .contexts
%patch -P 918 -p1 -b .log-in-chroot
%patch -P 919 -p1 -b .scp
%patch -P 802 -p1 -b .GSSAPIEnablek5users
%patch -P 922 -p1 -b .sshdt
%patch -P 926 -p1 -b .sftp-force-mode
%patch -P 939 -p1 -b .s390-dev
%patch -P 944 -p1 -b .x11max
%patch -P 948 -p1 -b .systemd
%patch -P 949 -p1 -b .refactor
%patch -P 950 -p1 -b .sandbox
%patch -P 951 -p1 -b .pkcs11-uri
%patch -P 953 -p1 -b .scp-ipv6
%patch -P 962 -p1 -b .crypto-policies
%patch -P 963 -p1 -b .openssl-evp
%patch -P 964 -p1 -b .openssl-kdf
%patch -P 965 -p1 -b .visibility
%patch -P 966 -p1 -b .x11-ipv6
%patch -P 974 -p1 -b .keygen-strip-doseol
%patch -P 975 -p1 -b .preserve-pam-errors
%patch -P 977 -p1 -b .kill-scp
%patch -P 981 -p1 -b .scp-sftpdirs
%patch -P 982 -p1 -b .minrsabits
%patch -P 984 -p1 -b .ibmca
%patch -P 200 -p1 -b .audit
%patch -P 201 -p1 -b .audit-race
%patch -P 202 -p1 -b .audit-log
%patch -P 700 -p1 -b .fips
%patch -P 1002 -p1 -b .ssh-manpage
%patch -P 1006 -p1 -b .negotiate-supported-algs
%patch -P 1012 -p1 -b .evp-fips-dh
%patch -P 1013 -p1 -b .evp-fips-ecdh
%patch -P 1014 -p1 -b .nosha1hostproof
%patch -P 1015 -p1 -b .cve-2023-38408
%patch -P 1016 -p1 -b .ossl-version
%patch -P 100 -p1 -b .coverity
%autosetup -T -b 0 -p1
autoreconf
pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
autoreconf
popd
%build
%set_build_flags
# the -fvisibility=hidden is needed for clean build of the pam_ssh_agent_auth
# it is needed for lib(open)ssh build too since it is linked to the pam module too
CFLAGS="$CFLAGS -fvisibility=hidden"; export CFLAGS
%if %{pie}
%ifarch s390 s390x sparc sparcv9 sparc64
CFLAGS="$CFLAGS -fPIC"
@ -481,16 +336,14 @@ fi
--sysconfdir=%{_sysconfdir}/ssh \
--libexecdir=%{_libexecdir}/openssh \
--datadir=%{_datadir}/openssh \
--with-default-path=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \
--with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \
--with-default-path=/usr/local/bin:/usr/bin \
--with-superuser-path=/usr/local/bin:/usr/bin \
--with-privsep-path=%{_datadir}/empty.sshd \
--disable-strip \
--without-zlib-version-check \
--with-ssl-engine \
--with-ipaddr-display \
--with-pie=no \
--without-hardening `# The hardening flags are configured by system` \
--with-systemd \
--with-default-pkcs11-provider=yes \
--with-security-key-builtin=yes \
--with-pam \
@ -538,22 +391,9 @@ fi
popd
%endif
%if %{pam_ssh_agent}
pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
LDFLAGS="$SAVE_LDFLAGS"
%configure --with-selinux \
--libexecdir=/%{_libdir}/security \
--with-mantype=man \
--without-openssl-header-check `# The check is broken`
%make_build
popd
%endif
%check
#to run tests use "--with check"
%if %{?_with_check:1}%{!?_with_check:0}
make tests
%endif
OPENSSL_CONF=/dev/null %{SOURCE22} %{SOURCE23} # ./parallel_tests.sh parallel_tests.Makefile
#make tests
%install
rm -rf $RPM_BUILD_ROOT
@ -611,12 +451,6 @@ rm -f $RPM_BUILD_ROOT/etc/profile.d/gnome-ssh-askpass.*
perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/*
%if %{pam_ssh_agent}
pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
%make_install
popd
%endif
install -m 755 -d $RPM_BUILD_ROOT%{_libdir}/sshtest/
install -m 755 regress/misc/sk-dummy/sk-dummy.so $RPM_BUILD_ROOT%{_libdir}/sshtest
@ -667,8 +501,6 @@ test -f %{sysconfig_anaconda} && \
%attr(0755,root,root) %{_bindir}/ssh-keygen
%attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1*
%attr(0755,root,root) %dir %{_libexecdir}/openssh
%attr(4555,root,root) %{_libexecdir}/openssh/ssh-keysign
%attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8*
%files clients
%attr(0755,root,root) %{_bindir}/ssh
@ -696,9 +528,15 @@ test -f %{sysconfig_anaconda} && \
%attr(0644,root,root) %{_userunitdir}/ssh-agent.service
%attr(0644,root,root) %{_userunitdir}/ssh-agent.socket
%files keysign
%attr(4555,root,root) %{_libexecdir}/openssh/ssh-keysign
%attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8*
%files server
%dir %attr(0711,root,root) %{_datadir}/empty.sshd
%attr(0755,root,root) %{_sbindir}/sshd
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-session
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-auth
%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-keygen
%attr(0644,root,root) %{_mandir}/man5/sshd_config.5*
@ -730,20 +568,184 @@ test -f %{sysconfig_anaconda} && \
%files askpass
%attr(0644,root,root) %{_sysconfdir}/profile.d/gnome-ssh-askpass.*
%attr(0755,root,root) %{_libexecdir}/openssh/gnome-ssh-askpass
%attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass
%{_libexecdir}/openssh/ssh-askpass
%endif
%files sk-dummy
%attr(0755,root,root) %{_libdir}/sshtest/sk-dummy.so
%if %{pam_ssh_agent}
%files -n pam_ssh_agent_auth
%license pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}/OPENSSH_LICENSE
%attr(0755,root,root) %{_libdir}/security/pam_ssh_agent_auth.so
%attr(0644,root,root) %{_mandir}/man8/pam_ssh_agent_auth.8*
%endif
%changelog
* Wed Dec 17 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.2p1-1
- Rebase to OpenSSH 10.2p1
* Wed Dec 10 2025 Pavol Žáčik <pzacik@redhat.com> - 10.0p1-10
- Update gssapi-keyex patch to not abort KEX without hostkey
* Mon Dec 01 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.0p1-9
- rebuilt
* Mon Nov 03 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.0p1-8
- Implement mlkem768nistp256-sha256 and mlkem1024nistp384-sha384 KEX methods
* Mon Sep 15 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.0p1-7
- rebuilt
* Thu Aug 28 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.0p1-6
- Enable GSS KEX in FIPS mode
* Thu Jul 24 2025 Fedora Release Engineering <releng@fedoraproject.org> - 10.0p1-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Fri Jun 27 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.0p1-4
- Update sshd@.service to follow upstream, mostly support ephemeral sshd keys
Submitted by Allison Karlitskaya (https://src.fedoraproject.org/rpms/openssh/pull-request/101)
Needs a SELinux counterpart.
Related: rhbz#2374928
* Mon Jun 09 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.0p1-3
- Apply patches forgot in previous respin
* Mon May 19 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.0p1-2
- Provide better diagnostics for non-supported private keys
(https://github.com/openssh/openssh-portable/pull/564)
- Ignore too short hostkeys in known_hosts file
(https://github.com/openssh/openssh-portable/pull/567)
- Switch to systemd-socket activation for ssh-agent
Resolves: rhbz#2181353
* Fri May 16 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 10.0p1-1
- Rebase to OpenSSH 10.0p1
* Thu Apr 17 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-15
- Require OpenSSL 3.5 to support PQ crypto
- Suppress systemd warning on restart sshd
* Tue Mar 18 2025 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 9.9p1-14
- Remove /usr/local/sbin from the default path too
* Tue Mar 18 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-13
- Remove /usr/sbin from the default path
Resolves: rhbz#2352387
- Export and accept COLORTERM
Resolves: rhbz#2352653
* Thu Mar 06 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-12
- Update ssh-keysign permission for RPM linter
* Wed Mar 05 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-11
- Use OpenSSL ML-KEM implementation instead of the native one
* Tue Feb 25 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-10
- Some minor fixes from Rocky Linux
https://www.openwall.com/lists/oss-security/2025/02/22/1
* Tue Feb 18 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-9
- Fix regression of Match directive processing
- Fix missing error codes set and invalid error code checks in OpenSSH. It
prevents memory exhaustion attack and a MITM attack when VerifyHostKeyDNS
is on (CVE-2025-26465, CVE-2025-26466).
* Sat Feb 01 2025 Björn Esser <besser82@fedoraproject.org> - 9.9p1-8.1
- Add explicit BR: libxcrypt-devel
* Wed Jan 29 2025 FeRD (Frank Dana) <ferdnyc@gmail.com> - 9.9p1-8
- Replace deprecated (since 8.7) ChallengeResponseAuthentication
with KbdInteractiveAuthentication, in redhat sshd config
* Mon Jan 27 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-7
- Fix regression of Match directive processing
Resolves: rhbz#2341769
* Mon Jan 27 2025 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-6
- Remove pam-ssh-agent subcomponent
Resolves: rhbz#2338440
* Fri Jan 17 2025 Fedora Release Engineering <releng@fedoraproject.org> - 9.9p1-5.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Mon Oct 28 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-5
- Fix MLKEM for BE platforms
* Wed Oct 16 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-4
- Resolve memory management issues after rebase
- Define OPTIONS env in systemd modules (https://src.fedoraproject.org/rpms/openssh/pull-request/92)
* Fri Oct 11 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-3
- Separate ssh-keysign to a dedicated package
- Use FIPS KEX defaults in FIPS mode
* Thu Oct 10 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-2
- Update version of pam_ssh_agent_auth
* Tue Oct 08 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.9p1-1
- Update to OpenSSH 9.9p1
* Tue Sep 03 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.8p1-4
- Synchronize patches from Red Hat
* Mon Aug 05 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.8p1-3
- Sshd now proposes to enter password again when a non-existing user is specified
* Fri Jul 26 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.8p1-2
- Change default key type in FIPS mode
* Mon Jul 22 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.8p1-1
- Update to OpenSSH 9.8p1
* Thu Jul 18 2024 Fedora Release Engineering <releng@fedoraproject.org> - 9.6p1-1.14
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Tue Jul 02 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.6p1-1.13
- rebuilt
* Mon Jul 01 2024 Gordon Messmer <gordon.messmer@gmail.com> - 9.6p1-12
- Patch 9.6p1 for CVE-2024-6387
* Mon Jul 01 2024 Gordon Messmer <gordon.messmer@gmail.com> - 9.6p1-11
- Shorten paths used for parallel tests to fix BZ#2295117
* Thu May 09 2024 Zoltan Fridrich <zfridric@redhat.com> - 9.6p1-10
- Correctly audit hostname and IP address
- Make default key sizes configurable in sshd-keygen
* Wed Apr 24 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.6p1-1.9
- Use OpenSSL SSH KDF implementation - s390x fixup
* Wed Apr 24 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.6p1-1.8
- Use OpenSSL SSH KDF implementation
* Wed Apr 17 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.6p1-1.7
- Only set PAM_RHOST if the remote host is not "UNKNOWN"
https://src.fedoraproject.org/rpms/openssh/pull-request/71
Patch by Daan De Meyer <daan.j.demeyer@gmail.com>
- Some spec cleanup
https://src.fedoraproject.org/rpms/openssh/pull-request/74
by Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
* Thu Apr 04 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.6p1-1.6
- rebuilt
* Thu Apr 04 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.6p1-1.5
- rebuilt
* Tue Apr 02 2024 Gordon Messmer <gordon.messmer@gmail.com> - 9.6p1-1.4
- Build OpenSSH without libsystemd dependency, using reference implementation
* Wed Mar 13 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.6p1-1.3
- Build OpenSSH without engine support
- Make tests run at build phase (using parallel run mechanism by Alexander Sosedkin)
* Thu Jan 25 2024 Fedora Release Engineering <releng@fedoraproject.org> - 9.6p1-1.2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 9.6p1-1.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Tue Dec 26 2023 Daniel Milnes <daniel@daniel-milnes.uk> - 9.6p1-1
- Update to OpenSSH 9.6
Original patches from https://src.fedoraproject.org/rpms/openssh/pull-request/63
Tuned by Dmitry Belyavskiy for GSS and PKCS#11 URI processing
* Fri Dec 22 2023 Florian Weimer <fweimer@redhat.com> - 9.3p1-13.1
- Fix type errors in downstream gssapi-keyex patch

View file

@ -1,249 +0,0 @@
configure.ac: Improve C99 compatibility
Future compilers will not support implicit declarations and implicit
ints by default. This means that configure probes which rely on them
will fail unconditionally, without actually testing anything.
The changes mostly mirror what has been implemented in the openssh
repository, but had to be adapted somewhat because of drift between
the two versions of configure.ac.
Sam James has submitted similar fixes upstream:
<https://github.com/jbeverly/pam_ssh_agent_auth/pull/41>
diff --git a/configure.ac b/configure.ac
index 6496679..d927b62 100644
--- a/configure.ac
+++ b/configure.ac
@@ -500,10 +500,10 @@ int main(void) { exit(0); }
AC_DEFINE(HAVE_BUNDLE, 1, [Define if your system uses bundles instead of ELF shared objects])
AC_MSG_CHECKING(if we have working getaddrinfo)
AC_TRY_RUN([#include <mach-o/dyld.h>
-main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
- exit(0);
+int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
+ return 0;
else
- exit(1);
+ return 1;
}], [AC_MSG_RESULT(working)],
[AC_MSG_RESULT(buggy)
AC_DEFINE(BROKEN_GETADDRINFO, 1, [getaddrinfo is broken (if present)])],
@@ -917,8 +917,8 @@ AC_SUBST(LDFLAGS_SHARED)
AC_MSG_CHECKING(compiler and flags for sanity)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([
-#include <stdio.h>
-int main(){exit(0);}
+#include <stdlib.h>
+int main(void){exit(0);}
])],
[ AC_MSG_RESULT(yes) ],
[
@@ -951,9 +951,9 @@ int main(int argc, char **argv) {
strncpy(buf,"/etc", 32);
s = dirname(buf);
if (!s || strncmp(s, "/", 32) != 0) {
- exit(1);
+ return 1;
} else {
- exit(0);
+ return 0;
}
}
]])],
@@ -1102,7 +1102,7 @@ AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <sys/types.h>
#include <dirent.h>
-int main(void){struct dirent d;exit(sizeof(d.d_name)<=sizeof(char));}
+int main(void){struct dirent d;return sizeof(d.d_name)<=sizeof(char);}
]])],
[AC_MSG_RESULT(yes)],
[
@@ -1327,8 +1327,10 @@ AC_CHECK_FUNCS(setresuid, [
AC_MSG_CHECKING(if setresuid seems to work)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
+#define _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
+#include <unistd.h>
int main(){errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
]])],
[AC_MSG_RESULT(yes)],
@@ -1344,8 +1346,10 @@ AC_CHECK_FUNCS(setresgid, [
AC_MSG_CHECKING(if setresgid seems to work)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
+#define _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
+#include <unistd.h>
int main(){errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
]])],
[AC_MSG_RESULT(yes)],
@@ -1384,7 +1388,7 @@ if test "x$ac_cv_func_snprintf" = "xyes" ; then
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdio.h>
-int main(void){char b[5];snprintf(b,5,"123456789");exit(b[4]!='\0');}
+int main(void){char b[5];snprintf(b,5,"123456789");return b[4]!='\0';}
]])],
[AC_MSG_RESULT(yes)],
[
@@ -1418,7 +1422,7 @@ int x_snprintf(char *str,size_t count,const char *fmt,...)
int main(void)
{
char x[1];
- exit(x_snprintf(x, 1, "%s %d", "hello", 12345) == 11 ? 0 : 1);
+ return x_snprintf(x, 1, "%s %d", "hello", 12345) == 11 ? 0 : 1;
} ]])],
[AC_MSG_RESULT(yes)],
[
@@ -1467,7 +1471,8 @@ AC_MSG_CHECKING([for (overly) strict mkstemp])
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdlib.h>
-main() { char template[]="conftest.mkstemp-test";
+#include <unistd.h>
+int main(void) { char template[]="conftest.mkstemp-test";
if (mkstemp(template) == -1)
exit(1);
unlink(template); exit(0);
@@ -1492,10 +1497,14 @@ if test ! -z "$check_for_openpty_ctty_bug"; then
AC_MSG_CHECKING(if openpty correctly handles controlling tty)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
+#include <stdlib.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
+#ifdef HAVE_PTY_H
+#include <pty.h>
+#endif
int
main()
@@ -1543,6 +1552,7 @@ if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdio.h>
+#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
@@ -1748,6 +1758,7 @@ AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL, 1,
AC_MSG_CHECKING([OpenSSL header version])
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/opensslv.h>
@@ -1794,12 +1805,12 @@ int main(void) {
fd = fopen(DATA,"w");
if(fd == NULL)
- exit(1);
+ return 1;
if ((rc = fprintf(fd ,"%x (%s)\n", SSLeay(), SSLeay_version(SSLEAY_VERSION))) <0)
- exit(1);
+ return 1;
- exit(0);
+ return 0;
}
]])],
[
@@ -1829,7 +1840,7 @@ AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <string.h>
#include <openssl/opensslv.h>
-int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); }
+int main(void) { return SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1; }
]])],
[
AC_MSG_RESULT(yes)
@@ -2598,7 +2609,7 @@ dnl test snprintf (broken on SCO w/gcc)
#include <stdio.h>
#include <string.h>
#ifdef HAVE_SNPRINTF
-main()
+int main(void)
{
char buf[50];
char expected_out[50];
@@ -2611,11 +2622,11 @@ main()
strcpy(expected_out, "9223372036854775807");
snprintf(buf, mazsize, "%lld", num);
if(strcmp(buf, expected_out) != 0)
- exit(1);
- exit(0);
+ return 1;
+ return 0;
}
#else
-main() { exit(0); }
+int main(void) { return 0; }
#endif
]])], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ],
AC_MSG_WARN([cross compiling: Assuming working snprintf()])
@@ -2746,11 +2757,11 @@ AC_CACHE_CHECK([for msg_accrights field in struct msghdr],
int main() {
#ifdef msg_accrights
#error "msg_accrights is a macro"
-exit(1);
+return 1;
#endif
struct msghdr m;
m.msg_accrights = 0;
-exit(0);
+return 0;
}
])],
[ ac_cv_have_accrights_in_msghdr="yes" ],
@@ -2773,11 +2784,11 @@ AC_CACHE_CHECK([for msg_control field in struct msghdr],
int main() {
#ifdef msg_control
#error "msg_control is a macro"
-exit(1);
+return 1;
#endif
struct msghdr m;
m.msg_control = 0;
-exit(0);
+return 0;
}
])],
[ ac_cv_have_control_in_msghdr="yes" ],
@@ -2791,7 +2802,7 @@ if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then
fi
AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [
- AC_TRY_LINK([],
+ AC_TRY_LINK([#include <stdio.h>],
[ extern char *__progname; printf("%s", __progname); ],
[ ac_cv_libc_defines___progname="yes" ],
[ ac_cv_libc_defines___progname="no" ]
@@ -2871,7 +2882,7 @@ if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then
fi
AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [
- AC_TRY_LINK([],
+ AC_TRY_LINK([#include <stdio.h>],
[ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);],
[ ac_cv_libc_defines_sys_errlist="yes" ],
[ ac_cv_libc_defines_sys_errlist="no" ]
@@ -2884,7 +2895,7 @@ fi
AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [
- AC_TRY_LINK([],
+ AC_TRY_LINK([#include <stdio.h>],
[ extern int sys_nerr; printf("%i", sys_nerr);],
[ ac_cv_libc_defines_sys_nerr="yes" ],
[ ac_cv_libc_defines_sys_nerr="no" ]

View file

@ -1,36 +0,0 @@
authfd.c
authfd.h
atomicio.c
atomicio.h
bufaux.c
bufbn.c
buffer.h
buffer.c
cleanup.c
cipher.h
compat.h
entropy.c
entropy.h
fatal.c
includes.h
kex.h
key.c
key.h
log.c
log.h
match.h
misc.c
misc.h
pathnames.h
platform.h
rsa.h
ssh-dss.c
ssh-rsa.c
ssh.h
ssh2.h
uidswap.c
uidswap.h
uuencode.c
uuencode.h
xmalloc.c
xmalloc.h

View file

@ -1,992 +0,0 @@
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c 2020-09-23 10:52:16.424001475 +0200
@@ -27,6 +27,7 @@
* or implied, of Jamie Beverly.
*/
+#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@@ -66,8 +67,8 @@ proc_pid_cmdline(char *** inargv)
case EOF:
case '\0':
if (len > 0) {
- argv = pamsshagentauth_xrealloc(argv, count + 1, sizeof(*argv));
- argv[count] = pamsshagentauth_xcalloc(len + 1, sizeof(*argv[count]));
+ argv = xreallocarray(argv, count + 1, sizeof(*argv));
+ argv[count] = xcalloc(len + 1, sizeof(*argv[count]));
strncpy(argv[count++], argbuf, len);
memset(argbuf, '\0', MAX_LEN_PER_CMDLINE_ARG + 1);
len = 0;
@@ -106,9 +107,9 @@ pamsshagentauth_free_command_line(char *
{
size_t i;
for (i = 0; i < n_args; i++)
- pamsshagentauth_xfree(argv[i]);
+ free(argv[i]);
- pamsshagentauth_xfree(argv);
+ free(argv);
return;
}
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h 2020-09-23 10:52:16.424001475 +0200
@@ -30,8 +30,8 @@
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "log.h"
-#include "buffer.h"
-#include "key.h"
+#include "sshbuf.h"
+#include "sshkey.h"
#include "authfd.h"
#include <stdio.h>
@@ -41,7 +41,7 @@ typedef struct idlist Idlist;
struct identity {
TAILQ_ENTRY(identity) next;
AuthenticationConnection *ac; /* set if agent supports key */
- Key *key; /* public/private key */
+ struct sshkey *key; /* public/private key */
char *filename; /* comment for agent-only keys */
int tried;
int isprivate; /* key points to the private key */
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c.psaa-compat 2020-09-23 10:52:16.421001434 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c 2020-09-23 10:52:16.424001475 +0200
@@ -36,8 +36,8 @@
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "log.h"
-#include "buffer.h"
-#include "key.h"
+#include "sshbuf.h"
+#include "sshkey.h"
#include "authfd.h"
#include <stdio.h>
#include <openssl/evp.h>
@@ -58,6 +58,8 @@
#include "get_command_line.h"
extern char **environ;
+#define PAM_SSH_AGENT_AUTH_REQUESTv1 101
+
/*
* Added by Jamie Beverly, ensure socket fd points to a socket owned by the user
* A cursory check is done, but to avoid race conditions, it is necessary
@@ -77,7 +79,7 @@ log_action(char ** action, size_t count)
if (count == 0)
return NULL;
- buf = pamsshagentauth_xcalloc((count * MAX_LEN_PER_CMDLINE_ARG) + (count * 3), sizeof(*buf));
+ buf = xcalloc((count * MAX_LEN_PER_CMDLINE_ARG) + (count * 3), sizeof(*buf));
for (i = 0; i < count; i++) {
strcat(buf, (i > 0) ? " '" : "'");
strncat(buf, action[i], MAX_LEN_PER_CMDLINE_ARG);
@@ -87,21 +89,25 @@ log_action(char ** action, size_t count)
}
void
-agent_action(Buffer *buf, char ** action, size_t count)
+agent_action(struct sshbuf **buf, char ** action, size_t count)
{
size_t i;
- pamsshagentauth_buffer_init(buf);
+ int r;
- pamsshagentauth_buffer_put_int(buf, count);
+ if ((*buf = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __func__);
+ if ((r = sshbuf_put_u32(*buf, count)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
for (i = 0; i < count; i++) {
- pamsshagentauth_buffer_put_cstring(buf, action[i]);
+ if ((r = sshbuf_put_cstring(*buf, action[i])) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
}
-void
-pamsshagentauth_session_id2_gen(Buffer * session_id2, const char * user,
+static void
+pamsshagentauth_session_id2_gen(struct sshbuf ** session_id2, const char * user,
const char * ruser, const char * servicename)
{
u_char *cookie = NULL;
@@ -114,22 +120,23 @@ pamsshagentauth_session_id2_gen(Buffer *
char ** reported_argv = NULL;
size_t count = 0;
char * action_logbuf = NULL;
- Buffer action_agentbuf;
+ struct sshbuf *action_agentbuf = NULL;
uint8_t free_logbuf = 0;
char * retc;
int32_t reti;
+ int r;
- rnd = pamsshagentauth_arc4random();
+ rnd = arc4random();
cookie_len = ((uint8_t) rnd);
while (cookie_len < 16) {
cookie_len += 16; /* Add 16 bytes to the size to ensure that while the length is random, the length is always reasonable; ticket #18 */
}
- cookie = pamsshagentauth_xcalloc(1,cookie_len);
+ cookie = xcalloc(1, cookie_len);
for (i = 0; i < cookie_len; i++) {
if (i % 4 == 0) {
- rnd = pamsshagentauth_arc4random();
+ rnd = arc4random();
}
cookie[i] = (u_char) rnd;
rnd >>= 8;
@@ -144,7 +151,8 @@ pamsshagentauth_session_id2_gen(Buffer *
}
else {
action_logbuf = "unknown on this platform";
- pamsshagentauth_buffer_init(&action_agentbuf); /* stays empty, means unavailable */
+ if ((action_agentbuf = sshbuf_new()) == NULL) /* stays empty, means unavailable */
+ fatal("%s: sshbuf_new failed", __func__);
}
/*
@@ -161,35 +169,39 @@ pamsshagentauth_session_id2_gen(Buffer *
retc = getcwd(pwd, sizeof(pwd) - 1);
time(&ts);
- pamsshagentauth_buffer_init(session_id2);
+ if ((*session_id2 = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __func__);
- pamsshagentauth_buffer_put_int(session_id2, PAM_SSH_AGENT_AUTH_REQUESTv1);
- /* pamsshagentauth_debug3("cookie: %s", pamsshagentauth_tohex(cookie, cookie_len)); */
- pamsshagentauth_buffer_put_string(session_id2, cookie, cookie_len);
- /* pamsshagentauth_debug3("user: %s", user); */
- pamsshagentauth_buffer_put_cstring(session_id2, user);
- /* pamsshagentauth_debug3("ruser: %s", ruser); */
- pamsshagentauth_buffer_put_cstring(session_id2, ruser);
- /* pamsshagentauth_debug3("servicename: %s", servicename); */
- pamsshagentauth_buffer_put_cstring(session_id2, servicename);
- /* pamsshagentauth_debug3("pwd: %s", pwd); */
- if(retc)
- pamsshagentauth_buffer_put_cstring(session_id2, pwd);
- else
- pamsshagentauth_buffer_put_cstring(session_id2, "");
- /* pamsshagentauth_debug3("action: %s", action_logbuf); */
- pamsshagentauth_buffer_put_string(session_id2, action_agentbuf.buf + action_agentbuf.offset, action_agentbuf.end - action_agentbuf.offset);
+ if ((r = sshbuf_put_u32(*session_id2, PAM_SSH_AGENT_AUTH_REQUESTv1)) != 0 ||
+ (r = sshbuf_put_string(*session_id2, cookie, cookie_len)) != 0 ||
+ (r = sshbuf_put_cstring(*session_id2, user)) != 0 ||
+ (r = sshbuf_put_cstring(*session_id2, ruser)) != 0 ||
+ (r = sshbuf_put_cstring(*session_id2, servicename)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if (retc) {
+ if ((r = sshbuf_put_cstring(*session_id2, pwd)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ } else {
+ if ((r = sshbuf_put_cstring(*session_id2, "")) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ }
+ if ((r = sshbuf_put_stringb(*session_id2, action_agentbuf)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (free_logbuf) {
- pamsshagentauth_xfree(action_logbuf);
- pamsshagentauth_buffer_free(&action_agentbuf);
+ free(action_logbuf);
+ sshbuf_free(action_agentbuf);
+ }
+ /* debug3("hostname: %s", hostname); */
+ if (reti >= 0) {
+ if ((r = sshbuf_put_cstring(*session_id2, hostname)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ } else {
+ if ((r = sshbuf_put_cstring(*session_id2, "")) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
- /* pamsshagentauth_debug3("hostname: %s", hostname); */
- if(reti >= 0)
- pamsshagentauth_buffer_put_cstring(session_id2, hostname);
- else
- pamsshagentauth_buffer_put_cstring(session_id2, "");
- /* pamsshagentauth_debug3("ts: %ld", ts); */
- pamsshagentauth_buffer_put_int64(session_id2, (uint64_t) ts);
+ /* debug3("ts: %ld", ts); */
+ if ((r = sshbuf_put_u64(*session_id2, (uint64_t) ts)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
free(cookie);
return;
@@ -278,7 +290,8 @@ ssh_get_authentication_connection_for_ui
auth = xmalloc(sizeof(*auth));
auth->fd = sock;
- buffer_init(&auth->identities);
+ if ((auth->identities = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __func__);
auth->howmany = 0;
return auth;
@@ -287,9 +300,9 @@ ssh_get_authentication_connection_for_ui
int
pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename)
{
- Buffer session_id2 = { 0 };
+ struct sshbuf *session_id2 = NULL;
Identity *id;
- Key *key;
+ struct sshkey *key;
AuthenticationConnection *ac;
char *comment;
uint8_t retval = 0;
@@ -299,31 +312,30 @@ pamsshagentauth_find_authorized_keys(con
pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename);
if ((ac = ssh_get_authentication_connection_for_uid(uid))) {
- pamsshagentauth_verbose("Contacted ssh-agent of user %s (%u)", ruser, uid);
+ verbose("Contacted ssh-agent of user %s (%u)", ruser, uid);
for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2))
{
if(key != NULL) {
- id = pamsshagentauth_xcalloc(1, sizeof(*id));
+ id = xcalloc(1, sizeof(*id));
id->key = key;
id->filename = comment;
id->ac = ac;
- if(userauth_pubkey_from_id(ruser, id, &session_id2)) {
+ if(userauth_pubkey_from_id(ruser, id, session_id2)) {
retval = 1;
}
- pamsshagentauth_xfree(id->filename);
- pamsshagentauth_key_free(id->key);
- pamsshagentauth_xfree(id);
+ free(id->filename);
+ key_free(id->key);
+ free(id);
if(retval == 1)
break;
}
}
- pamsshagentauth_buffer_free(&session_id2);
+ sshbuf_free(session_id2);
ssh_close_authentication_connection(ac);
}
else {
- pamsshagentauth_verbose("No ssh-agent could be contacted");
+ verbose("No ssh-agent could be contacted");
}
- /* pamsshagentauth_xfree(session_id2); */
EVP_cleanup();
return retval;
}
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c.psaa-compat 2020-09-23 10:52:16.423001461 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c 2020-09-23 10:53:10.631727657 +0200
@@ -106,7 +106,7 @@ pam_sm_authenticate(pam_handle_t * pamh,
* a patch 8-)
*/
#if ! HAVE___PROGNAME || HAVE_BUNDLE
- __progname = pamsshagentauth_xstrdup(servicename);
+ __progname = xstrdup(servicename);
#endif
for(i = argc, argv_ptr = (char **) argv; i > 0; ++argv_ptr, i--) {
@@ -132,11 +132,11 @@ pam_sm_authenticate(pam_handle_t * pamh,
#endif
}
- pamsshagentauth_log_init(__progname, log_lvl, facility, getenv("PAM_SSH_AGENT_AUTH_DEBUG") ? 1 : 0);
+ log_init(__progname, log_lvl, facility, getenv("PAM_SSH_AGENT_AUTH_DEBUG") ? 1 : 0);
pam_get_item(pamh, PAM_USER, (void *) &user);
pam_get_item(pamh, PAM_RUSER, (void *) &ruser_ptr);
- pamsshagentauth_verbose("Beginning pam_ssh_agent_auth for user %s", user);
+ verbose("Beginning pam_ssh_agent_auth for user %s", user);
if(ruser_ptr) {
strncpy(ruser, ruser_ptr, sizeof(ruser) - 1);
@@ -151,12 +151,12 @@ pam_sm_authenticate(pam_handle_t * pamh,
#ifdef ENABLE_SUDO_HACK
if( (strlen(sudo_service_name) > 0) && strncasecmp(servicename, sudo_service_name, sizeof(sudo_service_name) - 1) == 0 && getenv("SUDO_USER") ) {
strncpy(ruser, getenv("SUDO_USER"), sizeof(ruser) - 1 );
- pamsshagentauth_verbose( "Using environment variable SUDO_USER (%s)", ruser );
+ verbose( "Using environment variable SUDO_USER (%s)", ruser );
} else
#endif
{
if( ! getpwuid(getuid()) ) {
- pamsshagentauth_verbose("Unable to getpwuid(getuid())");
+ verbose("Unable to getpwuid(getuid())");
goto cleanexit;
}
strncpy(ruser, getpwuid(getuid())->pw_name, sizeof(ruser) - 1);
@@ -165,11 +165,11 @@ pam_sm_authenticate(pam_handle_t * pamh,
/* Might as well explicitely confirm the user exists here */
if(! getpwnam(ruser) ) {
- pamsshagentauth_verbose("getpwnam(%s) failed, bailing out", ruser);
+ verbose("getpwnam(%s) failed, bailing out", ruser);
goto cleanexit;
}
if( ! getpwnam(user) ) {
- pamsshagentauth_verbose("getpwnam(%s) failed, bailing out", user);
+ verbose("getpwnam(%s) failed, bailing out", user);
goto cleanexit;
}
@@ -179,8 +179,8 @@ pam_sm_authenticate(pam_handle_t * pamh,
*/
parse_authorized_key_file(user, authorized_keys_file_input);
} else {
- pamsshagentauth_verbose("Using default file=/etc/security/authorized_keys");
- authorized_keys_file = pamsshagentauth_xstrdup("/etc/security/authorized_keys");
+ verbose("Using default file=/etc/security/authorized_keys");
+ authorized_keys_file = xstrdup("/etc/security/authorized_keys");
}
/*
@@ -189,7 +189,7 @@ pam_sm_authenticate(pam_handle_t * pamh,
*/
if(user && strlen(ruser) > 0) {
- pamsshagentauth_verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
+ verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
/*
* Attempt to read data from the sshd if we're being called as an auth agent.
@@ -197,10 +197,10 @@ pam_sm_authenticate(pam_handle_t * pamh,
const char* ssh_user_auth = pam_getenv(pamh, "SSH_AUTH_INFO_0");
int sshd_service = strncasecmp(servicename, sshd_service_name, sizeof(sshd_service_name) - 1);
if (sshd_service == 0 && ssh_user_auth != NULL) {
- pamsshagentauth_verbose("Got SSH_AUTH_INFO_0: `%.20s...'", ssh_user_auth);
+ verbose("Got SSH_AUTH_INFO_0: `%.20s...'", ssh_user_auth);
if (userauth_pubkey_from_pam(ruser, ssh_user_auth) > 0) {
retval = PAM_SUCCESS;
- pamsshagentauth_logit("Authenticated (sshd): `%s' as `%s' using %s", ruser, user, authorized_keys_file);
+ logit("Authenticated (sshd): `%s' as `%s' using %s", ruser, user, authorized_keys_file);
goto cleanexit;
}
}
@@ -208,13 +208,13 @@ pam_sm_authenticate(pam_handle_t * pamh,
* this pw_uid is used to validate the SSH_AUTH_SOCK, and so must be the uid of the ruser invoking the program, not the target-user
*/
if(pamsshagentauth_find_authorized_keys(user, ruser, servicename)) { /* getpwnam(ruser)->pw_uid)) { */
- pamsshagentauth_logit("Authenticated (agent): `%s' as `%s' using %s", ruser, user, authorized_keys_file);
+ logit("Authenticated (agent): `%s' as `%s' using %s", ruser, user, authorized_keys_file);
retval = PAM_SUCCESS;
} else {
- pamsshagentauth_logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
+ logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
}
} else {
- pamsshagentauth_logit("No %s specified, cannot continue with this form of authentication", (user) ? "ruser" : "user" );
+ logit("No %s specified, cannot continue with this form of authentication", (user) ? "ruser" : "user" );
}
cleanexit:
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c 2020-09-23 10:52:16.424001475 +0200
@@ -66,8 +66,8 @@
#include "xmalloc.h"
#include "match.h"
#include "log.h"
-#include "buffer.h"
-#include "key.h"
+#include "sshbuf.h"
+#include "sshkey.h"
#include "misc.h"
#include "xmalloc.h"
@@ -77,7 +77,6 @@
#include "pathnames.h"
#include "secure_filename.h"
-#include "identity.h"
#include "pam_user_key_allowed2.h"
extern char *authorized_keys_file;
@@ -117,12 +116,12 @@ parse_authorized_key_file(const char *us
} else {
slash_ptr = strchr(auth_keys_file_buf, '/');
if(!slash_ptr)
- pamsshagentauth_fatal
+ fatal
("cannot expand tilde in path without a `/'");
owner_uname_len = slash_ptr - auth_keys_file_buf - 1;
if(owner_uname_len > (sizeof(owner_uname) - 1))
- pamsshagentauth_fatal("Username too long");
+ fatal("Username too long");
strncat(owner_uname, auth_keys_file_buf + 1, owner_uname_len);
if(!authorized_keys_file_allowed_owner_uid)
@@ -130,11 +129,11 @@ parse_authorized_key_file(const char *us
getpwnam(owner_uname)->pw_uid;
}
authorized_keys_file =
- pamsshagentauth_tilde_expand_filename(auth_keys_file_buf,
+ tilde_expand_filename(auth_keys_file_buf,
authorized_keys_file_allowed_owner_uid);
strncpy(auth_keys_file_buf, authorized_keys_file,
sizeof(auth_keys_file_buf) - 1);
- pamsshagentauth_xfree(authorized_keys_file) /* when we
+ free(authorized_keys_file) /* when we
percent_expand
later, we'd step
on this, so free
@@ -150,13 +149,13 @@ parse_authorized_key_file(const char *us
strncat(hostname, fqdn, strcspn(fqdn, "."));
#endif
authorized_keys_file =
- pamsshagentauth_percent_expand(auth_keys_file_buf, "h",
+ percent_expand(auth_keys_file_buf, "h",
getpwnam(user)->pw_dir, "H", hostname,
"f", fqdn, "u", user, NULL);
}
int
-pam_user_key_allowed(const char *ruser, Key * key)
+pam_user_key_allowed(const char *ruser, struct sshkey * key)
{
return
pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid),
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h 2020-09-23 10:52:16.424001475 +0200
@@ -32,7 +32,7 @@
#define _PAM_USER_KEY_ALLOWED_H
#include "identity.h"
-int pam_user_key_allowed(const char *, Key *);
+int pam_user_key_allowed(const char *, struct sshkey *);
void parse_authorized_key_file(const char *, const char *);
#endif
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c 2020-09-23 10:52:16.424001475 +0200
@@ -45,44 +45,46 @@
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
-#include "buffer.h"
+#include "sshbuf.h"
#include "log.h"
#include "compat.h"
-#include "key.h"
+#include "digest.h"
+#include "sshkey.h"
#include "pathnames.h"
#include "misc.h"
#include "secure_filename.h"
#include "uidswap.h"
-
-#include "identity.h"
+#include <unistd.h>
/* return 1 if user allows given key */
/* Modified slightly from original found in auth2-pubkey.c */
static int
-pamsshagentauth_check_authkeys_file(FILE * f, char *file, Key * key)
+pamsshagentauth_check_authkeys_file(FILE * f, char *file, struct sshkey * key)
{
- char line[SSH_MAX_PUBKEY_BYTES];
+ char *line = NULL;
int found_key = 0;
u_long linenum = 0;
- Key *found;
+ struct sshkey *found;
char *fp;
+ size_t linesize = 0;
found_key = 0;
- found = pamsshagentauth_key_new(key->type);
+ found = sshkey_new(key->type);
- while(read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
+ while ((getline(&line, &linesize, f)) != -1) {
char *cp = NULL; /* *key_options = NULL; */
+ linenum++;
/* Skip leading whitespace, empty and comment lines. */
for(cp = line; *cp == ' ' || *cp == '\t'; cp++);
if(!*cp || *cp == '\n' || *cp == '#')
continue;
- if(pamsshagentauth_key_read(found, &cp) != 1) {
+ if (sshkey_read(found, &cp) != 0) {
/* no key? check if there are options for this key */
int quoted = 0;
- pamsshagentauth_verbose("user_key_allowed: check options: '%s'", cp);
+ verbose("user_key_allowed: check options: '%s'", cp);
/* key_options = cp; */
for(; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
if(*cp == '\\' && cp[1] == '"')
@@ -92,26 +94,27 @@ pamsshagentauth_check_authkeys_file(FILE
}
/* Skip remaining whitespace. */
for(; *cp == ' ' || *cp == '\t'; cp++);
- if(pamsshagentauth_key_read(found, &cp) != 1) {
- pamsshagentauth_verbose("user_key_allowed: advance: '%s'", cp);
+ if(sshkey_read(found, &cp) != 0) {
+ verbose("user_key_allowed: advance: '%s'", cp);
/* still no key? advance to next line */
continue;
}
}
- if(pamsshagentauth_key_equal(found, key)) {
+ if(sshkey_equal(found, key)) {
found_key = 1;
- pamsshagentauth_logit("matching key found: file/command %s, line %lu", file,
+ logit("matching key found: file/command %s, line %lu", file,
linenum);
- fp = pamsshagentauth_key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
- pamsshagentauth_logit("Found matching %s key: %s",
- pamsshagentauth_key_type(found), fp);
- pamsshagentauth_xfree(fp);
+ fp = sshkey_fingerprint(found, SSH_DIGEST_SHA256, SSH_FP_BASE64);
+ logit("Found matching %s key: %s",
+ sshkey_type(found), fp);
+ free(fp);
break;
}
}
- pamsshagentauth_key_free(found);
+ free(line);
+ sshkey_free(found);
if(!found_key)
- pamsshagentauth_verbose("key not found");
+ verbose("key not found");
return found_key;
}
@@ -120,19 +123,19 @@ pamsshagentauth_check_authkeys_file(FILE
* returns 1 if the key is allowed or 0 otherwise.
*/
int
-pamsshagentauth_user_key_allowed2(struct passwd *pw, Key * key, char *file)
+pamsshagentauth_user_key_allowed2(struct passwd *pw, struct sshkey * key, char *file)
{
FILE *f;
int found_key = 0;
struct stat st;
- char buf[SSH_MAX_PUBKEY_BYTES];
+ char buf[256];
/* Temporarily use the user's uid. */
- pamsshagentauth_verbose("trying public key file %s", file);
+ verbose("trying public key file %s", file);
/* Fail not so quietly if file does not exist */
if(stat(file, &st) < 0) {
- pamsshagentauth_verbose("File not found: %s", file);
+ verbose("File not found: %s", file);
return 0;
}
@@ -144,7 +147,7 @@ pamsshagentauth_user_key_allowed2(struct
if(pamsshagentauth_secure_filename(f, file, pw, buf, sizeof(buf)) != 0) {
fclose(f);
- pamsshagentauth_logit("Authentication refused: %s", buf);
+ logit("Authentication refused: %s", buf);
return 0;
}
@@ -160,7 +163,7 @@ pamsshagentauth_user_key_allowed2(struct
int
pamsshagentauth_user_key_command_allowed2(char *authorized_keys_command,
char *authorized_keys_command_user,
- struct passwd *user_pw, Key * key)
+ struct passwd *user_pw, struct sshkey * key)
{
FILE *f;
int ok, found_key = 0;
@@ -187,44 +190,44 @@ pamsshagentauth_user_key_command_allowed
else {
pw = getpwnam(authorized_keys_command_user);
if(pw == NULL) {
- pamsshagentauth_logerror("authorized_keys_command_user \"%s\" not found: %s",
+ error("authorized_keys_command_user \"%s\" not found: %s",
authorized_keys_command_user, strerror(errno));
return 0;
}
}
- pamsshagentauth_temporarily_use_uid(pw);
+ temporarily_use_uid(pw);
if(stat(authorized_keys_command, &st) < 0) {
- pamsshagentauth_logerror
+ error
("Could not stat AuthorizedKeysCommand \"%s\": %s",
authorized_keys_command, strerror(errno));
goto out;
}
if(pamsshagentauth_auth_secure_path
(authorized_keys_command, &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) {
- pamsshagentauth_logerror("Unsafe AuthorizedKeysCommand: %s", errmsg);
+ error("Unsafe AuthorizedKeysCommand: %s", errmsg);
goto out;
}
/* open the pipe and read the keys */
if(pipe(p) != 0) {
- pamsshagentauth_logerror("%s: pipe: %s", __func__, strerror(errno));
+ error("%s: pipe: %s", __func__, strerror(errno));
goto out;
}
- pamsshagentauth_debug("Running AuthorizedKeysCommand: \"%s\" as \"%s\" with argument: \"%s\"",
+ debug("Running AuthorizedKeysCommand: \"%s\" as \"%s\" with argument: \"%s\"",
authorized_keys_command, pw->pw_name, username);
/*
* Don't want to call this in the child, where it can fatal() and
* run cleanup_exit() code.
*/
- pamsshagentauth_restore_uid();
+ restore_uid();
switch ((pid = fork())) {
case -1: /* error */
- pamsshagentauth_logerror("%s: fork: %s", __func__, strerror(errno));
+ error("%s: fork: %s", __func__, strerror(errno));
close(p[0]);
close(p[1]);
return 0;
@@ -234,13 +237,13 @@ pamsshagentauth_user_key_command_allowed
/* do this before the setresuid so thta they can be logged */
if((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
- pamsshagentauth_logerror("%s: open %s: %s", __func__, _PATH_DEVNULL,
+ error("%s: open %s: %s", __func__, _PATH_DEVNULL,
strerror(errno));
_exit(1);
}
if(dup2(devnull, STDIN_FILENO) == -1 || dup2(p[1], STDOUT_FILENO) == -1
|| dup2(devnull, STDERR_FILENO) == -1) {
- pamsshagentauth_logerror("%s: dup2: %s", __func__, strerror(errno));
+ error("%s: dup2: %s", __func__, strerror(errno));
_exit(1);
}
#if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID)
@@ -248,7 +251,7 @@ pamsshagentauth_user_key_command_allowed
#else
if (setgid(pw->pw_gid) != 0 || setegid(pw->pw_gid) != 0) {
#endif
- pamsshagentauth_logerror("setresgid %u: %s", (u_int) pw->pw_gid,
+ error("setresgid %u: %s", (u_int) pw->pw_gid,
strerror(errno));
_exit(1);
}
@@ -258,7 +261,7 @@ pamsshagentauth_user_key_command_allowed
#else
if (setuid(pw->pw_uid) != 0 || seteuid(pw->pw_uid) != 0) {
#endif
- pamsshagentauth_logerror("setresuid %u: %s", (u_int) pw->pw_uid,
+ error("setresuid %u: %s", (u_int) pw->pw_uid,
strerror(errno));
_exit(1);
}
@@ -270,18 +273,18 @@ pamsshagentauth_user_key_command_allowed
/* pretty sure this will barf because we are now suid, but since we
should't reach this anyway, I'll leave it here */
- pamsshagentauth_logerror("AuthorizedKeysCommand %s exec failed: %s",
+ error("AuthorizedKeysCommand %s exec failed: %s",
authorized_keys_command, strerror(errno));
_exit(127);
default: /* parent */
break;
}
- pamsshagentauth_temporarily_use_uid(pw);
+ temporarily_use_uid(pw);
close(p[1]);
if((f = fdopen(p[0], "r")) == NULL) {
- pamsshagentauth_logerror("%s: fdopen: %s", __func__, strerror(errno));
+ error("%s: fdopen: %s", __func__, strerror(errno));
close(p[0]);
/* Don't leave zombie child */
while(waitpid(pid, NULL, 0) == -1 && errno == EINTR);
@@ -292,22 +295,22 @@ pamsshagentauth_user_key_command_allowed
while(waitpid(pid, &status, 0) == -1) {
if(errno != EINTR) {
- pamsshagentauth_logerror("%s: waitpid: %s", __func__,
+ error("%s: waitpid: %s", __func__,
strerror(errno));
goto out;
}
}
if(WIFSIGNALED(status)) {
- pamsshagentauth_logerror("AuthorizedKeysCommand %s exited on signal %d",
+ error("AuthorizedKeysCommand %s exited on signal %d",
authorized_keys_command, WTERMSIG(status));
goto out;
} else if(WEXITSTATUS(status) != 0) {
- pamsshagentauth_logerror("AuthorizedKeysCommand %s returned status %d",
+ error("AuthorizedKeysCommand %s returned status %d",
authorized_keys_command, WEXITSTATUS(status));
goto out;
}
found_key = ok;
out:
- pamsshagentauth_restore_uid();
+ restore_uid();
return found_key;
}
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h 2020-09-23 10:52:16.424001475 +0200
@@ -32,7 +32,7 @@
#define _PAM_USER_KEY_ALLOWED_H
#include "identity.h"
-int pamsshagentauth_user_key_allowed2(struct passwd *, Key *, char *);
-int pamsshagentauth_user_key_command_allowed2(char *, char *, struct passwd *, Key *);
+int pamsshagentauth_user_key_allowed2(struct passwd *, struct sshkey *, char *);
+int pamsshagentauth_user_key_command_allowed2(char *, char *, struct passwd *, struct sshkey *);
#endif
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c 2020-09-23 10:52:16.424001475 +0200
@@ -53,8 +53,8 @@
#include "xmalloc.h"
#include "match.h"
#include "log.h"
-#include "buffer.h"
-#include "key.h"
+#include "sshbuf.h"
+#include "sshkey.h"
#include "misc.h"
@@ -80,7 +80,7 @@ pamsshagentauth_auth_secure_path(const c
int comparehome = 0;
struct stat st;
- pamsshagentauth_verbose("auth_secure_filename: checking for uid: %u", uid);
+ verbose("auth_secure_filename: checking for uid: %u", uid);
if (realpath(name, buf) == NULL) {
snprintf(err, errlen, "realpath %s failed: %s", name,
@@ -115,9 +115,9 @@ pamsshagentauth_auth_secure_path(const c
snprintf(err, errlen, "dirname() failed");
return -1;
}
- pamsshagentauth_strlcpy(buf, cp, sizeof(buf));
+ strlcpy(buf, cp, sizeof(buf));
- pamsshagentauth_verbose("secure_filename: checking '%s'", buf);
+ verbose("secure_filename: checking '%s'", buf);
if (stat(buf, &st) < 0 ||
(st.st_uid != 0 && st.st_uid != uid) ||
(st.st_mode & 022) != 0) {
@@ -128,7 +128,7 @@ pamsshagentauth_auth_secure_path(const c
/* If are passed the homedir then we can stop */
if (comparehome && strcmp(homedir, buf) == 0) {
- pamsshagentauth_verbose("secure_filename: terminating check at '%s'",
+ verbose("secure_filename: terminating check at '%s'",
buf);
break;
}
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c 2020-09-23 10:52:16.424001475 +0200
@@ -37,10 +37,11 @@
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
-#include "buffer.h"
+#include "sshbuf.h"
#include "log.h"
#include "compat.h"
-#include "key.h"
+#include "sshkey.h"
+#include "ssherr.h"
#include "pathnames.h"
#include "misc.h"
#include "secure_filename.h"
@@ -48,54 +49,59 @@
#include "identity.h"
#include "pam_user_authorized_keys.h"
+#define SSH2_MSG_USERAUTH_TRUST_REQUEST 54
+
/* extern u_char *session_id2;
extern uint8_t session_id_len;
*/
int
-userauth_pubkey_from_id(const char *ruser, Identity * id, Buffer * session_id2)
+userauth_pubkey_from_id(const char *ruser, Identity * id, struct sshbuf * session_id2)
{
- Buffer b = { 0 };
+ struct sshbuf *b = NULL;
char *pkalg = NULL;
u_char *pkblob = NULL, *sig = NULL;
- u_int blen = 0, slen = 0;
- int authenticated = 0;
+ size_t blen = 0, slen = 0;
+ int r, authenticated = 0;
- pkalg = (char *) key_ssh_name(id->key);
+ pkalg = (char *) sshkey_ssh_name(id->key);
/* first test if this key is even allowed */
if(! pam_user_key_allowed(ruser, id->key))
- goto user_auth_clean_exit;
+ goto user_auth_clean_exit_without_buffer;
- if(pamsshagentauth_key_to_blob(id->key, &pkblob, &blen) == 0)
- goto user_auth_clean_exit;
+ if(sshkey_to_blob(id->key, &pkblob, &blen) != 0)
+ goto user_auth_clean_exit_without_buffer;
/* construct packet to sign and test */
- pamsshagentauth_buffer_init(&b);
+ if ((b = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __func__);
- pamsshagentauth_buffer_put_string(&b, session_id2->buf + session_id2->offset, session_id2->end - session_id2->offset);
- pamsshagentauth_buffer_put_char(&b, SSH2_MSG_USERAUTH_TRUST_REQUEST);
- pamsshagentauth_buffer_put_cstring(&b, ruser);
- pamsshagentauth_buffer_put_cstring(&b, "pam_ssh_agent_auth");
- pamsshagentauth_buffer_put_cstring(&b, "publickey");
- pamsshagentauth_buffer_put_char(&b, 1);
- pamsshagentauth_buffer_put_cstring(&b, pkalg);
- pamsshagentauth_buffer_put_string(&b, pkblob, blen);
+ if ((r = sshbuf_put_string(b, sshbuf_ptr(session_id2), sshbuf_len(session_id2))) != 0 ||
+ (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_TRUST_REQUEST)) != 0 ||
+ (r = sshbuf_put_cstring(b, ruser)) != 0 ||
+ (r = sshbuf_put_cstring(b, "pam_ssh_agent_auth")) != 0 ||
+ (r = sshbuf_put_cstring(b, "publickey")) != 0 ||
+ (r = sshbuf_put_u8(b, 1)) != 0 ||
+ (r = sshbuf_put_cstring(b, pkalg)) != 0 ||
+ (r = sshbuf_put_string(b, pkblob, blen)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if(ssh_agent_sign(id->ac, id->key, &sig, &slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) != 0)
+ if (ssh_agent_sign(id->ac, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b)) != 0)
goto user_auth_clean_exit;
/* test for correct signature */
- if(pamsshagentauth_key_verify(id->key, sig, slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) == 1)
+ if (sshkey_verify(id->key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0, NULL) == 0)
authenticated = 1;
user_auth_clean_exit:
/* if(&b != NULL) */
- pamsshagentauth_buffer_free(&b);
+ sshbuf_free(b);
+ user_auth_clean_exit_without_buffer:
if(sig != NULL)
- pamsshagentauth_xfree(sig);
+ free(sig);
if(pkblob != NULL)
- pamsshagentauth_xfree(pkblob);
+ free(pkblob);
CRYPTO_cleanup_all_ex_data();
return authenticated;
}
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h 2020-09-23 10:52:16.424001475 +0200
@@ -31,7 +31,7 @@
#ifndef _USERAUTH_PUBKEY_FROM_ID_H
#define _USERAUTH_PUBKEY_FROM_ID_H
-#include <identity.h>
-int userauth_pubkey_from_id(const char *, Identity *, Buffer *);
+#include "identity.h"
+int userauth_pubkey_from_id(const char *, Identity *, struct sshbuf *);
#endif
diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c 2020-09-23 10:52:16.424001475 +0200
@@ -56,7 +56,7 @@ pamsshagentauth_uudecode(const char *src
/* and remove trailing whitespace because __b64_pton needs this */
*p = '\0';
len = pamsshagentauth___b64_pton(encoded, target, targsize);
- pamsshagentauth_xfree(encoded);
+ xfree(encoded);
return len;
}
@@ -70,7 +70,7 @@ pamsshagentauth_dump_base64(FILE *fp, co
fprintf(fp, "dump_base64: len > 65536\n");
return;
}
- buf = pamsshagentauth_xmalloc(2*len);
+ buf = malloc(2*len);
n = pamsshagentauth_uuencode(data, len, buf, 2*len);
for (i = 0; i < n; i++) {
fprintf(fp, "%c", buf[i]);
@@ -79,5 +79,5 @@ pamsshagentauth_dump_base64(FILE *fp, co
}
if (i % 70 != 69)
fprintf(fp, "\n");
- pamsshagentauth_xfree(buf);
+ free(buf);
}
--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_pam.c.compat 2020-09-23 11:32:30.783695267 +0200
+++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_pam.c 2020-09-23 11:33:21.383389036 +0200
@@ -33,7 +33,8 @@
#include <string.h>
#include "defines.h"
-#include "key.h"
+#include <includes.h>
+#include "sshkey.h"
#include "log.h"
#include "pam_user_authorized_keys.h"
@@ -42,28 +42,28 @@
int authenticated = 0;
const char method[] = "publickey ";
- char* ai = pamsshagentauth_xstrdup(ssh_auth_info);
+ char* ai = xstrdup(ssh_auth_info);
char* saveptr;
char* auth_line = strtok_r(ai, "\n", &saveptr);
while (auth_line != NULL) {
if (strncmp(auth_line, method, sizeof(method) - 1) == 0) {
char* key_str = auth_line + sizeof(method) - 1;
- Key* key = pamsshagentauth_key_new(KEY_UNSPEC);
+ struct sshkey* key = sshkey_new(KEY_UNSPEC);
if (key == NULL) {
continue;
}
- int r = pamsshagentauth_key_read(key, &key_str);
+ int r = sshkey_read(key, &key_str);
if (r == 1) {
if (pam_user_key_allowed(ruser, key)) {
authenticated = 1;
- pamsshagentauth_key_free(key);
+ sshkey_free(key);
break;
}
} else {
- pamsshagentauth_verbose("Failed to create key for %s: %d", auth_line, r);
+ verbose("Failed to create key for %s: %d", auth_line, r);
}
- pamsshagentauth_key_free(key);
+ sshkey_free(key);
}
auth_line = strtok_r(NULL, "\n", &saveptr);
}

View file

@ -1,20 +0,0 @@
diff --git a/pam_ssh_agent_auth-0.10.2/pam_user_authorized_keys.c b/pam_ssh_agent_auth-0.10.2/pam_user_authorized_keys.c
--- a/pam_ssh_agent_auth-0.10.2/pam_user_authorized_keys.c
+++ b/pam_ssh_agent_auth-0.10.2/pam_user_authorized_keys.c
@@ -158,11 +158,12 @@ parse_authorized_key_file(const char *user,
int
pam_user_key_allowed(const char *ruser, struct sshkey * key)
{
+ struct passwd *pw;
return
- pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid),
- key, authorized_keys_file)
- || pamsshagentauth_user_key_allowed2(getpwuid(0), key,
- authorized_keys_file)
+ ( (pw = getpwuid(authorized_keys_file_allowed_owner_uid)) &&
+ pamsshagentauth_user_key_allowed2(pw, key, authorized_keys_file))
+ || ((pw = getpwuid(0)) &&
+ pamsshagentauth_user_key_allowed2(pw, key, authorized_keys_file))
|| pamsshagentauth_user_key_command_allowed2(authorized_keys_command,
authorized_keys_command_user,
getpwnam(ruser), key);

View file

@ -1,37 +0,0 @@
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-seteuid openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-seteuid 2017-02-07 15:41:53.172334151 +0100
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c 2017-02-07 15:41:53.174334149 +0100
@@ -238,17 +238,26 @@ ssh_get_authentication_socket_for_uid(ui
}
errno = 0;
- seteuid(uid); /* To ensure a race condition is not used to circumvent the stat
- above, we will temporarily drop UID to the caller */
- if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) {
+ /* To ensure a race condition is not used to circumvent the stat
+ above, we will temporarily drop UID to the caller */
+ if (seteuid(uid) == -1) {
close(sock);
- if(errno == EACCES)
- fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid);
+ error("seteuid(%lu) failed with error: %s",
+ (unsigned long) uid, strerror(errno));
return -1;
}
+ if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) {
+ close(sock);
+ sock = -1;
+ if(errno == EACCES)
+ fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid);
+ }
- seteuid(0); /* we now continue the regularly scheduled programming */
-
+ /* we now continue the regularly scheduled programming */
+ if (0 != seteuid(0)) {
+ fatal("setuid(0) failed with error: %s", strerror(errno));
+ return -1;
+ }
return sock;
}

View file

@ -1,19 +0,0 @@
diff -up openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.rsasha2 openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c
--- openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.rsasha2 2022-07-15 15:08:12.865585410 +0200
+++ openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c 2022-07-15 15:16:25.164282372 +0200
@@ -87,8 +87,13 @@ userauth_pubkey_from_id(const char *ruse
(r = sshbuf_put_string(b, pkblob, blen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
- goto user_auth_clean_exit;
+ if (sshkey_type_plain(id->key->type) == KEY_RSA
+ && ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), "rsa-sha2-256", 0) == 0) {
+ /* Do nothing */
+ } else {
+ if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
+ goto user_auth_clean_exit;
+ }
/* test for correct signature */
if (sshkey_verify(id->key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0, NULL) == 0)

View file

@ -1,21 +0,0 @@
diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/pam_ssh_agent_auth.c.psaa-visibility openssh-7.1p2/pam_ssh_agent_auth-0.10.2/pam_ssh_agent_auth.c
--- openssh-7.1p2/pam_ssh_agent_auth-0.10.2/pam_ssh_agent_auth.c.psaa-visibility 2014-03-31 19:35:17.000000000 +0200
+++ openssh-7.1p2/pam_ssh_agent_auth-0.10.2/pam_ssh_agent_auth.c 2016-01-22 15:22:40.984469774 +0100
@@ -72,7 +72,7 @@ char *__progname;
extern char *__progname;
#endif
-PAM_EXTERN int
+PAM_EXTERN int __attribute__ ((visibility ("default")))
pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv)
{
char **argv_ptr;
@@ -214,7 +214,7 @@ cleanexit:
}
-PAM_EXTERN int
+PAM_EXTERN int __attribute__ ((visibility ("default")))
pam_sm_setcred(pam_handle_t * pamh, int flags, int argc, const char **argv)
{
UNUSED(pamh);

View file

@ -1,96 +0,0 @@
diff -up openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/identity.h
--- openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-agent 2016-11-13 04:24:32.000000000 +0100
+++ openssh/pam_ssh_agent_auth-0.10.3/identity.h 2017-09-27 14:25:49.421739027 +0200
@@ -38,6 +38,12 @@
typedef struct identity Identity;
typedef struct idlist Idlist;
+typedef struct {
+ int fd;
+ struct sshbuf *identities;
+ int howmany;
+} AuthenticationConnection;
+
struct identity {
TAILQ_ENTRY(identity) next;
AuthenticationConnection *ac; /* set if agent supports key */
diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c
--- openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-agent 2017-09-27 14:25:49.420739021 +0200
+++ openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c 2017-09-27 14:25:49.421739027 +0200
@@ -39,6 +39,7 @@
#include "sshbuf.h"
#include "sshkey.h"
#include "authfd.h"
+#include "ssherr.h"
#include <stdio.h>
#include <openssl/evp.h>
#include "ssh2.h"
@@ -291,36 +292,43 @@ pamsshagentauth_find_authorized_keys(con
{
struct sshbuf *session_id2 = NULL;
Identity *id;
- struct sshkey *key;
AuthenticationConnection *ac;
- char *comment;
uint8_t retval = 0;
uid_t uid = getpwnam(ruser)->pw_uid;
+ struct ssh_identitylist *idlist;
+ int r;
+ unsigned int i;
OpenSSL_add_all_digests();
pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename);
if ((ac = ssh_get_authentication_connection_for_uid(uid))) {
verbose("Contacted ssh-agent of user %s (%u)", ruser, uid);
- for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2))
- {
- if(key != NULL) {
+ if ((r = ssh_fetch_identitylist(ac->fd, &idlist)) != 0) {
+ if (r != SSH_ERR_AGENT_NO_IDENTITIES)
+ fprintf(stderr, "error fetching identities for "
+ "protocol %d: %s\n", 2, ssh_err(r));
+ } else {
+ for (i = 0; i < idlist->nkeys; i++)
+ {
+ if (idlist->keys[i] != NULL) {
id = xcalloc(1, sizeof(*id));
- id->key = key;
- id->filename = comment;
+ id->key = idlist->keys[i];
+ id->filename = idlist->comments[i];
id->ac = ac;
if(userauth_pubkey_from_id(ruser, id, session_id2)) {
retval = 1;
}
- free(id->filename);
- key_free(id->key);
free(id);
if(retval == 1)
break;
- }
- }
+ }
+ }
- sshbuf_free(session_id2);
- ssh_close_authentication_connection(ac);
+ sshbuf_free(session_id2);
+ ssh_free_identitylist(idlist);
+ }
+ ssh_close_authentication_socket(ac->fd);
+ free(ac);
}
else {
verbose("No ssh-agent could be contacted");
diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c
--- openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-agent 2017-09-27 14:25:49.420739021 +0200
+++ openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c 2017-09-27 14:25:49.422739032 +0200
@@ -84,7 +85,7 @@ userauth_pubkey_from_id(const char *ruse
(r = sshbuf_put_string(b, pkblob, blen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (ssh_agent_sign(id->ac, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b)) != 0)
+ if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
goto user_auth_clean_exit;
/* test for correct signature */

View file

@ -1,198 +0,0 @@
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-build openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-build 2016-11-13 04:24:32.000000000 +0100
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c 2017-02-07 14:29:41.626116675 +0100
@@ -43,12 +43,31 @@
#include <openssl/evp.h>
#include "ssh2.h"
#include "misc.h"
+#include "ssh.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
#include "userauth_pubkey_from_id.h"
#include "identity.h"
#include "get_command_line.h"
extern char **environ;
+/*
+ * Added by Jamie Beverly, ensure socket fd points to a socket owned by the user
+ * A cursory check is done, but to avoid race conditions, it is necessary
+ * to drop effective UID when connecting to the socket.
+ *
+ * If the cause of error is EACCES, because we verified we would not have that
+ * problem initially, we can safely assume that somebody is attempting to find a
+ * race condition; so a more "direct" log message is generated.
+ */
+
static char *
log_action(char ** action, size_t count)
{
@@ -85,7 +104,7 @@ void
pamsshagentauth_session_id2_gen(Buffer * session_id2, const char * user,
const char * ruser, const char * servicename)
{
- char *cookie = NULL;
+ u_char *cookie = NULL;
uint8_t i = 0;
uint32_t rnd = 0;
uint8_t cookie_len;
@@ -112,7 +131,7 @@ pamsshagentauth_session_id2_gen(Buffer *
if (i % 4 == 0) {
rnd = pamsshagentauth_arc4random();
}
- cookie[i] = (char) rnd;
+ cookie[i] = (u_char) rnd;
rnd >>= 8;
}
@@ -177,6 +196,86 @@ pamsshagentauth_session_id2_gen(Buffer *
}
int
+ssh_get_authentication_socket_for_uid(uid_t uid)
+{
+ const char *authsocket;
+ int sock;
+ struct sockaddr_un sunaddr;
+ struct stat sock_st;
+
+ authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
+ if (!authsocket)
+ return -1;
+
+ /* Advisory only; seteuid ensures no race condition; but will only log if we see EACCES */
+ if( stat(authsocket,&sock_st) == 0) {
+ if(uid != 0 && sock_st.st_uid != uid) {
+ fatal("uid %lu attempted to open an agent socket owned by uid %lu", (unsigned long) uid, (unsigned long) sock_st.st_uid);
+ return -1;
+ }
+ }
+
+ /*
+ * Ensures that the EACCES tested for below can _only_ happen if somebody
+ * is attempting to race the stat above to bypass authentication.
+ */
+ if( (sock_st.st_mode & S_IWUSR) != S_IWUSR || (sock_st.st_mode & S_IRUSR) != S_IRUSR) {
+ error("ssh-agent socket has incorrect permissions for owner");
+ return -1;
+ }
+
+ sunaddr.sun_family = AF_UNIX;
+ strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0)
+ return -1;
+
+ /* close on exec */
+ if (fcntl(sock, F_SETFD, 1) == -1) {
+ close(sock);
+ return -1;
+ }
+
+ errno = 0;
+ seteuid(uid); /* To ensure a race condition is not used to circumvent the stat
+ above, we will temporarily drop UID to the caller */
+ if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) {
+ close(sock);
+ if(errno == EACCES)
+ fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid);
+ return -1;
+ }
+
+ seteuid(0); /* we now continue the regularly scheduled programming */
+
+ return sock;
+}
+
+AuthenticationConnection *
+ssh_get_authentication_connection_for_uid(uid_t uid)
+{
+ AuthenticationConnection *auth;
+ int sock;
+
+ sock = ssh_get_authentication_socket_for_uid(uid);
+
+ /*
+ * Fail if we couldn't obtain a connection. This happens if we
+ * exited due to a timeout.
+ */
+ if (sock < 0)
+ return NULL;
+
+ auth = xmalloc(sizeof(*auth));
+ auth->fd = sock;
+ buffer_init(&auth->identities);
+ auth->howmany = 0;
+
+ return auth;
+}
+
+int
pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename)
{
Buffer session_id2 = { 0 };
@@ -190,7 +289,7 @@ pamsshagentauth_find_authorized_keys(con
OpenSSL_add_all_digests();
pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename);
- if ((ac = ssh_get_authentication_connection(uid))) {
+ if ((ac = ssh_get_authentication_connection_for_uid(uid))) {
pamsshagentauth_verbose("Contacted ssh-agent of user %s (%u)", ruser, uid);
for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2))
{
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build 2016-11-13 04:24:32.000000000 +0100
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in 2017-02-07 14:40:14.407566921 +0100
@@ -52,7 +52,7 @@ PATHS=
CC=@CC@
LD=@LD@
CFLAGS=@CFLAGS@
-CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
+CPPFLAGS=-I.. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
LIBS=@LIBS@
AR=@AR@
AWK=@AWK@
@@ -61,8 +61,8 @@ INSTALL=@INSTALL@
PERL=@PERL@
SED=@SED@
ENT=@ENT@
-LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
-LDFLAGS_SHARED = @LDFLAGS_SHARED@
+LDFLAGS=-L.. -L../openbsd-compat/ @LDFLAGS@
+LDFLAGS_SHARED =-Wl,-z,defs @LDFLAGS_SHARED@
EXEEXT=@EXEEXT@
INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
@@ -74,7 +74,7 @@ SSHOBJS=xmalloc.o atomicio.o authfd.o bu
ED25519OBJS=ed25519-donna/ed25519.o
-PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o userauth_pubkey_from_pam.o
+PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o userauth_pubkey_from_pam.o secure_filename.o
MANPAGES_IN = pam_ssh_agent_auth.pod
@@ -94,13 +94,13 @@ $(PAM_MODULES): Makefile.in config.h
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
-LIBCOMPAT=openbsd-compat/libopenbsd-compat.a
+LIBCOMPAT=../openbsd-compat/libopenbsd-compat.a
$(LIBCOMPAT): always
(cd openbsd-compat && $(MAKE))
always:
-pam_ssh_agent_auth.so: $(LIBCOMPAT) $(SSHOBJS) $(ED25519OBJS) $(PAM_SSH_AGENT_AUTH_OBJS) pam_ssh_agent_auth.o
- $(LD) $(LDFLAGS_SHARED) -o $@ $(SSHOBJS) $(ED25519OBJS) $(PAM_SSH_AGENT_AUTH_OBJS) $(LDFLAGS) -lopenbsd-compat pam_ssh_agent_auth.o $(LIBS) -lpam
+pam_ssh_agent_auth.so: $(PAM_SSH_AGENT_AUTH_OBJS) pam_ssh_agent_auth.o ../uidswap.o ../ssh-sk-client.o
+ $(LD) $(LDFLAGS_SHARED) -o $@ $(PAM_SSH_AGENT_AUTH_OBJS) ../ssh-sk-client.o $(LDFLAGS) -lssh -lopenbsd-compat pam_ssh_agent_auth.o ../uidswap.o $(LIBS) -lpam
$(MANPAGES): $(MANPAGES_IN)
pod2man --section=8 --release=v0.10.3 --name=pam_ssh_agent_auth --official --center "PAM" pam_ssh_agent_auth.pod > pam_ssh_agent_auth.8

14
parallel_test.Makefile Normal file
View file

@ -0,0 +1,14 @@
# just a Makefile parallel_test.sh uses to run stuff in parallel with make
%:
$(MAKE) -j1 -C .t/$* $*
t-exec-%:
$(MAKE) -j1 -C ".t/t-exec-$*" \
TEST_SSH_PORT=10$*0 \
SKIP_LTESTS="$(shell cat .ltests/not-in/$*)" \
BUILDDIR="$(shell pwd)/.t/t-exec-$*" \
TEST_SHELL=sh \
MAKE=make \
TEST_SSH_TRACE=yes \
TEST_SSH_FAIL_FATAL=yes \
t-exec \

91
parallel_test.sh Executable file
View file

@ -0,0 +1,91 @@
#!/usr/bin/bash
set -uexo pipefail
# The custom %check script to run the OpenSSH upstream testsuite in parallel.
#
# The upstream testsuite is serial,
# so the idea here is to split the testsuite into several $PARTS:
# * file-tests
# * interop-tests
# * unit
# * ltests-00
# * ltests-01
# * ...
# * ltests-23
# and run them in parallel, using make, each in its own build subtree.
PARALLEL_MAKEFILE=$1
SPLIT=24
PARTS='file-tests interop-tests unit '
for ((i = 1; i < SPLIT; i++)); do ii=$(printf %02d $i);
PARTS+="t-exec-$ii "
done
# work around a selinux restriction:
chcon -t unconfined_exec_t ssh-sk-helper || :
# work around something else that only crops up in brew
export TEST_SSH_UNSAFE_PERMISSIONS=1
# create a .test directory to store all our files in:
mkdir -p .t .ltests/{in,not-in}
# patch testsuite: use different ports to avoid port collisions
grep -REi 'port=[2-9][0-9]*' regress
sed -i 's|PORT=4242|PORT=$(expr $TEST_SSH_PORT + 1)|' \
regress/test-exec.sh*
sed -i 's|^P=3301 # test port|P=$(expr $TEST_SSH_PORT + 1)|' \
regress/multiplex.sh*
sed -i 's|^fwdport=3301|fwdport=$(expr $TEST_SSH_PORT + 1)|' \
regress/cfgmatch.sh* regress/cfgmatchlisten.sh*
sed -i 's|^LFWD_PORT=.*|LFWD_PORT=$(expr $TEST_SSH_PORT + 1)|' \
regress/forward-control.sh*
sed -i 's|^RFWD_PORT=.*|RFWD_PORT=$(expr $TEST_SSH_PORT + 2)|' \
regress/forward-control.sh*
( ! grep -REi 'port=[2-9][0-9]*' regress) # try to find more of those
# patch testsuite: speed up
sed -i 's|sleep 1$|sleep .25|' regress/forward-control.sh
# extract LTESTS list to .tests/ltests/all:
grep -Ex 'tests:[[:space:]]*file-tests t-exec interop-tests extra-tests unit' Makefile
echo -ne '\necho-ltests:\n\techo ${LTESTS}' >> regress/Makefile
make -s -C regress echo-ltests | tr ' ' '\n' > .ltests/all
# separate ltests into $SPLIT roughly equal .tests/ltests/in/$ii parts:
grep -qFx connect .ltests/all
( ! grep -qFx nonex .ltests/all )
split -d -a2 --number=l/$SPLIT .ltests/all .ltests/in/
wc -l .ltests/in/*
grep -qFx connect .ltests/in/*
# generate the inverses of them --- .ltests/not-in/$ii:
( ! grep -qFx nonex .ltests/in/* )
for ((i = 0; i < SPLIT; i++)); do ii=$(printf %02d $i);
while read -r tname; do
if ! grep -qFx "$tname" ".ltests/in/$ii"; then
echo -n "$tname " >> ".ltests/not-in/$ii"
fi
done < .ltests/all
done
grep . .ltests/not-in/*
( ! grep -q ^connect .ltests/not-in/0 )
for ((i = 1; i < SPLIT; i++)); do ii=$(printf %02d $i);
grep -q ^connect .ltests/not-in/$ii
done
# prepare several test directories:
for PART in $PARTS; do
mkdir .t/${PART}
cp -ra * .t/${PART}/
sed -i "s|abs_top_srcdir=.*|abs_top_srcdir=$(pwd)/.t/${PART}|" \
.t/${PART}/Makefile
sed -i "s|abs_top_builddir=.*|abs_top_builddir=$(pwd)/.t/${PART}|" \
.t/${PART}/Makefile
sed -i "s|^BUILDDIR=.*|BUILDDIR=$(pwd)/.t/${PART}|" \
.t/${PART}/Makefile
done
# finally, run tests $PARTS in parallel in their own subtrees:
time make -f "$PARALLEL_MAKEFILE" -j$(nproc) $PARTS

6
plans/main.fmf Normal file
View file

@ -0,0 +1,6 @@
summary: Run all tests
execute:
how: tmt
discover:
how: fmf

View file

@ -1,4 +1,3 @@
SHA512 (openssh-9.3p1.tar.gz) = 087ff6fe5f6caab4c6c3001d906399e02beffad7277280f11187420c2939fd4befdcb14643862a657ce4cad2f115b82a0a1a2c99df6ee54dcd76b53647637c19
SHA512 (openssh-9.3p1.tar.gz.asc) = 6222378eb24a445c6c1db255392b405f5369b1af0e92f558d4ba05b0d83ab0d084cb8f4b91d7ae8636f333d970638a6635e2bc7af885135dd34992d87f2ef1f4
SHA512 (pam_ssh_agent_auth-0.10.4.tar.gz) = caccf72174d15e43f4c86a459ac6448682e62116557cf1e1e828955f3d1731595b238df42adec57860e7f341e92daf5d8285020bcb5018f3b8a5145aa32ee1c2
SHA512 (openssh-10.2p1.tar.gz) = 66f3dd646179e71aaf41c33b6f14a207dc873d71d24f11c130a89dee317ee45398b818e5b94887b5913240964a38630d7bca3e481e0f1eff2e41d9e1cfdbdfc5
SHA512 (openssh-10.2p1.tar.gz.asc) = f1f71700b1b0b2117aed505488b98b7ebb51ce26e53184b08df0b07aa2c5a1e54dc4d3cbcbe871b5ad849a2a0e22b02af318ff22a68c980ab53b04be03c9bf3c
SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21

View file

@ -8,9 +8,7 @@ Documentation=man:ssh-agent(1) man:ssh-add(1) man:ssh(1)
Requires=ssh-agent.socket
[Service]
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStartPre=/usr/bin/rm -f $SSH_AUTH_SOCK
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
ExecStart=/usr/bin/ssh-agent -D
PassEnvironment=SSH_AGENT_PID
SuccessExitStatus=2
Type=simple

View file

@ -9,8 +9,14 @@ case $KEYTYPE in
if [[ -r "$FIPS" && $(cat $FIPS) == "1" ]]; then
exit 0
fi ;;
"rsa") ;; # always ok
"ecdsa") ;;
"rsa")
if [[ ! -z $SSH_RSA_BITS ]]; then
SSH_KEYGEN_OPTIONS="-b $SSH_RSA_BITS"
fi ;; # always ok
"ecdsa")
if [[ ! -z $SSH_ECDSA_BITS ]]; then
SSH_KEYGEN_OPTIONS="-b $SSH_ECDSA_BITS"
fi ;;
*) # wrong argument
exit 12 ;;
esac
@ -25,7 +31,7 @@ fi
rm -f $KEY{,.pub}
# create new keys
if ! $KEYGEN -q -t $KEYTYPE -f $KEY -C '' -N '' >&/dev/null; then
if ! $KEYGEN -q -t $KEYTYPE $SSH_KEYGEN_OPTIONS -f $KEY -C '' -N '' >&/dev/null; then
exit 1
fi

View file

@ -4,6 +4,9 @@ ConditionFileNotEmpty=|!/etc/ssh/ssh_host_%i_key
[Service]
Type=oneshot
# Set option as empty variable to suppress warnings upon expanding the command line
# when the config file under /etc does not exist or is empty.
Environment=OPTIONS=
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/libexec/openssh/sshd-keygen %i

View file

@ -9,6 +9,9 @@ Wants=ssh-host-keys-migration.service
[Service]
Type=notify
# Set option as empty variable to suppress warnings upon expanding the command line
# when the config file under /etc does not exist or is empty.
Environment=OPTIONS=
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID

View file

@ -5,3 +5,7 @@
# example using systemctl enable sshd-keygen@dsa.service to allow creation
# of DSA key or systemctl mask sshd-keygen@rsa.service to disable RSA key
# creation.
#SSH_RSA_BITS=3072
#SSH_ECDSA_BITS=256
OPTIONS=""

View file

@ -8,6 +8,10 @@ After=sshd-keygen.target
Wants=ssh-host-keys-migration.service
[Service]
# Set option as empty variable to avoid warnings upon expanding the command line
# when the config file under /etc does not exist or is empty.
Environment=OPTIONS=
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=-/usr/sbin/sshd -i $OPTIONS
ExecStart=-/usr/sbin/sshd -i $OPTIONS -o "AuthorizedKeysFile ${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys"
StandardInput=socket
ImportCredential=ssh.ephemeral-authorized_keys-all

11
tests/main.fmf Normal file
View file

@ -0,0 +1,11 @@
test: ./runtest.sh
framework: beakerlib
require:
- iproute # needs ip command
- procps-ng # needs ps and pgrep commands
- initscripts # needs service command
- openssh-clients # needs ssh command
- findutils # needs find command
- net-tools # needs netstat command
- libselinux-utils # needs selinuxenabled command
- nmap-ncat # needs nc command

Some files were not shown because too many files have changed in this diff Show more