Compare commits

..

3 commits

Author SHA1 Message Date
Dmitry Belyavskiy
bbc9a8c13f The code is compiling 2024-01-12 15:03:41 +01:00
Dmitry Belyavskiy
61f514d274 pkcs11-uri cleanup 2024-01-12 14:43:38 +01:00
Dmitry Belyavskiy
70d0863455 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 14:02:11 +01:00
107 changed files with 10364 additions and 10519 deletions

View file

@ -1 +0,0 @@
1

8
.gitignore vendored
View file

@ -60,11 +60,3 @@ pam_ssh_agent_auth-0.9.2.tar.bz2
/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,26 +0,0 @@
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,41 +0,0 @@
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,28 +0,0 @@
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,27 +0,0 @@
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,25 +0,0 @@
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,58 +0,0 @@
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,157 +0,0 @@
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,25 +0,0 @@
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

View file

@ -1,265 +0,0 @@
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,47 +0,0 @@
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,616 +0,0 @@
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

@ -1,332 +0,0 @@
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

@ -1,25 +0,0 @@
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

@ -1,402 +0,0 @@
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

@ -1,25 +0,0 @@
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

@ -1,27 +0,0 @@
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

@ -1,86 +0,0 @@
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

@ -1,450 +0,0 @@
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

@ -1,139 +0,0 @@
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,229 +0,0 @@
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,17 +1,7 @@
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)
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
err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
@ -26,6 +16,3 @@ index cb7152dc8..bbe93d838 100644
gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
gtk_dialog_run(GTK_DIALOG(err));
--
2.52.0

View file

@ -1,17 +1,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 @@
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 @@
#include <unistd.h>
#include <X11/Xlib.h>
@ -19,7 +9,7 @@ index a62f98152..cb7152dc8 100644
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
@@ -146,6 +147,17 @@ parse_env_hex_color(const char *env, GdkColor *c)
@@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia
return 1;
}
@ -37,7 +27,7 @@ index a62f98152..cb7152dc8 100644
static int
passphrase_dialog(char *message, int prompt_type)
{
@@ -153,7 +165,7 @@ passphrase_dialog(char *message, int prompt_type)
const char *failed;
char *passphrase, *local;
int result, grab_tries, grab_server, grab_pointer;
int buttons, default_response;
@ -46,7 +36,7 @@ index a62f98152..cb7152dc8 100644
GdkGrabStatus status;
GdkColor fg, bg;
int fg_set = 0, bg_set = 0;
@@ -199,14 +211,19 @@ passphrase_dialog(char *message, int prompt_type)
@@ -104,14 +116,19 @@ passphrase_dialog(char *message)
gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg);
if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) {
@ -55,12 +45,12 @@ index a62f98152..cb7152dc8 100644
+ 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);
@ -68,7 +58,7 @@ index a62f98152..cb7152dc8 100644
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
gtk_widget_grab_focus(entry);
if (prompt_type == PROMPT_ENTRY) {
@@ -225,6 +242,22 @@ passphrase_dialog(char *message, int prompt_type)
@@ -130,6 +145,22 @@ passphrase_dialog(char *message)
g_signal_connect(G_OBJECT(entry), "key_press_event",
G_CALLBACK(check_none), dialog);
}
@ -91,6 +81,3 @@ index a62f98152..cb7152dc8 100644
}
/* Grab focus */
--
2.52.0

View file

@ -0,0 +1,14 @@
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,18 +1,7 @@
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.
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.
.Nm
exits with the exit status of the remote command or with 255
if an error occurred.
@ -21,11 +10,10 @@ index 697f4e42a..db92ac9af 100644
.Sh SEE ALSO
.Xr scp 1 ,
.Xr sftp 1 ,
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
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
started last).
The content of this file is not sensitive; it can be world-readable.
.El
@ -34,6 +22,3 @@ index 7fbca776a..0226a8303 100644
.Sh SEE ALSO
.Xr scp 1 ,
.Xr sftp 1 ,
--
2.52.0

View file

@ -0,0 +1,16 @@
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,25 +1,7 @@
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
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
log_init(const char *av0, LogLevel level, SyslogFacility facility,
int on_stderr)
{
@ -31,7 +13,7 @@ index 5969c4a16..49b0c8a68 100644
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
struct syslog_data sdata = SYSLOG_DATA_INIT;
#endif
@@ -208,8 +213,10 @@ log_init(const char *av0, LogLevel level, SyslogFacility facility,
@@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level
exit(1);
}
@ -44,10 +26,9 @@ index 5969c4a16..49b0c8a68 100644
log_on_stderr = on_stderr;
if (on_stderr)
diff --git a/log.h b/log.h
index 8e8dfc23f..70048a8af 100644
--- a/log.h
+++ b/log.h
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
@@ -52,6 +52,7 @@ typedef enum {
typedef void (log_handler_fn)(LogLevel, int, const char *, void *);
@ -56,11 +37,43 @@ index 8e8dfc23f..70048a8af 100644
LogLevel log_level_get(void);
int log_change_level(LogLevel);
int log_is_on_stderr(void);
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)
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;
}
void
@ -85,11 +98,14 @@ index d463d6a9c..453469665 100644
}
#ifdef GSSAPI
diff --git a/monitor.h b/monitor.h
index dbc7e0037..d4d631ddc 100644
--- a/monitor.h
+++ b/monitor.h
@@ -85,7 +85,7 @@ struct monitor {
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;
};
struct monitor *monitor_init(void);
@ -98,11 +114,10 @@ index dbc7e0037..d4d631ddc 100644
struct Authctxt;
void monitor_child_preauth(struct ssh *, struct monitor *);
diff --git a/session.c b/session.c
index b8a2dae92..d034f5c65 100644
--- a/session.c
+++ b/session.c
@@ -162,6 +162,7 @@ login_cap_t *lc;
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;
static int is_child = 0;
static int in_chroot = 0;
@ -110,7 +125,7 @@ index b8a2dae92..d034f5c65 100644
/* File containing userauth info, if ExposeAuthInfo set */
static char *auth_info_file = NULL;
@@ -632,6 +633,7 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
@@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con
int ret;
const char *forced = NULL, *tty = NULL;
char session_type[1024];
@ -118,7 +133,7 @@ index b8a2dae92..d034f5c65 100644
if (options.adm_forced_command) {
original_command = command;
@@ -691,6 +693,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
@@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con
tty += 5;
}
@ -129,7 +144,7 @@ index b8a2dae92..d034f5c65 100644
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d",
session_type,
tty == NULL ? "" : " on ",
@@ -1469,14 +1475,6 @@ child_close_fds(struct ssh *ssh)
@@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh)
/* Stop directing logs to a high-numbered fd before we close it */
log_redirect_stderr_to(NULL);
@ -144,7 +159,7 @@ index b8a2dae92..d034f5c65 100644
}
/*
@@ -1609,8 +1607,6 @@ do_child(struct ssh *ssh, Session *s, const char *command)
@@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co
exit(1);
}
@ -153,10 +168,10 @@ index b8a2dae92..d034f5c65 100644
do_rc_files(ssh, s, shell);
/* restore SIGPIPE for child */
@@ -1638,9 +1634,17 @@ do_child(struct ssh *ssh, Session *s, const char *command)
#ifdef WITH_SELINUX
ssh_selinux_change_context("sftpd_t");
#endif
@@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co
argv[i] = NULL;
optind = optreset = 1;
__progname = argv[0];
- exit(sftp_server_main(i, argv, s->pw));
+ exit(sftp_server_main(i, argv, s->pw, have_dev_log));
}
@ -172,31 +187,29 @@ index b8a2dae92..d034f5c65 100644
fflush(NULL);
/* Get the last component of the shell name. */
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;
}
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 @@
- 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)
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)
}
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;
@@ -1909,7 +1909,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
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,
extern char *__progname;
__progname = ssh_get_progname(argv[0]);
@ -205,7 +218,7 @@ index 777821acd..185ad1459 100644
pw = pwcopy(user_pw);
@@ -1982,7 +1982,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
@@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv,
}
}
@ -214,23 +227,21 @@ index 777821acd..185ad1459 100644
/*
* On platforms where we can, avoid making /proc/self/{mem,maps}
diff --git a/sftp.h b/sftp.h
index 2bde8bb7f..ddf1a3968 100644
--- a/sftp.h
+++ b/sftp.h
@@ -97,5 +97,5 @@
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;
}
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
- 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
}
/* New socket pair */
- monitor_reinit(pmonitor);
@ -238,7 +249,7 @@ index 028d5850e..4a5eaa1ff 100644
pmonitor->m_pid = fork();
if (pmonitor->m_pid == -1)
@@ -434,6 +434,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
@@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct
close(pmonitor->m_sendfd);
pmonitor->m_sendfd = -1;
@ -250,6 +261,3 @@ index 028d5850e..4a5eaa1ff 100644
/* Demote the private keys to public keys. */
demote_sensitive_data();
--
2.52.0

View file

@ -0,0 +1,14 @@
--- 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

@ -0,0 +1,131 @@
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
--- a/openbsd-compat/port-linux.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/openbsd-compat/port-linux.c (date 1703108053912)
@@ -207,7 +207,7 @@
xasprintf(&newctx, "%.*s%s%s", (int)(cx - oldctx + 1), oldctx,
newname, cx2 == NULL ? "" : cx2);
- debug3_f("setting context from '%s' to '%s'", oldctx, newctx);
+ debug_f("setting context from '%s' to '%s'", oldctx, newctx);
if (setcon(newctx) < 0)
do_log2_f(log_level, "setcon %s from %s failed with %s",
newctx, oldctx, strerror(errno));
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 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,21 +1,7 @@
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,
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
FILE *fp;
char file[MAXPATHLEN];
char *line = NULL;
@ -23,7 +9,7 @@ index 187faf929..03188d9b3 100644
struct stat st;
struct passwd *pw = the_authctxt->pw;
int found_principal = 0;
@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
/* If both .k5login and .k5users DNE, self-login is ok. */
@ -32,19 +18,18 @@ index 187faf929..03188d9b3 100644
return ssh_krb5_kuserok(krb_context, principal, luser,
k5login_exists);
}
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)
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
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;
@@ -396,6 +397,8 @@ fill_default_server_options(ServerOptions *options)
options->permit_empty_passwd = -1;
@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption
#endif
if (options->use_kuserok == -1)
options->use_kuserok = 1;
@ -53,16 +38,16 @@ index 8f4b2b43e..5e40f1b00 100644
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -579,7 +582,7 @@ typedef enum {
@@ -418,7 +421,7 @@ typedef enum {
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
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,
@@ -675,6 +678,7 @@ static struct {
@@ -497,14 +500,16 @@ static struct {
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
@ -70,7 +55,8 @@ index 8f4b2b43e..5e40f1b00 100644
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
@@ -683,6 +687,7 @@ static struct {
{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
@ -78,7 +64,7 @@ index 8f4b2b43e..5e40f1b00 100644
#endif
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
@@ -2440,6 +2445,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
@@ -1653,6 +1658,10 @@ process_server_config_line(ServerOptions
intptr = &options->use_kuserok;
goto parse_flag;
@ -86,10 +72,10 @@ index 8f4b2b43e..5e40f1b00 100644
+ intptr = &options->enable_k5users;
+ goto parse_flag;
+
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)
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
@@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d
M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk);
M_CP_INTOPT(use_kuserok);
@ -97,7 +83,7 @@ index 8f4b2b43e..5e40f1b00 100644
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
@@ -3316,6 +3326,7 @@ dump_config(ServerOptions *o)
@@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o)
# endif
dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
@ -105,35 +91,21 @@ index 8f4b2b43e..5e40f1b00 100644
#endif
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
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 */
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 */
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 --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
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
on logout.
The default is
.Cm yes .
@ -146,6 +118,14 @@ index c360fcfff..a0fc6064f 100644
.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.
--
2.52.0
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

View file

@ -1,17 +1,7 @@
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)
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)
if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts,
&option_size) >= 0 && option_size != 0) {
@ -48,8 +38,5 @@ index cb4b0523d..1c72e664a 100644
+ }
+ } while (i < option_size);
}
return;
#endif /* IP_OPTIONS */
}
--
2.52.0

View file

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

View file

@ -1,129 +1,7 @@
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
+polyinstantiation of home directories and SELinux MLS policy enabled.
+
+To use ssh-keycat, set these options in /etc/ssh/sshd_config file:
+ AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat
+ AuthorizedKeysCommandUser root
+
+Do not forget to enable public key authentication:
+ PubkeyAuthentication yes
+
+
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
@@ -58,6 +59,7 @@ CHANNELLIBS=@CHANNELLIBS@
K5LIBS=@K5LIBS@
GSSLIBS=@GSSLIBS@
SSHDLIBS=@SSHDLIBS@
+KEYCATLIBS=@KEYCATLIBS@
LIBEDIT=@LIBEDIT@
LIBFIDO2=@LIBFIDO2@
LIBWTMPDB=@LIBWTMPDB@
@@ -75,7 +77,7 @@ MKDIR_P=@MKDIR_P@
.SUFFIXES: .lo
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE)
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) $(SK_STANDALONE)
LIBOPENSSH_OBJS=\
ssh_api.o \
@@ -252,6 +254,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS)
ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
+
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)
@@ -439,6 +444,7 @@ install-files:
$(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)
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT)
$(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 --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"
SSHDLIBS="$SSHDLIBS -lpam"
+ KEYCATLIBS="$KEYCATLIBS -lpam"
AC_DEFINE([USE_PAM], [1],
[Define if you want to enable PAM support])
@@ -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,
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);
}
@ -137,13 +15,88 @@ index 5bed34735..7e27a38d1 100644
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;
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
@@ -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
+polyinstantiation of home directories and SELinux MLS policy enabled.
+
+To use ssh-keycat, set these options in /etc/ssh/sshd_config file:
+ AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat
+ AuthorizedKeysCommandUser root
+
+Do not forget to enable public key authentication:
+ 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
ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
SFTP_SERVER=$(libexecdir)/sftp-server
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
+SSH_KEYCAT=$(libexecdir)/ssh-keycat
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper
PRIVSEP_PATH=@PRIVSEP_PATH@
@@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@
K5LIBS=@K5LIBS@
GSSLIBS=@GSSLIBS@
SSHDLIBS=@SSHDLIBS@
+KEYCATLIBS=@KEYCATLIBS@
LIBEDIT=@LIBEDIT@
LIBFIDO2=@LIBFIDO2@
AR=@AR@
@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@
.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)
XMSS_OBJS=\
ssh-xmss.o \
@@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
+
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:
$(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)
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT)
$(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 *);
+int sshd_selinux_enabled(void);
void sshd_selinux_copy_context(void);
void sshd_selinux_setup_exec_context(char *);
+int sshd_selinux_setup_env_variables(void);
#endif
#ifdef LINUX_OOM_ADJUST
diff -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;
extern int inetd_flag;
extern int rexeced_flag;
+/* Wrapper around is_selinux_enabled() to log its return value once only */
+int
@ -162,7 +115,7 @@ index b9fbe38b7..4d56745f7 100644
/* Send audit message */
static int
sshd_selinux_send_audit_message(int success, security_context_t default_context,
@@ -317,7 +331,7 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -308,7 +322,7 @@ sshd_selinux_getctxbyname(char *pwname,
/* Setup environment variables for pam_selinux */
static int
@ -171,14 +124,14 @@ index b9fbe38b7..4d56745f7 100644
{
const char *reqlvl;
char *role;
@@ -328,16 +342,16 @@ sshd_selinux_setup_pam_variables(void)
@@ -319,16 +333,16 @@ sshd_selinux_setup_pam_variables(void)
ssh_selinux_get_role_level(&role, &reqlvl);
- rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
+ rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
if (inetd_flag) {
if (inetd_flag && !rexeced_flag) {
use_current = "1";
} else {
use_current = "";
@ -191,7 +144,7 @@ index b9fbe38b7..4d56745f7 100644
if (role != NULL)
free(role);
@@ -345,6 +359,24 @@ sshd_selinux_setup_pam_variables(void)
@@ -336,6 +350,24 @@ sshd_selinux_setup_pam_variables(void)
return rv;
}
@ -216,7 +169,7 @@ index b9fbe38b7..4d56745f7 100644
/* Set the execution context to the default for the specified user */
void
sshd_selinux_setup_exec_context(char *pwname)
@@ -353,7 +385,7 @@ sshd_selinux_setup_exec_context(char *pwname)
@@ -344,7 +376,7 @@ sshd_selinux_setup_exec_context(char *pw
int r = 0;
security_context_t default_ctx = NULL;
@ -225,23 +178,19 @@ index b9fbe38b7..4d56745f7 100644
return;
if (options.use_pam) {
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 *);
@@ -415,7 +447,7 @@ sshd_selinux_copy_context(void)
{
security_context_t *ctx;
void sshd_selinux_setup_exec_context(char *);
+int sshd_selinux_setup_env_variables(void);
#endif
- if (!ssh_selinux_enabled())
+ if (!sshd_selinux_enabled())
return;
#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)
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 WITH_SELINUX
/* Cache selinux status for later use */
@ -250,11 +199,9 @@ index bcf1b0491..c92a0cba6 100644
#endif
#ifdef USE_SOLARIS_PROJECTS
diff --git a/ssh-keycat.c b/ssh-keycat.c
new file mode 100644
index 000000000..5678be079
--- /dev/null
+++ b/ssh-keycat.c
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
@@ -0,0 +1,241 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
@ -497,6 +444,41 @@ index 000000000..5678be079
+ }
+ return ev;
+}
--
2.52.0
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 ""

View file

@ -1,22 +1,7 @@
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 @@
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 @@
extern ServerOptions options;
@ -38,7 +23,7 @@ index 4910aa38a..b9c261a24 100644
static int
krb5_init(void *context)
{
@@ -158,8 +173,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -160,8 +175,9 @@ auth_krb5_password(Authctxt *authctxt, c
if (problem)
goto out;
@ -50,11 +35,10 @@ index 4910aa38a..b9c261a24 100644
problem = -1;
goto out;
}
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 *,
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
int);
static krb5_context krb_context = NULL;
@ -62,7 +46,7 @@ index 820f794cf..187faf929 100644
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
@@ -91,6 +92,103 @@ ssh_gssapi_krb5_init(void)
@@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void)
* Returns true if the user is OK to log in, otherwise returns 0
*/
@ -166,7 +150,7 @@ index 820f794cf..187faf929 100644
static int
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
{
@@ -115,7 +213,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
@@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
/* 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. */
@ -176,7 +160,7 @@ index 820f794cf..187faf929 100644
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 principal, const char *name,
@@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
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)) {
@ -188,19 +172,18 @@ index 820f794cf..187faf929 100644
}
if ((fp = fopen(file, "r")) == NULL) {
int saved_errno = errno;
diff --git a/servconf.c b/servconf.c
index 7bf1507df..8f4b2b43e 100644
--- a/servconf.c
+++ b/servconf.c
@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions *options)
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
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;
@@ -393,6 +394,8 @@ fill_default_server_options(ServerOptions *options)
options->permit_empty_passwd = -1;
@@ -278,6 +279,8 @@ fill_default_server_options(ServerOption
if (options->gss_kex_algorithms == NULL)
options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
#endif
@ -209,16 +192,16 @@ index 7bf1507df..8f4b2b43e 100644
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -561,7 +564,7 @@ typedef enum {
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
@@ -399,7 +402,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,
@@ -653,12 +656,14 @@ static struct {
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -478,12 +481,14 @@ static struct {
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL },
@ -233,18 +216,18 @@ index 7bf1507df..8f4b2b43e 100644
#endif
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
@@ -2431,6 +2436,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
}
break;
@@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions
}
break;
+ case sKerberosUseKuserok:
+ intptr = &options->use_kuserok;
+ goto parse_flag;
+
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)
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
@@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d
M_CP_INTOPT(client_alive_interval);
M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk);
@ -252,19 +235,18 @@ index 7bf1507df..8f4b2b43e 100644
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
@@ -3305,6 +3315,7 @@ dump_config(ServerOptions *o)
@@ -2309,6 +2319,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 --git a/servconf.h b/servconf.h
index a4a38d6d7..11de36a23 100644
--- a/servconf.h
+++ b/servconf.h
@@ -151,6 +151,7 @@ typedef struct {
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 {
* authenticated with Kerberos. */
int kerberos_unique_ccache; /* If true, the acquired ticket will
* be stored in per-session ccache */
@ -272,23 +254,10 @@ index a4a38d6d7..11de36a23 100644
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 --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
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
.Cm no
can lead to overwriting previous tickets by subseqent connections to the same
user account.
@ -297,9 +266,9 @@ index cae0fd0b4..c360fcfff 100644
+The default is
+.Cm yes .
.It Cm KexAlgorithms
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
@@ -1354,6 +1358,7 @@ Available keywords are
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
@@ -1078,6 +1082,7 @@ Available keywords are
.Cm IPQoS ,
.Cm KbdInteractiveAuthentication ,
.Cm KerberosAuthentication ,
@ -307,6 +276,14 @@ index cae0fd0b4..c360fcfff 100644
.Cm LogLevel ,
.Cm MaxAuthTries ,
.Cm MaxSessions ,
--
2.52.0
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

View file

@ -0,0 +1,121 @@
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

@ -0,0 +1,264 @@
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/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
@@ -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/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-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/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 */
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,17 +1,6 @@
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
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
@@ -38,6 +38,7 @@
.Op Fl P Ar denied_requests
.Op Fl p Ar allowed_requests
@ -33,11 +22,10 @@ index 5311bf929..5e6e3aa44 100644
.El
.Pp
On some systems,
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;
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;
/* Version of client */
static u_int version;
@ -48,7 +36,7 @@ index 185ad1459..e04fc63b3 100644
/* SSH2_FXP_INIT received */
static int init_done;
@@ -741,6 +745,7 @@ process_open(u_int32_t id)
@@ -683,6 +687,7 @@ process_open(u_int32_t id)
Attrib a;
char *name;
int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE;
@ -56,7 +44,7 @@ index 185ad1459..e04fc63b3 100644
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */
@@ -750,6 +755,10 @@ process_open(u_int32_t id)
@@ -692,6 +697,10 @@ process_open(u_int32_t id)
debug3("request %u: open flags %d", id, pflags);
flags = flags_from_portable(pflags);
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
@ -67,7 +55,7 @@ index 185ad1459..e04fc63b3 100644
logit("open \"%s\" flags %s mode 0%o",
name, string_from_portable(pflags), mode);
if (readonly &&
@@ -771,6 +780,8 @@ process_open(u_int32_t id)
@@ -713,6 +722,8 @@ process_open(u_int32_t id)
}
}
}
@ -76,7 +64,7 @@ index 185ad1459..e04fc63b3 100644
if (status != SSH2_FX_OK)
send_status(id, status);
free(name);
@@ -1890,7 +1901,7 @@ sftp_server_usage(void)
@@ -1494,7 +1505,7 @@ sftp_server_usage(void)
fprintf(stderr,
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
"[-l log_level]\n\t[-P denied_requests] "
@ -85,7 +73,7 @@ index 185ad1459..e04fc63b3 100644
" %s -Q protocol_feature\n",
__progname, __progname);
exit(1);
@@ -1914,7 +1925,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle
@@ -1520,7 +1531,7 @@ sftp_server_main(int argc, char **argv,
pw = pwcopy(user_pw);
while (!skipargs && (ch = getopt(argc, argv,
@ -94,7 +82,7 @@ index 185ad1459..e04fc63b3 100644
switch (ch) {
case 'Q':
if (strcasecmp(optarg, "requests") != 0) {
@@ -1976,6 +1987,15 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle
@@ -1580,6 +1591,15 @@ sftp_server_main(int argc, char **argv,
fatal("Invalid umask \"%s\"", optarg);
(void)umask((mode_t)mask);
break;
@ -110,6 +98,3 @@ index 185ad1459..e04fc63b3 100644
case 'h':
default:
sftp_server_usage();
--
2.52.0

View file

@ -0,0 +1,12 @@
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,19 +1,7 @@
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_
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
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m);
sshbuf_free(m);
}
@ -64,11 +52,10 @@ index fb44ae733..17a6c9786 100644
+ pmonitor->m_recvfd = fd;
+}
#endif /* SSH_AUDIT_EVENTS */
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);
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);
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);
@ -77,11 +64,10 @@ index 1bcbfd305..2b814dbd1 100644
#endif
struct Session;
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;
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;
login_cap_t *lc;
#endif
@ -92,7 +78,7 @@ index 107edcf91..80282dfd8 100644
static int is_child = 0;
static int in_chroot = 0;
static int have_dev_log = 1;
@@ -358,6 +362,8 @@ xauth_valid_string(const char *s)
@@ -289,6 +293,8 @@ xauth_valid_string(const char *s)
return 1;
}
@ -101,7 +87,7 @@ index 107edcf91..80282dfd8 100644
#define USE_PIPES 1
/*
* This is called to fork and execute a command when we have no tty. This
@@ -481,6 +487,8 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
@@ -424,6 +430,8 @@ do_exec_no_pty(Session *s, const char *c
close(err[0]);
#endif
@ -110,7 +96,7 @@ index 107edcf91..80282dfd8 100644
/* Do processing for the child (exec command etc). */
do_child(ssh, s, command);
/* NOTREACHED */
@@ -595,6 +603,9 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
@@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm
/* Close the extra descriptor for the pseudo tty. */
close(ttyfd);
@ -120,22 +106,22 @@ index 107edcf91..80282dfd8 100644
/* record login, etc. similar to login(1) */
#ifndef HAVE_OSF_SIA
do_login(ssh, s, command);
@@ -729,6 +740,8 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
@@ -717,6 +728,8 @@ do_exec(Session *s, const char *command)
}
if (s->command != NULL && s->ptyfd == -1)
s->command_handle = mm_audit_run_command(ssh, s->command);
s->command_handle = PRIVSEP(audit_run_command(ssh, s->command));
+ if (pipe(paudit) < 0)
+ fatal("pipe: %s", strerror(errno));
#endif
if (s->ttyfd != -1)
ret = do_exec_pty(ssh, s, command);
@@ -744,6 +757,20 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
@@ -732,6 +745,20 @@ do_exec(Session *s, const char *command)
*/
sshbuf_reset(loginmsg);
+#ifdef SSH_AUDIT_EVENTS
+ close(paudit[1]);
+ if (ret == 0) {
+ if (use_privsep && ret == 0) {
+ /*
+ * Read the audit messages from forked child and send them
+ * back to monitor. We don't want to communicate directly,
@ -150,7 +136,7 @@ index 107edcf91..80282dfd8 100644
return ret;
}
@@ -1490,6 +1517,33 @@ child_close_fds(struct ssh *ssh)
@@ -1538,6 +1565,34 @@ child_close_fds(void)
log_redirect_stderr_to(NULL);
}
@ -161,11 +147,12 @@ index 107edcf91..80282dfd8 100644
+ int pparent = paudit[1];
+ close(paudit[0]);
+ /* Hack the monitor pipe to avoid race condition with parent */
+ mm_set_monitor_pipe(pparent);
+ if (use_privsep)
+ mm_set_monitor_pipe(pparent);
+#endif
+
+ /* remove hostkey from the child's memory */
+ /* FIXME beldmit destroy_sensitive_data(ssh); */
+ destroy_sensitive_data(ssh, use_privsep);
+ /*
+ * We can audit this, because we hacked the pipe to direct the
+ * messages over postauth child. But this message requires answer
@ -184,12 +171,12 @@ index 107edcf91..80282dfd8 100644
/*
* Performs common processing for the child, such as setting up the
* environment, closing extra file descriptors, setting the user and group
@@ -1507,13 +1561,6 @@ do_child(struct ssh *ssh, Session *s, const char *command)
@@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
- /* remove keys from memory */
- destroy_sensitive_data(ssh);
- /* remove hostkey from the child's memory */
- destroy_sensitive_data(ssh, 1);
- 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. */
@ -198,6 +185,3 @@ index 107edcf91..80282dfd8 100644
/* Force a password change */
if (s->authctxt->force_pwchange) {
do_setusercontext(pw);
--
2.52.0

View file

@ -1,20 +1,8 @@
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 035032221..4910aa38a 100644
index 2b02a04..19b9364 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -465,5 +465,21 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm
@@ -375,5 +375,21 @@ cleanup:
return (krb5_cc_resolve(ctx, ccname, ccache));
}
}
@ -37,10 +25,10 @@ index 035032221..4910aa38a 100644
#endif /* !HEIMDAL */
#endif /* KRB5 */
diff --git a/auth.h b/auth.h
index 10e88e11f..391630350 100644
index f9d191c..c432d2f 100644
--- a/auth.h
+++ b/auth.h
@@ -247,6 +247,8 @@ int sys_auth_passwd(struct ssh *, const char *);
@@ -222,6 +222,8 @@ int sys_auth_passwd(Authctxt *, const char *);
#if defined(KRB5) && !defined(HEIMDAL)
krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
@ -50,10 +38,10 @@ index 10e88e11f..391630350 100644
#endif /* AUTH_H */
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index df55512d3..820f794cf 100644
index a7c0c5f..df8cc9a 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -144,8 +144,27 @@ ssh_gssapi_k5login_exists()
@@ -244,8 +244,27 @@ ssh_gssapi_k5login_exists()
{
char file[MAXPATHLEN];
struct passwd *pw = the_authctxt->pw;
@ -83,10 +71,10 @@ index df55512d3..820f794cf 100644
}
diff --git a/sshd.8 b/sshd.8
index e2d8ff003..fa33f5232 100644
index 5c4f15b..135e290 100644
--- a/sshd.8
+++ b/sshd.8
@@ -880,6 +880,10 @@ rlogin/rsh.
@@ -806,6 +806,10 @@ rlogin/rsh.
These files enforce GSSAPI/Kerberos authentication access control.
Further details are described in
.Xr ksu 1 .
@ -97,6 +85,3 @@ index e2d8ff003..fa33f5232 100644
.Pp
.It Pa ~/.ssh/
This directory is the default location for all user-specific configuration
--
2.52.0

View file

@ -1,17 +1,21 @@
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
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>
---
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
@@ -140,7 +140,33 @@ closefrom(int lowfd)
@@ -82,7 +82,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))
@ -45,6 +49,4 @@ index 49a4f35ff..f61124585 100644
}
(void) closedir(dirp);
return;
--
2.52.0

View file

@ -1,32 +1,22 @@
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,
--- a/channels.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/channels.c (date 1703026069921)
@@ -5075,11 +5075,13 @@
}
static int
-connect_local_xsocket_path(const char *pathname)
+connect_local_xsocket_path(const char *pathname, int len)
{
int sock;
struct sockaddr_un addr;
+ if (len <= 0)
+ return -1;
+ if (len <= 0)
+ return -1;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
error("socket: %.100s", strerror(errno));
@@ -5181,11 +5183,12 @@ connect_local_xsocket_path(const char *pathname)
@@ -5087,11 +5089,12 @@
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
@ -41,8 +31,8 @@ index 80014ff34..5ce6bd400 100644
- error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
return -1;
}
@@ -5193,8 +5196,18 @@ static int
@@ -5099,8 +5102,18 @@
connect_local_xsocket(u_int dnr)
{
char buf[1024];
@ -63,6 +53,3 @@ index 80014ff34..5ce6bd400 100644
}
#ifdef __APPLE__
--
2.52.0

View file

@ -1,22 +1,18 @@
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)
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)
*/
int
x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
@ -25,33 +21,66 @@ index 26ed9945f..c26380e25 100644
u_int *display_numberp, int **chanids)
{
Channel *nc = NULL;
@@ -5080,8 +5080,11 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS)
@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_
if (chanids == NULL)
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 < x11_display_offset + MAX_DISPLAYS;
- display_number < MAX_DISPLAYS;
+ display_number < x11_max_displays;
display_number++) {
port = X11_BASE_PORT + display_number;
- port = 6000 + display_number;
+ port = X11_PORT_MIN + display_number;
+ if (port < X11_PORT_MIN) /* overflow */
+ break;
memset(&hints, 0, sizeof(hints));
@@ -5146,7 +5149,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
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_
if (num_socks > 0)
break;
}
- if (display_number >= x11_display_offset + MAX_DISPLAYS) {
+ if (display_number >= x11_max_displays || port < X11_BASE_PORT ) {
- if (display_number >= MAX_DISPLAYS) {
+ if (display_number >= x11_max_displays || port < X11_PORT_MIN ) {
error("Failed to allocate internet-domain X11 display socket.");
return -1;
}
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 *);
@@ -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 *);
void channel_set_x11_refuse_time(struct ssh *, time_t);
int x11_connect_display(struct ssh *);
@ -59,12 +88,11 @@ index 7456541f8..754bd98ee 100644
+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);
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)
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
options->print_lastlog = -1;
options->x11_forwarding = -1;
options->x11_display_offset = -1;
@ -72,7 +100,7 @@ index fb1d150cd..956205f6d 100644
options->x11_use_localhost = -1;
options->permit_tty = -1;
options->permit_user_rc = -1;
@@ -357,6 +358,8 @@ fill_default_server_options(ServerOptions *options)
@@ -243,6 +244,8 @@ fill_default_server_options(ServerOption
options->x11_forwarding = 0;
if (options->x11_display_offset == -1)
options->x11_display_offset = 10;
@ -81,16 +109,16 @@ index fb1d150cd..956205f6d 100644
if (options->x11_use_localhost == -1)
options->x11_use_localhost = 1;
if (options->xauth_location == NULL)
@@ -582,7 +585,7 @@ typedef enum {
sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
@@ -419,7 +422,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,
@@ -725,6 +728,7 @@ static struct {
@@ -540,6 +543,7 @@ static struct {
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
@ -98,7 +126,7 @@ index fb1d150cd..956205f6d 100644
{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
@@ -1775,6 +1779,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
@@ -1316,6 +1320,10 @@ process_server_config_line(ServerOptions
*intptr = value;
break;
@ -109,7 +137,7 @@ index fb1d150cd..956205f6d 100644
case sX11UseLocalhost:
intptr = &options->x11_use_localhost;
goto parse_flag;
@@ -3037,6 +3045,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
@@ -2063,6 +2071,7 @@ copy_set_server_options(ServerOptions *d
M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
M_CP_INTOPT(x11_display_offset);
M_CP_INTOPT(x11_forwarding);
@ -117,7 +145,7 @@ index fb1d150cd..956205f6d 100644
M_CP_INTOPT(x11_use_localhost);
M_CP_INTOPT(permit_tty);
M_CP_INTOPT(permit_user_rc);
@@ -3332,6 +3341,7 @@ dump_config(ServerOptions *o)
@@ -2315,6 +2324,7 @@ dump_config(ServerOptions *o)
#endif
dump_cfg_int(sLoginGraceTime, o->login_grace_time);
dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
@ -125,11 +153,10 @@ index fb1d150cd..956205f6d 100644
dump_cfg_int(sMaxAuthTries, o->max_authtries);
dump_cfg_int(sMaxSessions, o->max_sessions);
dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
diff --git a/servconf.h b/servconf.h
index 9b1a73b8d..6bfdf6305 100644
--- a/servconf.h
+++ b/servconf.h
@@ -38,6 +38,7 @@
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 @@
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
@ -137,7 +164,7 @@ index 9b1a73b8d..6bfdf6305 100644
/* Magic name for internal sftp-server */
#define INTERNAL_SFTP_NAME "internal-sftp"
@@ -114,6 +115,7 @@ typedef struct {
@@ -85,6 +86,7 @@ typedef struct {
int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */
int x11_display_offset; /* What DISPLAY number to start
* searching at */
@ -145,14 +172,13 @@ index 9b1a73b8d..6bfdf6305 100644
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 --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)
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)
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,
@ -161,11 +187,10 @@ index 80282dfd8..e53d044a0 100644
debug("x11_create_display_inet failed.");
return 0;
}
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
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
.Cm TrustedUserCAKeys ,
.Cm UnusedConnectionTimeout ,
.Cm X11DisplayOffset ,
@ -173,7 +198,7 @@ index 4ae4bebee..3dbce55fc 100644
.Cm X11Forwarding
and
.Cm X11UseLocalhost .
@@ -2112,6 +2113,12 @@ Specifies the first display number available for
@@ -1566,6 +1567,12 @@ Specifies the first display number avail
X11 forwarding.
This prevents sshd from interfering with real X11 servers.
The default is 10.
@ -186,6 +211,3 @@ index 4ae4bebee..3dbce55fc 100644
.It Cm X11Forwarding
Specifies whether X11 forwarding is permitted.
The argument must be
--
2.52.0

View file

@ -0,0 +1,98 @@
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

@ -0,0 +1,86 @@
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

File diff suppressed because it is too large Load diff

View file

@ -1,58 +1,40 @@
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 @@
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 @@
/* import */
extern ServerOptions options;
+extern int inetd_flag;
+extern int rexeced_flag;
+extern Authctxt *the_authctxt;
extern struct authmethod_cfg methodcfg_pubkey;
static char *
@@ -483,7 +485,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key,
format_key(const struct sshkey *key)
@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
+ runas_pw, temporarily_use_uid, restore_uid,
+ inetd_flag, the_authctxt)) == 0)
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
goto out;
uid_swapped = 1;
@@ -759,7 +762,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key,
@@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
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, the_authctxt)) == 0)
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
goto out;
uid_swapped = 1;
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)
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 *
pid_t
subprocess(const char *tag, const char *command,
int ac, char **av, FILE **child, u_int flags,
@ -62,7 +44,7 @@ index 7e27a38d1..2fd14159d 100644
{
FILE *f = NULL;
struct stat st;
@@ -2922,7 +2923,7 @@ subprocess(const char *tag, const char *command,
@@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
_exit(1);
}
#ifdef WITH_SELINUX
@ -71,11 +53,10 @@ index 7e27a38d1..2fd14159d 100644
error ("failed to copy environment: %s",
strerror(errno));
_exit(127);
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);
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);
#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,
@ -84,22 +65,36 @@ index f3c5a18c6..8cdfd7cec 100644
typedef struct arglist arglist;
struct arglist {
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
index 4d56745f7..ab083a637 100644
--- a/openbsd-compat/port-linux-sshd.c
+++ b/openbsd-compat/port-linux-sshd.c
@@ -48,10 +48,6 @@
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 @@
#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)
@@ -221,7 +217,8 @@ get_user_context(const char *sename, const char *role, const char *lvl,
@@ -223,7 +218,8 @@ get_user_context(const char *sename, con
}
static void
@ -109,7 +104,7 @@ index 4d56745f7..ab083a637 100644
{
*role = NULL;
*level = NULL;
@@ -239,8 +236,8 @@ ssh_selinux_get_role_level(char **role, const char **level)
@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
/* Return the default security context for the given username */
static int
@ -120,7 +115,7 @@ index 4d56745f7..ab083a637 100644
{
char *sename, *lvl;
char *role;
@@ -248,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
int r = 0;
context_t con = NULL;
@ -129,16 +124,16 @@ index 4d56745f7..ab083a637 100644
#ifdef HAVE_GETSEUSERBYNAME
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
@@ -270,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
if (r == 0) {
/* If launched from xinetd, we must use current level */
- if (inetd_flag) {
- if (inetd_flag && !rexeced_flag) {
+ if (inetd) {
security_context_t sshdsc=NULL;
if (getcon_raw(&sshdsc) < 0)
@@ -331,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
/* Setup environment variables for pam_selinux */
static int
@ -148,7 +143,7 @@ index 4d56745f7..ab083a637 100644
{
const char *reqlvl;
char *role;
@@ -340,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
debug3_f("setting execution context");
@ -157,12 +152,12 @@ index 4d56745f7..ab083a637 100644
rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
- if (inetd_flag) {
- if (inetd_flag && !rexeced_flag) {
+ if (inetd) {
use_current = "1";
} else {
use_current = "";
@@ -360,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
}
static int
@ -175,7 +170,7 @@ index 4d56745f7..ab083a637 100644
}
static int
@@ -372,25 +371,28 @@ do_setenv(char *name, const char *value)
@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
}
int
@ -209,7 +204,7 @@ index 4d56745f7..ab083a637 100644
switch (security_getenforce()) {
case -1:
fatal_f("security_getenforce() failed");
@@ -406,7 +408,7 @@ sshd_selinux_setup_exec_context(char *pwname)
@@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
debug3_f("setting execution context");
@ -218,51 +213,66 @@ index 4d56745f7..ab083a637 100644
if (r >= 0) {
r = setexeccon(user_ctx);
if (r < 0) {
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index c004071d1..26c5f773b 100644
--- 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"
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 @@
extern int use_privsep;
extern ServerOptions options;
+extern int inetd_flag;
+extern int rexeced_flag;
+extern Authctxt *the_authctxt;
/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
int
@@ -140,7 +142,9 @@ platform_setusercontext_post_groups(struct passwd *pw)
void
platform_pre_listen(void)
@@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru
}
#endif /* HAVE_SETPCRED */
#ifdef WITH_SELINUX
- sshd_selinux_setup_exec_context(pw->pw_name);
+ sshd_selinux_setup_exec_context(pw->pw_name,
+ inetd_flag, do_pam_putenv, the_authctxt,
+ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt,
+ options.use_pam);
#endif
}
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,
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
if ((pid = subprocess(tag, command, ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH|
@ -271,43 +281,3 @@ index 912a520c5..babe4a982 100644
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

@ -1,33 +1,6 @@
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
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
@@ -36,6 +36,7 @@
#include <openssl/bn.h>
@ -36,7 +9,7 @@ index 168dea1dd..8c9a29fa7 100644
#include "dh.h"
#include "pathnames.h"
@@ -164,6 +165,12 @@ choose_dh(int min, int wantbits, int max)
@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max
int best, bestcount, which, linenum;
struct dhgroup dhg;
@ -49,7 +22,7 @@ index 168dea1dd..8c9a29fa7 100644
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 +509,38 @@ dh_estimate(int bits)
@@ -502,4 +508,38 @@ dh_estimate(int bits)
return 8192;
}
@ -88,10 +61,9 @@ index 168dea1dd..8c9a29fa7 100644
+}
+
#endif /* WITH_OPENSSL */
diff --git a/dh.h b/dh.h
index c6326a39d..e51e292b8 100644
--- a/dh.h
+++ b/dh.h
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
@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);
@ -100,19 +72,18 @@ index c6326a39d..e51e292b8 100644
u_int dh_estimate(int);
void dh_set_moduli_file(const char *);
diff --git a/kex-names.c b/kex-names.c
index 31e395aa2..1360a4095 100644
--- a/kex-names.c
+++ b/kex-names.c
@@ -33,6 +33,7 @@
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 @@
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
+#include <openssl/fips.h>
#include <openssl/evp.h>
#endif
@@ -208,7 +209,10 @@ kex_names_valid(const char *names)
#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)
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (kex_alg_by_name(p) == NULL) {
@ -124,149 +95,9 @@ index 31e395aa2..1360a4095 100644
free(s);
return 0;
}
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
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
@@ -28,6 +28,7 @@
#ifdef WITH_OPENSSL
@ -274,8 +105,8 @@ index 097d83f30..ccbb9b580 100644
+#include <openssl/fips.h>
#include <sys/types.h>
#include "openbsd-compat/openssl-compat.h"
@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
#include <openssl/dh.h>
@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
@ -286,11 +117,10 @@ index 097d83f30..ccbb9b580 100644
p = g = NULL; /* belong to kex->dh now */
/* generate and send 'e', client DH public key */
diff --git a/myproposal.h b/myproposal.h
index 8fe9276c2..3e0ec6826 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -58,6 +58,18 @@
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 @@
"rsa-sha2-512," \
"rsa-sha2-256"
@ -308,8 +138,8 @@ index 8fe9276c2..3e0ec6826 100644
+
#define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \
"aes128-gcm@openssh.com,aes256-gcm@openssh.com," \
@@ -79,6 +91,27 @@
"aes128-ctr,aes192-ctr,aes256-ctr," \
@@ -78,6 +92,27 @@
#define KEX_CLIENT_MAC KEX_SERVER_MAC
@ -337,10 +167,9 @@ index 8fe9276c2..3e0ec6826 100644
/* Not a KEX value, but here so all the algorithm defaults are together */
#define SSH_ALLOWED_CA_SIGALGS \
"ssh-ed25519," \
diff --git a/readconf.c b/readconf.c
index 3f67f4de4..b6ad47b49 100644
--- a/readconf.c
+++ b/readconf.c
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
@@ -39,6 +39,7 @@
#include <string.h>
#include <stdarg.h>
@ -349,7 +178,7 @@ index 3f67f4de4..b6ad47b49 100644
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
@@ -3078,11 +3079,16 @@ fill_default_options(Options * options)
@@ -2538,11 +2538,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 */
@ -371,11 +200,10 @@ index 3f67f4de4..b6ad47b49 100644
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&options->what, \
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[] = {
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_
#ifdef __NR_open
SC_DENY(__NR_open, EACCES),
#endif
@ -385,22 +213,18 @@ index e0f2d4289..c52f64897 100644
#ifdef __NR_openat
SC_DENY(__NR_openat, EACCES),
#endif
diff --git a/servconf.c b/servconf.c
index ac84b74d9..f78615c28 100644
--- a/servconf.c
+++ b/servconf.c
@@ -37,7 +37,10 @@
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 @@
#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
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
@@ -244,11 +247,16 @@ assemble_algorithms(ServerOptions *o)
#endif
@@ -226,11 +226,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 */
@ -422,150 +246,10 @@ index ac84b74d9..f78615c28 100644
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index c8caa2221..4bcd9ef81 100644
--- 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 @@
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 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#endif
@ -573,7 +257,7 @@ index 8d27f6379..7d6ba516e 100644
#include "openbsd-compat/openssl-compat.h"
#include "openbsd-compat/sys-queue.h"
@@ -1664,6 +1665,10 @@ main(int ac, char **av)
@@ -1516,6 +1517,10 @@ main(int ac, char **av)
exit(0);
}
@ -584,10 +268,9 @@ index 8d27f6379..7d6ba516e 100644
/* Expand SecurityKeyProvider if it refers to an environment variable */
if (options.sk_provider != NULL && *options.sk_provider == '$' &&
strlen(options.sk_provider) > 1) {
diff --git a/sshconnect2.c b/sshconnect2.c
index b253f991b..fffa66c8d 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
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
@@ -45,6 +45,8 @@
#include <vis.h>
#endif
@ -597,48 +280,95 @@ index b253f991b..fffa66c8d 100644
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
@@ -262,6 +264,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
@@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {
+ char * gss_kex_filtered = FIPS_mode() ?
+ match_filter_allowlist(options.gss_kex_algorithms, GSS_KEX_DEFAULT_KEX_FIPS) : xstrdup(options.gss_kex_algorithms);
- /* Add the GSSAPI mechanisms currently supported on this
- * client to the key exchange algorithm proposal */
- orig = myproposal[PROPOSAL_KEX_ALGS];
-
- if (options.gss_server_identity) {
- gss_host = xstrdup(options.gss_server_identity);
- } else if (options.gss_trust_dns) {
- gss_host = remote_hostname(ssh);
- /* Fall back to specified host if we are using proxy command
- * and can not use DNS on that socket */
- if (strcmp(gss_host, "UNKNOWN") == 0) {
- free(gss_host);
+ if (FIPS_mode()) {
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
+ options.gss_keyex = 0;
+ } else {
+ /* Add the GSSAPI mechanisms currently supported on this
+ * client to the key exchange algorithm proposal */
+ orig = myproposal[PROPOSAL_KEX_ALGS];
+
/* Add the GSSAPI mechanisms currently supported on this
* client to the key exchange algorithm proposal */
orig = myproposal[PROPOSAL_KEX_ALGS];
@@ -281,7 +286,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
}
+ if (options.gss_server_identity) {
+ gss_host = xstrdup(options.gss_server_identity);
+ } else if (options.gss_trust_dns) {
+ gss_host = remote_hostname(ssh);
+ /* Fall back to specified host if we are using proxy command
+ * and can not use DNS on that socket */
+ if (strcmp(gss_host, "UNKNOWN") == 0) {
+ free(gss_host);
+ gss_host = xstrdup(host);
+ }
+ } else {
gss_host = xstrdup(host);
}
- } else {
- gss_host = xstrdup(host);
- }
gss = ssh_gssapi_client_mechanisms(gss_host,
- gss = ssh_gssapi_client_mechanisms(gss_host,
- options.gss_client_identity, options.gss_kex_algorithms);
+ options.gss_client_identity, gss_kex_filtered);
+ free(gss_kex_filtered);
- if (gss) {
- debug("Offering GSSAPI proposal: %s", gss);
- xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
- "%s,%s", gss, orig);
-
- /* If we've got GSSAPI algorithms, then we also support the
- * 'null' hostkey, as a last resort */
- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
- "%s,null", orig);
+ gss = ssh_gssapi_client_mechanisms(gss_host,
+ options.gss_client_identity, options.gss_kex_algorithms);
+ if (gss) {
+ debug("Offering GSSAPI proposal: %s", gss);
+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
+ "%s,%s", gss, orig);
+
if (gss) {
debug("Offering GSSAPI proposal: %s", gss);
xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
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>
+ /* If we've got GSSAPI algorithms, then we also support the
+ * 'null' hostkey, as a last resort */
+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
+ "%s,null", orig);
+ }
}
}
#endif
diff -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
#include <pwd.h>
#include <signal.h>
+#include <syslog.h>
#include <stdarg.h>
#include <time.h>
#include <stdio.h>
@@ -55,6 +56,7 @@
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
#include <stdlib.h>
@@ -77,6 +78,7 @@
#include <openssl/dh.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
#endif
@@ -1613,6 +1615,13 @@ main(int ac, char **av)
@@ -1931,6 +1931,13 @@ main(int ac, char **av)
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
do_log2_r(r, ll, "Unable to load host key \"%s\"",
options.host_key_files[i]);
@ -652,7 +382,7 @@ index ed7faf96d..de2baa5e4 100644
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
@@ -1836,6 +1845,10 @@ main(int ac, char **av)
@@ -2110,6 +2113,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);
@ -663,27 +393,45 @@ index ed7faf96d..de2baa5e4 100644
/*
* Chdir to the root directory so that the current disk can be
* unmounted if desired.
diff --git a/sshkey.c b/sshkey.c
index 148fee2b7..394d9b105 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -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
@@ -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"
@@ -58,6 +59,7 @@
@@ -57,6 +58,7 @@
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "match.h"
+#include "log.h"
#include "ssh-sk.h"
#include "ssh-pkcs11.h"
@@ -386,6 +388,18 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
#ifdef WITH_XMSS
@@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai
impl = keyimpls[i];
if (impl->name == NULL || impl->type == KEY_NULL)
continue;
@ -702,7 +450,7 @@ index 148fee2b7..394d9b105 100644
if (!include_sigonly && impl->sigonly)
continue;
if ((certs_only && !impl->cert) || (plain_only && impl->cert))
@@ -1418,6 +1432,20 @@ sshkey_read(struct sshkey *ret, char **cpp)
@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c
return SSH_ERR_EC_CURVE_MISMATCH;
}
@ -723,29 +471,208 @@ index 148fee2b7..394d9b105 100644
/* Fill in ret from parsed key */
sshkey_free_contents(ret);
*ret = *k;
@@ -2251,6 +2279,11 @@ sshkey_sign(struct sshkey *key,
@@ -2916,6 +2916,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)
@@ -2290,6 +2323,10 @@ sshkey_verify(const struct sshkey *key,
@@ -2973,6 +2978,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))) {
+ 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");
+ }
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 (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;
+ }
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
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

@ -1,25 +1,26 @@
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
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
@@ -51,6 +51,7 @@
#include <unistd.h>
#include <string.h>
@ -28,7 +29,7 @@ index 9d2f1f0ea..035032221 100644
extern ServerOptions options;
@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c
#endif
krb5_error_code problem;
krb5_ccache ccache = NULL;
@ -37,7 +38,7 @@ index 9d2f1f0ea..035032221 100644
char *client, *platform_client;
const char *errmsg;
@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c
goto out;
}
@ -48,7 +49,7 @@ index 9d2f1f0ea..035032221 100644
if (problem)
goto out;
@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c
goto out;
#endif
@ -69,7 +70,7 @@ index 9d2f1f0ea..035032221 100644
do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
#endif
@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c
void
krb5_cleanup_proc(Authctxt *authctxt)
{
@ -125,29 +126,12 @@ index 9d2f1f0ea..035032221 100644
if (authctxt->krb5_user) {
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
authctxt->krb5_user = NULL;
@@ -238,36 +281,189 @@ krb5_cleanup_proc(Authctxt *authctxt)
@@ -238,36 +281,188 @@ 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, ...) {
@ -165,8 +149,7 @@ index 9d2f1f0ea..035032221 100644
+ old = *dsc;
+
+ i = asprintf(dsc, "%s%s", *dsc, src);
+ if (i == -1) {
+ *dsc = old;
+ if (i == -1 || src == NULL) {
+ free(src);
+ return -1;
+ }
@ -213,9 +196,8 @@ index 9d2f1f0ea..035032221 100644
+ /* 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;
+
@ -250,13 +232,29 @@ index 9d2f1f0ea..035032221 100644
+ return ret;
+}
+
+krb5_error_code
krb5_error_code
-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
- int tmpfd, ret, oerrno;
- char ccname[40];
+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;
@ -271,7 +269,8 @@ index 9d2f1f0ea..035032221 100644
+ "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;
@ -338,32 +337,42 @@ index 9d2f1f0ea..035032221 100644
}
#endif /* !HEIMDAL */
#endif /* KRB5 */
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;
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)
}
@@ -245,7 +246,7 @@ FILE *auth_openprincipals(const char *, struct passwd *, int);
int sys_auth_passwd(struct ssh *, const char *);
/* 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;
}
#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 *);
/* This allows GSSAPI methods to do things to the child's environment based
@@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) {
char *envstr;
#endif
#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,
- 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
/* This writes out any forwarded credentials from the structure populated
* during userauth. Called after we have setuid to the user */
@ -372,7 +381,7 @@ index 14502c5a6..df55512d3 100644
ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
{
krb5_ccache ccache;
@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
OM_uint32 maj_status, min_status;
const char *new_ccname, *new_cctype;
const char *errmsg;
@ -390,7 +399,7 @@ index 14502c5a6..df55512d3 100644
#ifdef HEIMDAL
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
krb5_get_err_text(krb_context, problem));
# endif
krb5_free_error_message(krb_context, errmsg);
@ -409,7 +418,7 @@ index 14502c5a6..df55512d3 100644
}
#endif /* #ifdef HEIMDAL */
@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
errmsg = krb5_get_error_message(krb_context, problem);
logit("krb5_parse_name(): %.100s", errmsg);
krb5_free_error_message(krb_context, errmsg);
@ -418,7 +427,7 @@ index 14502c5a6..df55512d3 100644
}
if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) {
@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
krb5_free_error_message(krb_context, errmsg);
krb5_free_principal(krb_context, princ);
krb5_cc_destroy(krb_context, ccache);
@ -427,7 +436,7 @@ index 14502c5a6..df55512d3 100644
}
krb5_free_principal(krb_context, princ);
@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
client->creds, ccache))) {
logit("gss_krb5_copy_ccache() failed");
krb5_cc_destroy(krb_context, ccache);
@ -465,7 +474,7 @@ index 14502c5a6..df55512d3 100644
do_pam_putenv(client->store.envvar, client->store.envval);
#endif
@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
client->store.data = krb_context;
@ -474,44 +483,10 @@ index 14502c5a6..df55512d3 100644
}
int
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)
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
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
options->kerberos_get_afs_token = -1;
@ -519,7 +494,7 @@ index 3b93ca829..7bf1507df 100644
options->gss_authentication=-1;
options->gss_keyex = -1;
options->gss_cleanup_creds = -1;
@@ -376,6 +377,8 @@ fill_default_server_options(ServerOptions *options)
@@ -359,6 +360,8 @@ fill_default_server_options(ServerOption
options->kerberos_ticket_cleanup = 1;
if (options->kerberos_get_afs_token == -1)
options->kerberos_get_afs_token = 0;
@ -528,16 +503,16 @@ index 3b93ca829..7bf1507df 100644
if (options->gss_authentication == -1)
options->gss_authentication = 0;
if (options->gss_keyex == -1)
@@ -558,7 +561,7 @@ typedef enum {
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
@@ -506,7 +509,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,
@@ -649,11 +652,13 @@ static struct {
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -593,11 +597,13 @@ static struct {
#else
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
@ -551,7 +526,7 @@ index 3b93ca829..7bf1507df 100644
#endif
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
@@ -1662,6 +1667,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
@@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO
intptr = &options->kerberos_get_afs_token;
goto parse_flag;
@ -562,7 +537,7 @@ index 3b93ca829..7bf1507df 100644
case sGssAuthentication:
intptr = &options->gss_authentication;
goto parse_flag;
@@ -3295,6 +3304,7 @@ dump_config(ServerOptions *o)
@@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o)
# ifdef USE_AFS
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
# endif
@ -570,11 +545,10 @@ index 3b93ca829..7bf1507df 100644
#endif
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
diff --git a/servconf.h b/servconf.h
index c3f501400..a4a38d6d7 100644
--- a/servconf.h
+++ b/servconf.h
@@ -149,6 +149,8 @@ typedef struct {
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 {
* file on logout. */
int kerberos_get_afs_token; /* If true, try to get AFS token if
* authenticated with Kerberos. */
@ -583,11 +557,10 @@ index c3f501400..a4a38d6d7 100644
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 --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)
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
/* Allow any GSSAPI methods that we've used to alter
* the child's environment as they see fit
*/
@ -597,7 +570,7 @@ index 3eae5bdf3..b8a2dae92 100644
#endif
/* Set basic environment. */
@@ -1063,7 +1064,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
@@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s
}
#endif
#ifdef KRB5
@ -606,33 +579,10 @@ index 3eae5bdf3..b8a2dae92 100644
child_set_env(&env, &envsize, "KRB5CCNAME",
s->authctxt->krb5_ccname);
#endif
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)
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)
#ifdef GSSAPI
if (options.gss_authentication) {
temporarily_use_uid(authctxt->pw);
@ -641,11 +591,10 @@ index 6e28020e9..028d5850e 100644
restore_uid();
}
#endif
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
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
file on logout.
The default is
.Cm yes .
@ -658,8 +607,26 @@ index b90068bf3..cae0fd0b4 100644
+can lead to overwriting previous tickets by subseqent connections to the same
+user account.
.It Cm KexAlgorithms
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
--
2.52.0
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);

View file

@ -1,25 +1,6 @@
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
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
@@ -43,3 +43,10 @@
# ProxyCommand ssh -q -W %h:%p gateway.example.com
# RekeyLimit 1G 1h
@ -31,12 +12,10 @@ index 238a0c5e3..d9324c957 100644
+# 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 --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 @@
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 @@
+# 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
@ -50,35 +29,12 @@ index 000000000..8b1b59021
+# 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 --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
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
SyslogFacility
Gives the facility code that is used when logging messages from
@ -91,11 +47,10 @@ index c63d729a9..8c5217c0b 100644
TCPKeepAlive
Specifies whether the system should send TCP keepalive messages
diff --git a/sshd_config.5 b/sshd_config.5
index 6ae606f1e..aa9f0af76 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1941,7 +1941,7 @@ By default no subsystems are defined.
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.
.It Cm SyslogFacility
Gives the facility code that is used when logging messages from
.Xr sshd 8 .
@ -104,15 +59,31 @@ index 6ae606f1e..aa9f0af76 100644
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
The default is AUTH.
.It Cm TCPKeepAlive
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 @@
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 @@
+SyslogFacility AUTHPRIV
+
+KbdInteractiveAuthentication no
+ChallengeResponseAuthentication no
+
+GSSAPIAuthentication yes
+GSSAPICleanupCredentials no
@ -121,18 +92,13 @@ index 000000000..993a28d52
+
+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 --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
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
@@ -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
@ -141,6 +107,3 @@ index 000000000..1d592d13f
+# 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,26 @@
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,83 +1,57 @@
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;
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;
+#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 --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)
@@ -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;
@@ -314,8 +314,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 ((r = kex_server_update_ext_info(ssh)) != 0)
fatal_fr(r, "kex_server_update_ext_info failed");
diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
--- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200
+++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200
@@ -281,6 +281,7 @@ input_gssapi_mic(int type, u_int32_t ple
Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
int r, authenticated = 0;
+ char *micuser;
struct sshbuf *b;
gss_buffer_desc mic, gssbuf;
u_char *p;
@@ -300,7 +301,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
const char *displayname;
@@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple
fatal_f("sshbuf_new failed");
mic.value = p;
mic.length = len;
@ -92,7 +66,7 @@ index 75eb4e3a3..f7898ab3e 100644
"gssapi-with-mic", ssh->kex->session_id);
if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
@@ -313,6 +320,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
@@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple
logit("GSSAPI MIC check failed");
sshbuf_free(b);
@ -100,12 +74,11 @@ index 75eb4e3a3..f7898ab3e 100644
+ free(micuser);
free(mic.value);
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)
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)
/* reconstruct packet */
if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
@ -122,11 +95,10 @@ index 9d8b860eb..976484fc5 100644
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
(r = sshbuf_put_cstring(b, method)) != 0 ||
(r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 15ad3000c..c326a69ba 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -204,9 +204,16 @@ userauth_pubkey(struct ssh *ssh, const char *method)
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)
goto done;
}
/* reconstruct packet */
@ -145,51 +117,47 @@ index 15ad3000c..c326a69ba 100644
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 --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;
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;
+#ifdef WITH_SELINUX
+ char *role = NULL;
+ char *role;
+#endif
int r, authenticated = 0;
double tstart = monotime_double();
@@ -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 *
/* 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 *
colon(char *cp)
{
int flag = 0;
@ -197,7 +165,7 @@ index ce77ec943..5bed34735 100644
if (*cp == ':') /* Leading colon is part of file name. */
return NULL;
@@ -837,6 +838,13 @@ colon(char *cp)
@@ -557,6 +558,13 @@ colon(char *cp)
return (cp);
if (*cp == '/')
return NULL;
@ -211,11 +179,10 @@ index ce77ec943..5bed34735 100644
}
return NULL;
}
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 *);
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
int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *);
int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *);
int mm_answer_authserv(struct ssh *, int, struct sshbuf *);
@ -225,7 +192,7 @@ index a9e854bec..85dc1b1b7 100644
int mm_answer_authpassword(struct ssh *, int, struct sshbuf *);
int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *);
int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *);
@@ -184,6 +187,9 @@ struct mon_table mon_dispatch_proto20[] = {
@@ -195,6 +198,9 @@ struct mon_table mon_dispatch_proto20[]
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
@ -235,7 +202,7 @@ index a9e854bec..85dc1b1b7 100644
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
#ifdef USE_PAM
@@ -919,6 +925,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
@@ -803,6 +809,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in
/* Allow service/style information on the auth context */
monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
@ -245,7 +212,7 @@ index a9e854bec..85dc1b1b7 100644
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
#ifdef USE_PAM
@@ -993,6 +1002,26 @@ key_base_type_match(const char *method, const struct sshkey *key,
@@ -877,6 +886,26 @@ key_base_type_match(const char *method,
return found;
}
@ -272,16 +239,16 @@ index a9e854bec..85dc1b1b7 100644
int
mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
{
@@ -1364,7 +1393,7 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen)
@@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh,
struct sshbuf *b;
struct sshkey *hostkey = NULL;
struct sshkey *hostkey = NULL;
const u_char *p;
- char *userstyle, *cp;
+ char *userstyle, *s, *cp;
size_t len;
u_char type;
int hostbound = 0, r, fail = 0;
@@ -1395,6 +1424,8 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen)
@@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh,
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
fatal_fr(r, "parse userstyle");
@ -290,7 +257,7 @@ index a9e854bec..85dc1b1b7 100644
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",
authctxt->style ? authctxt->style : "");
@@ -1445,7 +1476,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
@@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char
{
struct sshbuf *b;
const u_char *p;
@ -299,7 +266,7 @@ index a9e854bec..85dc1b1b7 100644
size_t len;
int r, fail = 0;
u_char type;
@@ -1466,6 +1497,8 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
@@ -1338,6 +1370,8 @@ monitor_valid_hostbasedblob(const u_char
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
fatal_fr(r, "parse userstyle");
@ -308,13 +275,12 @@ index a9e854bec..85dc1b1b7 100644
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",
authctxt->style ? authctxt->style : "");
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 {
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,
MONITOR_REQ_TERM = 50,
MONITOR_REQ_STATE = 51, MONITOR_ANS_STATE = 52,
+#ifdef WITH_SELINUX
+ MONITOR_REQ_AUTHROLE = 80,
@ -323,11 +289,10 @@ index 3f8a9bea3..9dcd9c293 100644
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 --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)
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 *
sshbuf_free(m);
}
@ -355,11 +320,10 @@ index 33494b73f..347eb6870 100644
/* Do the password authentication */
int
mm_auth_password(struct ssh *ssh, char *password)
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 *,
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);
const u_char *, size_t, const char *, const char *,
const char *, u_int compat);
void mm_inform_authserv(char *, char *);
@ -369,11 +333,10 @@ index c87295388..9b42ddbcb 100644
struct passwd *mm_getpwnamallow(struct ssh *, const char *);
char *mm_auth2_read_banner(void);
int mm_auth_password(struct ssh *, char *);
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index 53c87db6d..39531ae77 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -102,7 +102,8 @@ PORTS= port-aix.o \
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 \
port-prngd.o \
port-solaris.o \
port-net.o \
@ -383,12 +346,79 @@ index 53c87db6d..39531ae77 100644
.c.o:
$(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $<
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
new file mode 100644
index 000000000..b9fbe38b7
--- /dev/null
+++ b/openbsd-compat/port-linux-sshd.c
@@ -0,0 +1,420 @@
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 @@
+/*
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
+ * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com>
@ -442,6 +472,7 @@ index 000000000..b9fbe38b7
+extern ServerOptions options;
+extern Authctxt *the_authctxt;
+extern int inetd_flag;
+extern int rexeced_flag;
+
+/* Send audit message */
+static int
@ -647,7 +678,7 @@ index 000000000..b9fbe38b7
+
+ if (r == 0) {
+ /* If launched from xinetd, we must use current level */
+ if (inetd_flag) {
+ if (inetd_flag && !rexeced_flag) {
+ security_context_t sshdsc=NULL;
+
+ if (getcon_raw(&sshdsc) < 0)
@ -721,7 +752,7 @@ index 000000000..b9fbe38b7
+
+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
+
+ if (inetd_flag) {
+ if (inetd_flag && !rexeced_flag) {
+ use_current = "1";
+ } else {
+ use_current = "";
@ -809,82 +840,10 @@ index 000000000..b9fbe38b7
+#endif
+#endif
+
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)
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
}
#endif /* HAVE_SETPCRED */
#ifdef WITH_SELINUX
@ -893,11 +852,10 @@ index fd1a7a7c2..bcf1b0491 100644
#endif
}
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)
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)
restore_uid();
}
#endif
@ -906,7 +864,4 @@ index 8979f743b..cb4b0523d 100644
+#endif
#ifdef USE_PAM
if (options.use_pam) {
do_pam_setcred();
--
2.52.0
do_pam_setcred(1);

View file

@ -1,17 +1,8 @@
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 e1992622f..621131ffc 100644
index 60682c68..9344806e 100644
--- a/scp.c
+++ b/scp.c
@@ -1169,7 +1169,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
@@ -714,7 +714,9 @@ toremote(int argc, char **argv)
addargs(&alist, "%s", host);
addargs(&alist, "%s", cmd);
addargs(&alist, "%s", src);
@ -22,6 +13,4 @@ index e1992622f..621131ffc 100644
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
if (do_local_cmd(&alist) != 0)
--
2.52.0

View file

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

View file

@ -0,0 +1,12 @@
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

@ -0,0 +1,137 @@
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,17 +1,7 @@
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)
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)
goto auth_fail;
if (!do_pam_account()) {
@ -24,9 +14,9 @@ index 70bcae83a..70b2b8580 100644
goto auth_fail;
}
if (sshpam_authctxt->force_pwchange) {
@@ -608,8 +612,10 @@ sshpam_thread(void *ctxtp)
@@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp)
pam_strerror(sshpam_handle, sshpam_err))) != 0)
fatal_fr(r, "buffer error");
fatal("%s: buffer error: %s", __func__, ssh_err(r));
/* XXX - can't do much about an error here */
- if (sshpam_err == PAM_ACCT_EXPIRED)
- ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer);
@ -37,20 +27,18 @@ index 70bcae83a..70b2b8580 100644
else if (sshpam_maxtries_reached)
ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer);
else
@@ -913,9 +919,11 @@ sshpam_query(void *ctx, char **name, char **info,
@@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha
plen++;
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,17 +1,8 @@
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 4c96e8827..4af5209db 100644
index dca158de..afdcb1d2 100644
--- a/regress/misc/sk-dummy/sk-dummy.c
+++ b/regress/misc/sk-dummy/sk-dummy.c
@@ -80,7 +80,7 @@ skdebug(const char *func, const char *fmt, ...)
@@ -71,7 +71,7 @@ skdebug(const char *func, const char *fmt, ...)
#endif
}
@ -20,7 +11,7 @@ index 4c96e8827..4af5209db 100644
sk_api_version(void)
{
return SSH_SK_VERSION_MAJOR;
@@ -229,7 +229,7 @@ check_options(struct sk_option **options)
@@ -220,7 +220,7 @@ check_options(struct sk_option **options)
return 0;
}
@ -29,7 +20,7 @@ index 4c96e8827..4af5209db 100644
sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
const char *application, uint8_t flags, const char *pin,
struct sk_option **options, struct sk_enroll_response **enroll_response)
@@ -477,7 +477,7 @@ sig_ed25519(const uint8_t *message, size_t message_len,
@@ -467,7 +467,7 @@ sig_ed25519(const uint8_t *message, size_t message_len,
return ret;
}
@ -38,7 +29,7 @@ index 4c96e8827..4af5209db 100644
sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
const char *application, const uint8_t *key_handle, size_t key_handle_len,
uint8_t flags, const char *pin, struct sk_option **options,
@@ -534,7 +534,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
@@ -518,7 +518,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
return ret;
}
@ -47,6 +38,3 @@ index 4c96e8827..4af5209db 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,17 +1,12 @@
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
@@ -5123,6 +5123,16 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
@@ -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) {
debug2_f("bind port %d: %.100s", port,
strerror(errno));
close(sock);
@ -28,6 +23,8 @@ index 5ce6bd400..26ed9945f 100644
for (n = 0; n < num_socks; n++)
close(socks[n]);
num_socks = 0;
--
2.52.0
break;
}
socks[num_socks++] = sock;
if (num_socks == NUM_SOCKS)
break;

11
openssh-8.7p1-ibmca.patch Normal file
View file

@ -0,0 +1,11 @@
--- 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,18 +1,7 @@
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 {
--- a/readconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/readconf.c (date 1703169891147)
@@ -326,6 +326,7 @@
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
{ "requiredrsasize", oRequiredRSASize },
@ -21,17 +10,13 @@ index eab734aaf..3f67f4de4 100644
{ "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 {
--- a/servconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/servconf.c (date 1703169891148)
@@ -691,6 +691,7 @@
{ "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
{ NULL, sBadOption, 0 }

View file

@ -1,17 +1,6 @@
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
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
@@ -17,8 +17,21 @@ trace "make CA key"
${SSHKEYGEN} -qt ed25519 -f $OBJ/agent-ca -N '' || fatal "ssh-keygen CA"
@ -35,7 +24,7 @@ index 28dcfe170..b9e716dcd 100644
${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 +45,16 @@ rm $OBJ/agent-ca # Don't need CA private any more either
@@ -32,12 +48,16 @@ rm $OBJ/agent-ca # Don't need CA private
unset SSH_AUTH_SOCK
@ -55,10 +44,10 @@ index 28dcfe170..b9e716dcd 100644
( 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 +67,16 @@ for k in $SSH_KEYTYPES ; do
@@ -50,15 +70,16 @@ for k in $SSH_KEYTYPES ; do
done
SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com' | maybe_filter_sk`
SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com'`
+SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
# Prepare sshd_proxy for certificates.
@ -74,7 +63,7 @@ index 28dcfe170..b9e716dcd 100644
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 +88,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >> $OBJ/sshd_proxy
@@ -70,7 +93,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >>
( printf '@cert-authority localhost-with-alias ' ;
cat $OBJ/agent-ca.pub) > $OBJ/known_hosts
@ -83,20 +72,19 @@ index 28dcfe170..b9e716dcd 100644
verbose "cert type $k"
opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"
SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
diff --git a/sshconnect2.c b/sshconnect2.c
index fffa66c8d..f43c81ad9 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
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
const struct ssh_conn_info *cinfo)
{
char *myproposal[PROPOSAL_MAX];
- char *all_key, *hkalgs = NULL;
+ char *all_key, *hkalgs = NULL, *filtered_algs = NULL;
- char *s, *all_key, *hkalgs = NULL;
+ char *s, *all_key, *hkalgs = NULL, *filtered_algs = NULL;
int r, use_known_hosts_order = 0;
#if defined(GSSAPI) && defined(WITH_OPENSSL)
@@ -257,10 +257,22 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
@@ -260,9 +260,21 @@ ssh_kex2(struct ssh *ssh, char *host, st
if (use_known_hosts_order)
hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);
@ -112,15 +100,14 @@ index fffa66c8d..f43c81ad9 100644
+ options.hostkeyalgorithms, options.pubkey_accepted_algos);
+ }
+
kex_proposal_populate_entries(ssh, myproposal,
options.kex_algorithms, options.ciphers, options.macs,
compression_alg_list(options.compression),
kex_proposal_populate_entries(ssh, myproposal, s, 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) {
@@ -304,6 +316,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
@@ -303,6 +315,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
#endif
free(hkalgs);
@ -128,6 +115,3 @@ index fffa66c8d..f43c81ad9 100644
/* start key exchange */
if ((r = kex_setup(ssh, myproposal)) != 0)
--
2.52.0

View file

@ -0,0 +1,402 @@
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,21 +1,8 @@
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)
--- a/scp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/scp.c (date 1703111453316)
@@ -1372,7 +1372,7 @@
if (src_is_dir && iamrecursive) {
if (sftp_upload_dir(conn, src, abs_dst, pflag,
- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
@ -24,11 +11,10 @@ index 3c213f83d..78c79a755 100644
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,
--- a/sftp-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/sftp-client.c (date 1703169614263)
@@ -1003,7 +1003,7 @@
/* Implements both the realpath and expand-path operations */
static char *
-sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
@ -36,7 +22,7 @@ index 840170ab6..9bf9cc047 100644
{
struct sshbuf *msg;
u_int expected_id, count, id;
@@ -1047,11 +1047,43 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
@@ -1049,11 +1049,43 @@
if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
fatal_fr(r, "parse status");
@ -85,9 +71,9 @@ index 840170ab6..9bf9cc047 100644
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
@@ -1076,9 +1108,9 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
@@ -1078,9 +1110,9 @@
}
char *
-sftp_realpath(struct sftp_conn *conn, const char *path)
+sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir)
@ -95,9 +81,9 @@ index 840170ab6..9bf9cc047 100644
- 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)
@@ -1094,9 +1126,9 @@
{
if (!sftp_can_expand_path(conn)) {
debug3_f("no server support, fallback to realpath");
@ -107,18 +93,18 @@ index 840170ab6..9bf9cc047 100644
- 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,
@@ -2016,7 +2048,7 @@
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,
@@ -2365,12 +2397,12 @@
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,
@ -127,48 +113,47 @@ index 840170ab6..9bf9cc047 100644
{
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,
@@ -2825,7 +2857,7 @@
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 *);
--- a/sftp-client.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/sftp-client.h (date 1703111691284)
@@ -111,7 +111,7 @@
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 *,
@@ -163,7 +163,7 @@
* 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,
--- a/sftp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/sftp.c (date 1703168795365)
@@ -807,7 +807,7 @@
(rflag || global_rflag)) {
if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
@ -177,7 +162,7 @@ index 3b505eea2..2a99698a8 100644
err = -1;
} else {
if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
@@ -1636,7 +1636,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
@@ -1642,7 +1642,7 @@
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
path1 = sftp_make_absolute(path1, *pwd);
@ -186,15 +171,12 @@ index 3b505eea2..2a99698a8 100644
err = 1;
break;
}
@@ -2241,7 +2241,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
@@ -2247,7 +2247,7 @@
}
#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

@ -1,31 +1,18 @@
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"
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"
#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 --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.
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
By default a 32KB buffer is used.
.El
.El
@ -39,11 +26,10 @@ index 7bce0fe6f..2bb838c7d 100644
.Sh EXIT STATUS
.Ex -std scp
.Sh SEE ALSO
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)
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)
if (iamremote)
mode = MODE_SCP;
@ -58,6 +44,3 @@ index 621131ffc..3c213f83d 100644
if ((pwd = getpwuid(userid = getuid())) == NULL)
fatal("unknown user %u", (u_int) userid);
--
2.52.0

View file

@ -0,0 +1,53 @@
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

@ -0,0 +1,119 @@
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

@ -0,0 +1,292 @@
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

@ -0,0 +1,207 @@
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

@ -0,0 +1,40 @@
--- 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

@ -0,0 +1,130 @@
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,7 +2,9 @@
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 4555')
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')
# The -cavs subpackage is internal without documentation
# The -askpass is not intended to be used directly so it is missing documentation

View file

@ -25,6 +25,13 @@
# 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}
@ -38,17 +45,24 @@
# rpm -ba|--rebuild --define "static_openssl 1"
%{?static_openssl:%global static_libcrypto 1}
%global openssh_ver 10.2p1
# Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1
%global openssh_ver 9.6p1
%global openssh_rel 1
%global pam_ssh_agent_ver 0.10.4
%global pam_ssh_agent_rel 9
Summary: An open source implementation of SSH protocol version 2
Name: openssh
Version: %{openssh_ver}
Release: 1%{?dist}
Release: %{openssh_rel}%{?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
@ -62,123 +76,161 @@ Source17: ssh-agent.socket
Source19: openssh-server-systemd-sysusers.conf
Source20: ssh-host-keys-migration.sh
Source21: ssh-host-keys-migration.service
Source22: parallel_test.sh
Source23: parallel_test.Makefile
#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
#https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
Patch0001: 0001-openssh-7.8p1-role-mls.patch
Patch0002: 0002-openssh-6.6p1-keycat.patch
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
#https://bugzilla.mindrot.org/show_bug.cgi?id=1644
Patch0003: 0003-openssh-6.6p1-allow-ip-opts.patch
Patch601: openssh-6.6p1-allow-ip-opts.patch
#(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925
Patch0004: 0004-openssh-5.9p1-ipv6man.patch
Patch0005: 0005-openssh-5.8p2-sigpipe.patch
Patch0006: 0006-openssh-7.2p2-x11.patch
Patch0007: 0007-openssh-5.1p1-askpass-progress.patch
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
#https://bugzilla.redhat.com/show_bug.cgi?id=198332
Patch0008: 0008-openssh-4.3p2-askpass-grab-info.patch
Patch703: openssh-4.3p2-askpass-grab-info.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
Patch0009: 0009-openssh-8.7p1-redhat.patch
Patch707: openssh-7.7p1-redhat.patch
# warn users for unsupported UsePAM=no (#757545)
Patch0010: 0010-openssh-7.8p1-UsePAM-warning.patch
Patch711: openssh-7.8p1-UsePAM-warning.patch
# GSSAPI Key Exchange (RFC 4462 + RFC 8732)
Patch0011: 0011-openssh-9.6p1-gssapi-keyex.patch
# from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master
# and
# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures
# upstream MR:
# https://github.com/openssh-gsskex/openssh-gsskex/pull/21
Patch800: openssh-8.0p1-gssapi-keyex.patch
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
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
Patch0013: 0013-openssh-7.7p1-gssapi-new-unique.patch
# Respect k5login_directory option in krk5.conf (#1328243)
Patch0014: 0014-openssh-7.2p2-k5login_directory.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
Patch0015: 0015-openssh-6.6p1-kuserok.patch
# Use tty allocation for a remote scp (#985650)
Patch0016: 0016-openssh-6.4p1-fromto-remote.patch
# log via monitor in chroots without /dev/log (#2681)
Patch0017: 0017-openssh-6.6.1p1-log-in-chroot.patch
# scp file into non-existing directory (#1142223)
Patch0018: 0018-openssh-6.6.1p1-scp-non-existing-directory.patch
Patch801: openssh-6.6p1-force_krb.patch
# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843)
# CVE-2014-9278
Patch0019: 0019-openssh-6.6p1-GSSAPIEnablek5users.patch
Patch802: openssh-6.6p1-GSSAPIEnablek5users.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
# Respect k5login_directory option in krk5.conf (#1328243)
Patch805: openssh-7.2p2-k5login_directory.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
Patch901: 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
# log via monitor in chroots without /dev/log (#2681)
Patch918: 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
# apply upstream patch and make sshd -T more consistent (#1187521)
Patch0020: 0020-openssh-6.8p1-sshdT-output.patch
Patch922: openssh-6.8p1-sshdT-output.patch
# Add sftp option to force mode of created files (#1191055)
Patch0021: 0021-openssh-6.7p1-sftp-force-permission.patch
Patch926: openssh-6.7p1-sftp-force-permission.patch
# make s390 use /dev/ crypto devices -- ignore closefrom
Patch0022: 0022-openssh-7.2p2-s390-closefrom.patch
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
# Pass inetd flags for SELinux down to openbsd compat level
Patch0023: 0023-openssh-7.6p1-cleanup-selinux.patch
Patch949: openssh-7.6p1-cleanup-selinux.patch
# Sandbox adjustments for s390 and audit
Patch0024: 0024-openssh-7.5p1-sandbox.patch
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
# Unbreak scp between two IPv6 hosts (#1620333)
Patch0025: 0025-openssh-7.8p1-scp-ipv6.patch
Patch953: openssh-7.8p1-scp-ipv6.patch
# Mention crypto-policies in manual pages (#1668325)
# clarify rhbz#2068423 on the man page of ssh_config
Patch0026: 0026-openssh-8.0p1-crypto-policies.patch
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
# Use OpenSSL KDF (#1631761)
Patch0027: 0027-openssh-8.0p1-openssl-kdf.patch
Patch964: openssh-8.0p1-openssl-kdf.patch
# sk-dummy.so built with -fvisibility=hidden does not work
Patch0028: 0028-openssh-8.2p1-visibility.patch
Patch965: openssh-8.2p1-visibility.patch
# Do not break X11 without IPv6
Patch0029: 0029-openssh-8.2p1-x11-without-ipv6.patch
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
# sshd provides PAM an incorrect error code (#1879503)
Patch0030: 0030-openssh-8.0p1-preserve-pam-errors.patch
Patch975: openssh-8.0p1-preserve-pam-errors.patch
# Implement kill switch for SCP protocol
Patch0031: 0031-openssh-8.7p1-scp-kill-switch.patch
Patch977: openssh-8.7p1-scp-kill-switch.patch
# Workaround for lack of sftp_realpath in older versions of RHEL
# https://bugzilla.redhat.com/show_bug.cgi?id=2038854
# https://github.com/openssh/openssh-portable/pull/299
# downstream only
Patch0032: 0032-openssh-8.7p1-recursive-scp.patch
# Downstream alias for MinRSABits
Patch0033: 0033-openssh-8.7p1-minrsabits.patch
Patch981: openssh-8.7p1-recursive-scp.patch
# https://github.com/djmdjm/openssh-wip/pull/13
Patch982: openssh-8.7p1-minrsabits.patch
# downstream only, IBMCA tentative fix
# From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14
Patch0034: 0034-openssh-8.7p1-ibmca.patch
#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
Patch984: openssh-8.7p1-ibmca.patch
# Add missing options from ssh_config into ssh manpage
# upstream bug:
# https://bugzilla.mindrot.org/show_bug.cgi?id=3455
Patch0039: 0039-openssh-8.7p1-ssh-manpage.patch
Patch1002: openssh-8.7p1-ssh-manpage.patch
# Don't propose disallowed algorithms during hostkey negotiation
# upstream MR:
# https://github.com/openssh/openssh-portable/pull/323
Patch0040: 0040-openssh-8.7p1-negotiate-supported-algs.patch
Patch0041: 0041-openssh-9.0p1-evp-fips-kex.patch
Patch0042: 0042-openssh-8.7p1-nohostsha1proof.patch
Patch0043: 0043-openssh-9.9p1-separate-keysign.patch
Patch0044: 0044-openssh-9.9p1-openssl-mlkem.patch
# 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
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
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
@ -193,14 +245,13 @@ 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 >= 3.5.0
BuildRequires: openssl-devel >= 0.9.8j
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
@ -229,10 +280,6 @@ 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}
@ -253,6 +300,12 @@ 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}
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
@ -272,11 +325,6 @@ 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
@ -295,14 +343,106 @@ 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}
%autosetup -T -b 0 -p1
%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 100 -p1 -b .coverity
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"
@ -336,14 +476,16 @@ fi
--sysconfdir=%{_sysconfdir}/ssh \
--libexecdir=%{_libexecdir}/openssh \
--datadir=%{_datadir}/openssh \
--with-default-path=/usr/local/bin:/usr/bin \
--with-superuser-path=/usr/local/bin:/usr/bin \
--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-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 \
@ -391,9 +533,22 @@ 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
OPENSSL_CONF=/dev/null %{SOURCE22} %{SOURCE23} # ./parallel_tests.sh parallel_tests.Makefile
#make tests
#to run tests use "--with check"
%if %{?_with_check:1}%{!?_with_check:0}
make tests
%endif
%install
rm -rf $RPM_BUILD_ROOT
@ -451,6 +606,12 @@ 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
@ -501,6 +662,8 @@ 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
@ -528,15 +691,9 @@ 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*
@ -568,183 +725,22 @@ 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
%{_libexecdir}/openssh/ssh-askpass
%attr(0755,root,root) %{_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

@ -0,0 +1,249 @@
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" ]

36
pam_ssh_agent-rmheaders Normal file
View file

@ -0,0 +1,36 @@
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

@ -0,0 +1,992 @@
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

@ -0,0 +1,20 @@
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

@ -0,0 +1,37 @@
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

@ -0,0 +1,19 @@
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

@ -0,0 +1,21 @@
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

@ -0,0 +1,96 @@
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

@ -0,0 +1,198 @@
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

View file

@ -1,14 +0,0 @@
# 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 \

View file

@ -1,91 +0,0 @@
#!/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

View file

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

View file

@ -1,3 +1,4 @@
SHA512 (openssh-10.2p1.tar.gz) = 66f3dd646179e71aaf41c33b6f14a207dc873d71d24f11c130a89dee317ee45398b818e5b94887b5913240964a38630d7bca3e481e0f1eff2e41d9e1cfdbdfc5
SHA512 (openssh-10.2p1.tar.gz.asc) = f1f71700b1b0b2117aed505488b98b7ebb51ce26e53184b08df0b07aa2c5a1e54dc4d3cbcbe871b5ad849a2a0e22b02af318ff22a68c980ab53b04be03c9bf3c
SHA512 (openssh-9.6p1.tar.gz) = 0ebf81e39914c3a90d7777a001ec7376a94b37e6024baf3e972c58f0982b7ddef942315f5e01d56c00ff95603b4a20ee561ab918ecc55511df007ac138160509
SHA512 (openssh-9.6p1.tar.gz.asc) = aec5a5bd6ce480a8e5b5879dc55f8186aec90fe61f085aa92ad7d07f324574aa781be09c83b7443a32848d091fd44fb12c1842d49cee77afc351e550ffcc096d
SHA512 (pam_ssh_agent_auth-0.10.4.tar.gz) = caccf72174d15e43f4c86a459ac6448682e62116557cf1e1e828955f3d1731595b238df42adec57860e7f341e92daf5d8285020bcb5018f3b8a5145aa32ee1c2
SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21

View file

@ -8,7 +8,9 @@ Documentation=man:ssh-agent(1) man:ssh-add(1) man:ssh(1)
Requires=ssh-agent.socket
[Service]
ExecStart=/usr/bin/ssh-agent -D
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
PassEnvironment=SSH_AGENT_PID
SuccessExitStatus=2
Type=simple

View file

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

View file

@ -4,9 +4,6 @@ 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,9 +9,6 @@ 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,7 +5,3 @@
# 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,10 +8,6 @@ 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 -o "AuthorizedKeysFile ${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys"
ExecStart=-/usr/sbin/sshd -i $OPTIONS
StandardInput=socket
ImportCredential=ssh.ephemeral-authorized_keys-all

View file

@ -1,11 +0,0 @@
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

View file

@ -28,7 +28,7 @@ export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile pam_save_ssh_var.c
FILES=$(METADATA) runtest.sh Makefile PURPOSE pam_save_ssh_var.c
.PHONY: all install download clean

View file

@ -0,0 +1,7 @@
PURPOSE of /CoreOS/openssh/Sanity/pam_ssh_agent_auth
Description: This is basic sanity test for pam_ssh_agent_auth
Author: Jakub Jelen <jjelen@redhat.com>
Created as a response to rhbz#1251777 and previous one rhbz#1225106.
The code of pam module is outdated and compiled with current openssh
version which went through quite enough refactoring.

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