Compare commits

..

7 commits

Author SHA1 Message Date
Mattias Ellert
76f997a6d6 Based on openssh-8.4p1-8.fc33 2021-10-24 06:24:47 +02:00
Mattias Ellert
42f77e22d6 Based on openssh-8.4p1-7.fc33 2021-06-21 20:09:32 +02:00
Mattias Ellert
651d6b5d57 Based on openssh-8.4p1-5.fc33 2021-05-25 09:56:34 +02:00
Mattias Ellert
6c50475edd Disable MTAES 2021-03-30 10:02:52 +02:00
Mattias Ellert
85f5ecc116 Fix issue with read-only ssh buffer during gssapi key exchange
Clean up HPN patch
2021-03-16 06:59:04 +01:00
Frank Scheiner
7b2f5e53c4 Add HPN patch 2021-03-12 13:09:16 +01:00
Mattias Ellert
2bbc3688bd Based on openssh-8.4p1-5.fc33 2021-02-05 15:12:25 +01:00
96 changed files with 10788 additions and 25312 deletions

View file

@ -1,144 +0,0 @@
From 99d8e250514023d3b88a1c9eb724c4898aba9827 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/50] openssh-6.6p1-privsep-selinux
---
openbsd-compat/port-linux-sshd.c | 22 ++++++++++++++++++++++
openbsd-compat/port-linux.h | 1 +
session.c | 16 +++++++++-------
sshd-auth.c | 4 ++++
sshd-session.c | 2 +-
5 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
index b9fbe38b..dfafc622 100644
--- a/openbsd-compat/port-linux-sshd.c
+++ b/openbsd-compat/port-linux-sshd.c
@@ -415,6 +415,28 @@ sshd_selinux_setup_exec_context(char *pwname)
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 --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 055c825e..498d242a 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -23,6 +23,7 @@ void ssh_selinux_setup_pty(char *, const char *);
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 --git a/session.c b/session.c
index 6444c77f..e4657cef 100644
--- a/session.c
+++ b/session.c
@@ -1350,7 +1350,7 @@ do_setusercontext(struct passwd *pw)
platform_setusercontext(pw);
- if (platform_privileged_uidswap()) {
+ if (platform_privileged_uidswap() && !is_child) {
#ifdef HAVE_LOGIN_CAP
if (setusercontext(lc, pw, pw->pw_uid,
(LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
@@ -1382,6 +1382,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);
@@ -1417,6 +1420,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");
@@ -1434,9 +1442,6 @@ do_pwchange(Session *s)
if (s->ttyfd != -1) {
fprintf(stderr,
"You must change your password now and log in again!\n");
-#ifdef WITH_SELINUX
- setexeccon(NULL);
-#endif
#ifdef PASSWD_NEEDS_USERNAME
execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
(char *)NULL);
@@ -1649,9 +1654,6 @@ do_child(struct ssh *ssh, 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 --git a/sshd-auth.c b/sshd-auth.c
index 30eecd8a..f957dc22 100644
--- a/sshd-auth.c
+++ b/sshd-auth.c
@@ -187,6 +187,10 @@ privsep_child_demote(void)
if ((box = ssh_sandbox_init(pmonitor)) == NULL)
fatal_f("ssh_sandbox_init failed");
#endif
+#ifdef WITH_SELINUX
+ ssh_selinux_change_context("sshd_net_t");
+#endif
+
/* Demote the child */
if (privsep_chroot) {
/* Change our root directory */
diff --git a/sshd-session.c b/sshd-session.c
index 74d2cbc7..4a148db4 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -432,7 +432,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
* fd passing, as AFAIK PTY allocation on this platform doesn't require
* special privileges to begin with.
*/
-#if defined(DISABLE_FD_PASSING) && !defined(HAVE_CYGWIN)
+#if defined(DISABLE_FD_PASSING) && !defined(HAVE_CYGWIN) && !defined(WITH_SELINUX)
skip_privdrop = 1;
#endif
--
2.49.0

View file

@ -1,26 +0,0 @@
From 80359feb76fd8061b5ce18f73451d7b9db0c2477 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/50] openssh-5.8p2-sigpipe
---
ssh-keyscan.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index 3436c0b5..9f76ad22 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -798,6 +798,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.49.0

View file

@ -1,31 +0,0 @@
From 710ce53fdf1d32a0629fce2e42fb49d407e2b06c 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/50] 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 cb7152dc..bbe93d83 100644
--- a/contrib/gnome-ssh-askpass2.c
+++ b/contrib/gnome-ssh-askpass2.c
@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_window, const char *what)
err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- "Could not grab %s. A malicious client may be eavesdropping "
- "on your session.", what);
+ "SSH password dialog could not grab the %s input.\n"
+ "This might be caused by application such as screensaver, "
+ "however it could also mean that someone may be eavesdropping "
+ "on your session.\n"
+ "Either close the application which grabs the %s or "
+ "log out and log in again to prevent this from happening.", what, what);
gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
gtk_dialog_run(GTK_DIALOG(err));
--
2.49.0

View file

@ -1,41 +0,0 @@
From 56b8d082bc9e25a77b5227d576f27088446c6fb9 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 11/50] 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 a365f26f..a70b36c9 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1127,6 +1127,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 608203e4..48af6321 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.49.0

View file

@ -1,28 +0,0 @@
From 20aabb2c445e29d211266ce7434bb0273edf88b9 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/50] openssh-6.4p1-fromto-remote
---
scp.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/scp.c b/scp.c
index 57c242ff..716ae386 100644
--- a/scp.c
+++ b/scp.c
@@ -1162,7 +1162,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.49.0

View file

@ -1,255 +0,0 @@
From 825018f5f2d892655f3d63167a0d1f3391cec678 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/50] 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 6617f267..9782cfb0 100644
--- a/log.c
+++ b/log.c
@@ -196,6 +196,11 @@ void
log_init(const char *av0, LogLevel level, SyslogFacility facility,
int on_stderr)
{
+ log_init_handler(av0, level, facility, on_stderr, 1);
+}
+
+void
+log_init_handler(const char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) {
#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,
exit(1);
}
- log_handler = NULL;
- log_handler_ctx = NULL;
+ if (reset_handler) {
+ log_handler = NULL;
+ log_handler_ctx = NULL;
+ }
log_on_stderr = on_stderr;
if (on_stderr)
diff --git a/log.h b/log.h
index 8e8dfc23..70048a8a 100644
--- a/log.h
+++ b/log.h
@@ -52,6 +52,7 @@ typedef enum {
typedef void (log_handler_fn)(LogLevel, int, const char *, void *);
void log_init(const char *, LogLevel, SyslogFacility, int);
+void log_init_handler(const char *, LogLevel, SyslogFacility, int, int);
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 2ef16cc8..43c10a4e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2001,9 +2001,22 @@ monitor_init(void)
}
void
-monitor_reinit(struct monitor *mon)
+monitor_reinit(struct monitor *mon, const char *chroot_dir)
{
- monitor_openfds(mon, 0);
+ struct stat dev_log_stat;
+ char *dev_log_path;
+ int do_logfds = 0;
+
+ if (chroot_dir != NULL) {
+ xasprintf(&dev_log_path, "%s/dev/log", chroot_dir);
+
+ if (stat(dev_log_path, &dev_log_stat) != 0) {
+ debug_f("/dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", chroot_dir);
+ do_logfds = 1;
+ }
+ free(dev_log_path);
+ }
+ monitor_openfds(mon, do_logfds);
}
#ifdef GSSAPI
diff --git a/monitor.h b/monitor.h
index dbc7e003..d4d631dd 100644
--- a/monitor.h
+++ b/monitor.h
@@ -85,7 +85,7 @@ struct monitor {
};
struct monitor *monitor_init(void);
-void monitor_reinit(struct monitor *);
+void monitor_reinit(struct monitor *, const char *);
struct Authctxt;
void monitor_child_preauth(struct ssh *, struct monitor *);
diff --git a/session.c b/session.c
index 2620dd11..54da09d5 100644
--- a/session.c
+++ b/session.c
@@ -169,6 +169,7 @@ login_cap_t *lc;
static int is_child = 0;
static int in_chroot = 0;
+static int have_dev_log = 1;
/* File containing userauth info, if ExposeAuthInfo set */
static char *auth_info_file = NULL;
@@ -670,6 +671,7 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
int ret;
const char *forced = NULL, *tty = NULL;
char session_type[1024];
+ struct stat dev_log_stat;
if (options.adm_forced_command) {
original_command = command;
@@ -729,6 +731,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
tty += 5;
}
+ if (lstat("/dev/log", &dev_log_stat) != 0) {
+ have_dev_log = 0;
+ }
+
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d",
session_type,
tty == NULL ? "" : " on ",
@@ -1512,14 +1518,6 @@ child_close_fds(struct ssh *ssh)
/* Stop directing logs to a high-numbered fd before we close it */
log_redirect_stderr_to(NULL);
-
- /*
- * Close any extra open file descriptors so that we don't have them
- * hanging around in clients. Note that we want to do this after
- * initgroups, because at least on Solaris 2.3 it leaves file
- * descriptors open.
- */
- closefrom(STDERR_FILENO + 1);
}
/*
@@ -1652,8 +1650,6 @@ do_child(struct ssh *ssh, Session *s, const char *command)
exit(1);
}
- closefrom(STDERR_FILENO + 1);
-
do_rc_files(ssh, s, shell);
/* restore SIGPIPE for child */
@@ -1678,9 +1674,17 @@ do_child(struct ssh *ssh, Session *s, const char *command)
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));
}
+ /*
+ * Close any extra open file descriptors so that we don't have them
+ * hanging around in clients. Note that we want to do this after
+ * initgroups, because at least on Solaris 2.3 it leaves file
+ * descriptors open.
+ */
+ closefrom(STDERR_FILENO + 1);
+
fflush(NULL);
/* Get the last component of the shell name. */
diff --git a/sftp-server-main.c b/sftp-server-main.c
index 2c70f89b..bbb79f27 100644
--- a/sftp-server-main.c
+++ b/sftp-server-main.c
@@ -48,5 +48,5 @@ main(int argc, char **argv)
return 1;
}
- 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 a4abb9f7..4985da38 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1901,7 +1901,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;
@@ -1913,7 +1913,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
extern char *__progname;
__progname = ssh_get_progname(argv[0]);
- log_init(__progname, log_level, log_facility, log_stderr);
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
pw = pwcopy(user_pw);
@@ -1986,7 +1986,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
}
}
- log_init(__progname, log_level, log_facility, log_stderr);
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
/*
* On platforms where we can, avoid making /proc/self/{mem,maps}
diff --git a/sftp.h b/sftp.h
index 2bde8bb7..ddf1a396 100644
--- a/sftp.h
+++ b/sftp.h
@@ -97,5 +97,5 @@
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 478381db..9342e416 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -437,7 +437,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
#endif
/* New socket pair */
- monitor_reinit(pmonitor);
+ monitor_reinit(pmonitor, options.chroot_directory);
pmonitor->m_pid = fork();
if (pmonitor->m_pid == -1)
@@ -456,6 +456,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
close(pmonitor->m_sendfd);
pmonitor->m_sendfd = -1;
+ close(pmonitor->m_log_recvfd);
+ pmonitor->m_log_recvfd = -1;
+
+ if (pmonitor->m_log_sendfd != -1)
+ set_log_handler(mm_log_handler, pmonitor);
/* Demote the private keys to public keys. */
demote_sensitive_data();
--
2.49.0

View file

@ -1,27 +0,0 @@
From 007ee98fa9100f7241985ac2a7eed71e17d89a9f 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/50] 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 716ae386..9554b188 100644
--- a/scp.c
+++ b/scp.c
@@ -1876,6 +1876,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.49.0

View file

@ -1,25 +0,0 @@
From 05b09904f431333e19cd24528ef66d1fd15e9efe 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/50] openssh-6.8p1-sshdT-output
---
servconf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/servconf.c b/servconf.c
index c0de7110..105e301d 100644
--- a/servconf.c
+++ b/servconf.c
@@ -3366,7 +3366,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.49.0

View file

@ -1,312 +0,0 @@
From 43320351b6f150167190aacc84f2f87030fef3d2 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/50] 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 | 4 +--
platform.c | 6 ++++-
sshconnect.c | 2 +-
sshd-auth.c | 2 +-
sshd-session.c | 6 +++--
9 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 267a27d2..0d5ae0df 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -77,6 +77,8 @@
/* import */
extern ServerOptions options;
+extern int inetd_flag;
+extern Authctxt *the_authctxt;
extern struct authmethod_cfg methodcfg_pubkey;
static char *
@@ -485,7 +487,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key,
if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
+ runas_pw, temporarily_use_uid, restore_uid,
+ inetd_flag, the_authctxt)) == 0)
goto out;
uid_swapped = 1;
@@ -755,7 +758,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key,
if ((pid = subprocess("AuthorizedKeysCommand", command,
ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
+ runas_pw, temporarily_use_uid, restore_uid,
+ inetd_flag, the_authctxt)) == 0)
goto out;
uid_swapped = 1;
diff --git a/misc.c b/misc.c
index 1e31acc9..09722962 100644
--- a/misc.c
+++ b/misc.c
@@ -2764,7 +2764,8 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr)
pid_t
subprocess(const char *tag, const char *command,
int ac, char **av, FILE **child, u_int flags,
- struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
+ struct passwd *pw, privdrop_fn *drop_privs,
+ privrestore_fn *restore_privs, int inetd, void *the_authctxt)
{
FILE *f = NULL;
struct stat st;
@@ -2898,7 +2899,7 @@ subprocess(const char *tag, const char *command,
_exit(1);
}
#ifdef WITH_SELINUX
- if (sshd_selinux_setup_env_variables() < 0) {
+ if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) {
error ("failed to copy environment: %s",
strerror(errno));
_exit(127);
diff --git a/misc.h b/misc.h
index efecdf1a..9efa9cf4 100644
--- a/misc.h
+++ b/misc.h
@@ -122,7 +122,7 @@ typedef void privrestore_fn(void);
#define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */
#define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */
pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int,
- struct passwd *, privdrop_fn *, privrestore_fn *);
+ struct passwd *, privdrop_fn *, privrestore_fn *, int, void *);
typedef struct arglist arglist;
struct arglist {
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
index 646f0887..291b569a 100644
--- a/openbsd-compat/port-linux-sshd.c
+++ b/openbsd-compat/port-linux-sshd.c
@@ -49,10 +49,6 @@
#include <unistd.h>
#endif
-extern ServerOptions options;
-extern Authctxt *the_authctxt;
-extern int inetd_flag;
-
/* Wrapper around is_selinux_enabled() to log its return value once only */
int
sshd_selinux_enabled(void)
@@ -222,7 +218,8 @@ get_user_context(const char *sename, const char *role, const char *lvl,
}
static void
-ssh_selinux_get_role_level(char **role, const char **level)
+ssh_selinux_get_role_level(char **role, const char **level,
+ Authctxt *the_authctxt)
{
*role = NULL;
*level = NULL;
@@ -240,8 +237,8 @@ ssh_selinux_get_role_level(char **role, const char **level)
/* Return the default security context for the given username */
static int
-sshd_selinux_getctxbyname(char *pwname,
- security_context_t *default_sc, security_context_t *user_sc)
+sshd_selinux_getctxbyname(char *pwname, security_context_t *default_sc,
+ security_context_t *user_sc, int inetd, Authctxt *the_authctxt)
{
char *sename, *lvl;
char *role;
@@ -249,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
int r = 0;
context_t con = NULL;
- ssh_selinux_get_role_level(&role, &reqlvl);
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
#ifdef HAVE_GETSEUSERBYNAME
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
@@ -271,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) {
security_context_t sshdsc=NULL;
if (getcon_raw(&sshdsc) < 0)
@@ -332,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
/* Setup environment variables for pam_selinux */
static int
-sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
+sshd_selinux_setup_variables(int(*set_it)(char *, const char *), int inetd,
+ Authctxt *the_authctxt)
{
const char *reqlvl;
char *role;
@@ -341,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
debug3_f("setting execution context");
- ssh_selinux_get_role_level(&role, &reqlvl);
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
- if (inetd_flag) {
+ if (inetd) {
use_current = "1";
} else {
use_current = "";
@@ -361,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
}
static int
-sshd_selinux_setup_pam_variables(void)
+sshd_selinux_setup_pam_variables(int inetd,
+ int(pam_setenv)(char *, const char *), Authctxt *the_authctxt)
{
- return sshd_selinux_setup_variables(do_pam_putenv);
+ return sshd_selinux_setup_variables(pam_setenv, inetd, the_authctxt);
}
static int
@@ -373,25 +372,28 @@ do_setenv(char *name, const char *value)
}
int
-sshd_selinux_setup_env_variables(void)
+sshd_selinux_setup_env_variables(int inetd, void *the_authctxt)
{
- return sshd_selinux_setup_variables(do_setenv);
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
+ return sshd_selinux_setup_variables(do_setenv, inetd, authctxt);
}
/* Set the execution context to the default for the specified user */
void
-sshd_selinux_setup_exec_context(char *pwname)
+sshd_selinux_setup_exec_context(char *pwname, int inetd,
+ int(pam_setenv)(char *, const char *), void *the_authctxt, int use_pam)
{
security_context_t user_ctx = NULL;
int r = 0;
security_context_t default_ctx = NULL;
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
if (!sshd_selinux_enabled())
return;
- if (options.use_pam) {
+ if (use_pam) {
/* do not compute context, just setup environment for pam_selinux */
- if (sshd_selinux_setup_pam_variables()) {
+ if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) {
switch (security_getenforce()) {
case -1:
fatal_f("security_getenforce() failed");
@@ -407,7 +409,7 @@ sshd_selinux_setup_exec_context(char *pwname)
debug3_f("setting execution context");
- r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt);
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 7f8ba200..3cd7da6a 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -25,8 +25,8 @@ 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);
+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 --git a/platform.c b/platform.c
index 0d12f311..f0800b1f 100644
--- a/platform.c
+++ b/platform.c
@@ -33,6 +33,8 @@
#include "openbsd-compat/openbsd-compat.h"
extern ServerOptions options;
+extern int inetd_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)
}
#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,
+ options.use_pam);
#endif
}
diff --git a/sshconnect.c b/sshconnect.c
index c86182d1..04084810 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -925,7 +925,7 @@ load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template,
if ((pid = subprocess(tag, command, ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH|
- SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0)
+ SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL, 0, NULL)) == 0)
goto out;
load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1);
diff --git a/sshd-auth.c b/sshd-auth.c
index e4a8edfd..897db9b4 100644
--- a/sshd-auth.c
+++ b/sshd-auth.c
@@ -122,7 +122,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 9342e416..81d30152 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -136,7 +136,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;
@@ -1359,7 +1359,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.49.0

View file

@ -1,58 +0,0 @@
From 35205319dd71d8e61c1596b8f9479df91aff7756 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/50] 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 b31062c2..1fabf99d 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -277,6 +277,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
@@ -295,6 +298,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
@@ -304,6 +322,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.49.0

View file

@ -1,654 +0,0 @@
From b436140fe3abd9f97f01f9af9f5da5cf6c5d7725 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 30/50] 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 8d5d0722..a43b2a27 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -438,17 +438,13 @@ A single argument of
causes no CNAMEs to be considered for canonicalization.
This is the default behaviour.
.It Cm CASignatureAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 which algorithms are allowed for signing of certificates
by certificate authorities (CAs).
-The default is:
-.Bd -literal -offset indent
-ssh-ed25519,ecdsa-sha2-nistp256,
-ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
-.Pp
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
(the default),
the check will not be executed.
.It Cm Ciphers
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 ciphers allowed and their order of preference.
Multiple ciphers must be comma-separated.
If the specified list begins with a
.Sq +
-character, then the specified ciphers will be appended to the default set
-instead of replacing them.
+character, then the specified ciphers will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified ciphers (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified ciphers will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The supported ciphers are:
.Bd -literal -offset indent
@@ -616,13 +617,6 @@ aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
.Ed
.Pp
-The default is:
-.Bd -literal -offset indent
-chacha20-poly1305@openssh.com,
-aes128-gcm@openssh.com,aes256-gcm@openssh.com,
-aes128-ctr,aes192-ctr,aes256-ctr
-.Ed
-.Pp
The list of available ciphers may also be obtained using
.Qq ssh -Q cipher .
.It Cm ClearAllForwardings
@@ -1022,6 +1016,11 @@ command line will be passed untouched to the GSSAPI library.
The default is
.Dq no .
.It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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
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-,
gss-curve25519-sha256-
.Ed
.Pp
-The default is
-.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,
-gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
This option only applies to connections using GSSAPI.
+.Pp
.It Cm HashKnownHosts
Indicates that
.Xr ssh 1
@@ -1056,36 +1053,25 @@ will not be converted automatically,
but may be manually hashed using
.Xr ssh-keygen 1 .
.It Cm HostbasedAcceptedAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 signature algorithms that will be used for hostbased
authentication as a comma-separated list of patterns.
Alternately if the specified list begins with a
.Sq +
character, then the specified signature algorithms will be appended
-to the default set instead of replacing them.
+to the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified signature algorithms (including wildcards)
-will be removed from the default set instead of replacing them.
+will be removed from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified signature algorithms will be placed
-at the head of the default set.
-The default for this option is:
-.Bd -literal -offset 3n
-ssh-ed25519-cert-v01@openssh.com,
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
+at the head of the built-in openssh default set.
.Pp
The
.Fl Q
@@ -1138,6 +1124,17 @@ to prefer their algorithms.
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
+.Pp
+The proposed
+.Cm HostKeyAlgorithms
+during KEX are limited to the set of algorithms that is defined in
+.Cm PubkeyAcceptedAlgorithms
+and therefore they are indirectly affected by system-wide
+.Xr crypto_policies 7 .
+.Xr crypto_policies 7 can not handle the list of host key algorithms directly as doing so
+would break the order given by the
+.Pa known_hosts
+file.
.It Cm HostKeyAlias
Specifies an alias that should be used instead of the
real host name when looking up or saving the host key
@@ -1376,6 +1373,11 @@ it may be zero or more of:
and
.Cm pam .
.It Cm KexAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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
@@ -1384,29 +1386,17 @@ Multiple algorithms must be comma-separated.
.Pp
If the specified list begins with a
.Sq +
-character, then the specified algorithms will be appended to the default set
-instead of replacing them.
+character, then the specified methods will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.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,
-curve25519-sha256,curve25519-sha256@libssh.org,
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
-diffie-hellman-group-exchange-sha256,
-diffie-hellman-group16-sha512,
-diffie-hellman-group18-sha512,
-diffie-hellman-group14-sha256
-.Ed
.Pp
+built-in openssh default set.
The list of supported key exchange algorithms may also be obtained using
.Qq ssh -Q kex .
.It Cm KnownHostsCommand
@@ -1522,37 +1512,33 @@ function, and all code in the
file.
This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 MAC (message authentication code) algorithms
in order of preference.
The MAC algorithm is used for data integrity protection.
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
-instead of replacing them.
+character, then the specified algorithms will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The algorithms that contain
.Qq -etm
calculate the MAC after encryption (encrypt-then-mac).
These are considered safer and their use recommended.
.Pp
-The default is:
-.Bd -literal -offset indent
-umac-64-etm@openssh.com,umac-128-etm@openssh.com,
-hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
-hmac-sha1-etm@openssh.com,
-umac-64@openssh.com,umac-128@openssh.com,
-hmac-sha2-256,hmac-sha2-512,hmac-sha1
-.Ed
-.Pp
The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac .
.It Cm NoHostAuthenticationForLocalhost
@@ -1741,39 +1727,31 @@ instead of continuing to execute and pass data.
The default is
.Cm no .
.It Cm PubkeyAcceptedAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 signature algorithms that will be used for public key
authentication as a comma-separated list of patterns.
If the specified list begins with a
.Sq +
-character, then the algorithms after it will be appended to the default
-instead of replacing it.
+character, then the algorithms after it will be appended to the built-in
+openssh default instead of replacing it.
If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
-default set.
-The default for this option is:
-.Bd -literal -offset 3n
-ssh-ed25519-cert-v01@openssh.com,
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
+built-in openssh default set.
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q PubkeyAcceptedAlgorithms .
+.Pp
+This option affects also
+.Cm HostKeyAlgorithms
.It Cm PubkeyAuthentication
Specifies whether to try public key authentication.
The argument to this keyword must be
@@ -2497,7 +2475,9 @@ for those users who do not have a configuration file.
This file must be world-readable.
.El
.Sh SEE ALSO
-.Xr ssh 1
+.Xr ssh 1 ,
+.Xr crypto-policies 7 ,
+.Xr update-crypto-policies 8
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free
diff --git a/sshd_config.5 b/sshd_config.5
index 26fcdc84..583a01cd 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -379,17 +379,13 @@ If the argument is
then no banner is displayed.
By default, no banner is displayed.
.It Cm CASignatureAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 which algorithms are allowed for signing of certificates
by certificate authorities (CAs).
-The default is:
-.Bd -literal -offset indent
-ssh-ed25519,ecdsa-sha2-nistp256,
-ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
-.Pp
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
indicating not to
.Xr chroot 2 .
.It Cm Ciphers
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 ciphers allowed.
Multiple ciphers must be comma-separated.
If the specified list begins with a
.Sq +
-character, then the specified ciphers will be appended to the default set
-instead of replacing them.
+character, then the specified ciphers will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified ciphers (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified ciphers will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The supported ciphers are:
.Pp
@@ -573,13 +574,6 @@ aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-chacha20-poly1305@openssh.com,
-aes128-gcm@openssh.com,aes256-gcm@openssh.com,
-aes128-ctr,aes192-ctr,aes256-ctr
-.Ed
-.Pp
The list of available ciphers may also be obtained using
.Qq ssh -Q cipher .
.It Cm ClientAliveCountMax
@@ -774,53 +768,43 @@ For this to work
.Cm GSSAPIKeyExchange
needs to be enabled in the server and also used by the client.
.It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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
The list of key exchange algorithms that are accepted by GSSAPI
key exchange. Possible values are
.Bd -literal -offset 3n
-gss-gex-sha1-,
-gss-group1-sha1-,
-gss-group14-sha1-,
-gss-group14-sha256-,
-gss-group16-sha512-,
-gss-nistp256-sha256-,
+gss-gex-sha1-
+gss-group1-sha1-
+gss-group14-sha1-
+gss-group14-sha256-
+gss-group16-sha512-
+gss-nistp256-sha256-
gss-curve25519-sha256-
.Ed
-.Pp
-The default is
-.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,
-gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
This option only applies to connections using GSSAPI.
.It Cm HostbasedAcceptedAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 signature algorithms that will be accepted for hostbased
authentication as a list of comma-separated patterns.
Alternately if the specified list begins with a
.Sq +
character, then the specified signature algorithms will be appended to
-the default set instead of replacing them.
+the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified signature algorithms (including wildcards)
-will be removed from the default set instead of replacing them.
+will be removed from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified signature algorithms will be placed at
-the head of the default set.
-The default for this option is:
-.Bd -literal -offset 3n
-ssh-ed25519-cert-v01@openssh.com,
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
+the head of the built-in openssh default set.
.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
.Ev SSH_AUTH_SOCK
environment variable.
.It Cm HostKeyAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 host key signature algorithms
that the server offers.
The default for this option is:
-.Bd -literal -offset 3n
-ssh-ed25519-cert-v01@openssh.com,
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
-.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts
@@ -1052,6 +1025,11 @@ Specifies whether to look at .k5login file for user's aliases.
The default is
.Cm yes .
.It Cm KexAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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
@@ -1060,16 +1038,16 @@ Multiple algorithms must be comma-separated.
.Pp
If the specified list begins with a
.Sq +
-character, then the specified algorithms will be appended to the default set
-instead of replacing them.
+character, then the specified methods will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
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
@@ -1106,14 +1084,6 @@ sntrup761x25519-sha512
sntrup761x25519-sha512@openssh.com
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-mlkem768x25519-sha256,
-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,
-curve25519-sha256,curve25519-sha256@libssh.org,
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
-.Ed
-.Pp
The list of supported key exchange algorithms may also be obtained using
.Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress
@@ -1200,21 +1170,26 @@ function, and all code in the
file.
This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the available MAC (message authentication code) algorithms.
The MAC algorithm is used for data integrity protection.
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
-instead of replacing them.
+character, then the specified algorithms will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The algorithms that contain
.Qq -etm
@@ -1257,15 +1232,6 @@ umac-64-etm@openssh.com
umac-128-etm@openssh.com
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-umac-64-etm@openssh.com,umac-128-etm@openssh.com,
-hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
-hmac-sha1-etm@openssh.com,
-umac-64@openssh.com,umac-128@openssh.com,
-hmac-sha2-256,hmac-sha2-512,hmac-sha1
-.Ed
-.Pp
The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac .
.It Cm Match
@@ -1753,36 +1719,25 @@ or equivalent.)
The default is
.Cm yes .
.It Cm PubkeyAcceptedAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 signature algorithms that will be accepted for public key
authentication as a list of comma-separated patterns.
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.
+character, then the specified algorithms will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
-default set.
-The default for this option is:
-.Bd -literal -offset 3n
-ssh-ed25519-cert-v01@openssh.com,
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
+built-in openssh default set.
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q PubkeyAcceptedAlgorithms .
@@ -2289,7 +2244,9 @@ This file should be writable by root only, but it is recommended
.El
.Sh SEE ALSO
.Xr sftp-server 8 ,
-.Xr sshd 8
+.Xr sshd 8 ,
+.Xr crypto-policies 7 ,
+.Xr update-crypto-policies 8
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free
--
2.49.0

View file

@ -1,157 +0,0 @@
From 430bd33963725beb8ec01a1e581529ae6bf6bec0 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 31/50] 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 d9bd2f51..d92a8580 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3137,6 +3137,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 19a56e8e..8b200ff4 100644
--- a/kex.c
+++ b/kex.c
@@ -40,6 +40,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"
@@ -1078,6 +1083,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)
@@ -1141,6 +1247,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.49.0

View file

@ -1,33 +0,0 @@
From cfe5a99d335eb57b8c08b4eb6b4535dd042d96e3 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 33/50] openssh-8.2p1-x11-without-ipv6
---
channels.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/channels.c b/channels.c
index 7438c1a5..95836d50 100644
--- a/channels.c
+++ b/channels.c
@@ -5055,6 +5055,16 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
debug2_f("bind port %d: %.100s", port,
strerror(errno));
close(sock);
+
+ /* do not remove successfully opened
+ * sockets if the request failed because
+ * the protocol IPv4/6 is not available
+ * (e.g. IPv6 may be disabled while being
+ * supported)
+ */
+ if (EADDRNOTAVAIL == errno)
+ continue;
+
for (n = 0; n < num_socks; n++)
close(socks[n]);
num_socks = 0;
--
2.49.0

View file

@ -1,56 +0,0 @@
From 8de0391e3b3eb75e23ee9f173f04a9c78f2b96c9 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/50] 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 b4100ea1..a042c3c8 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -523,7 +523,11 @@ sshpam_thread(void *ctxtp)
goto auth_fail;
if (!do_pam_account()) {
- sshpam_err = PAM_ACCT_EXPIRED;
+ /* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN.
+ * Backward compatibility for other errors. */
+ if (sshpam_err != PAM_PERM_DENIED
+ && sshpam_err != PAM_USER_UNKNOWN)
+ sshpam_err = PAM_ACCT_EXPIRED;
goto auth_fail;
}
if (sshpam_authctxt->force_pwchange) {
@@ -580,8 +584,10 @@ sshpam_thread(void *ctxtp)
pam_strerror(sshpam_handle, sshpam_err))) != 0)
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);
+ if (sshpam_err == PAM_PERM_DENIED
+ || sshpam_err == PAM_USER_UNKNOWN
+ || sshpam_err == PAM_ACCT_EXPIRED)
+ ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer);
else if (sshpam_maxtries_reached)
ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer);
else
@@ -890,9 +896,11 @@ sshpam_query(void *ctx, char **name, char **info,
free(msg);
break;
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.49.0

View file

@ -1,63 +0,0 @@
From a68f3741fdc01bf6823a69d2442caba7de9835f9 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 35/50] 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 1158bec9..43f0c570 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -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 aa2e2d8b..373d7237 100644
--- a/scp.1
+++ b/scp.1
@@ -331,6 +331,13 @@ during download or upload.
By default a 32KB buffer is used.
.El
.El
+.Pp
+Usage of SCP protocol can be blocked by creating a world-readable
+.Ar /etc/ssh/disable_scp
+file. If this file exists, when SCP protocol is in use (either remotely or
+via the
+.Fl O
+option), the program will exit.
.Sh EXIT STATUS
.Ex -std scp
.Sh SEE ALSO
diff --git a/scp.c b/scp.c
index 7f9795a5..7ed1a54c 100644
--- a/scp.c
+++ b/scp.c
@@ -649,6 +649,14 @@ main(int argc, char **argv)
if (iamremote)
mode = MODE_SCP;
+ if (mode == MODE_SCP) {
+ FILE *f = fopen(_PATH_SCP_KILL_SWITCH, "r");
+ if (f != NULL) {
+ fclose(f);
+ fatal("SCP protocol is forbidden via %s", _PATH_SCP_KILL_SWITCH);
+ }
+ }
+
if ((pwd = getpwuid(userid = getuid())) == NULL)
fatal("unknown user %u", (u_int) userid);
--
2.49.0

View file

@ -1,200 +0,0 @@
From 99e1e3af524376788e591ca73387f1ca37e6f5ef 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/50] 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 7ed1a54c..0c87dd0e 100644
--- a/scp.c
+++ b/scp.c
@@ -1388,7 +1388,7 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
if (src_is_dir && iamrecursive) {
if (sftp_upload_dir(conn, src, abs_dst, pflag,
- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) {
error("failed to upload directory %s to %s", src, targ);
errs = 1;
}
diff --git a/sftp-client.c b/sftp-client.c
index 9f8ab4af..873dec04 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1003,7 +1003,7 @@ sftp_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
/* Implements both the realpath and expand-path operations */
static char *
-sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
+sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir)
{
struct sshbuf *msg;
u_int expected_id, count, id;
@@ -1049,11 +1049,43 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
fatal_fr(r, "parse status");
- error("%s %s: %s", expand ? "expand" : "realpath",
- path, *errmsg == '\0' ? fx2txt(status) : errmsg);
- free(errmsg);
- sshbuf_free(msg);
- return NULL;
+ if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) {
+ memset(&a, '\0', sizeof(a));
+ if ((r = sftp_mkdir(conn, path, &a, 0)) != 0) {
+ sshbuf_free(msg);
+ return NULL;
+ }
+ debug2("Sending SSH2_FXP_REALPATH \"%s\" - create dir", path);
+ send_string_request(conn, id, SSH2_FXP_REALPATH,
+ path, strlen(path));
+
+ get_msg(conn, msg);
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+ (r = sshbuf_get_u32(msg, &id)) != 0)
+ fatal_fr(r, "parse");
+
+ if (id != expected_id)
+ fatal("ID mismatch (%u != %u)", id, expected_id);
+
+ if (type == SSH2_FXP_STATUS) {
+ free(errmsg);
+
+ if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
+ (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
+ fatal_fr(r, "parse status");
+ error("%s %s: %s", expand ? "expand" : "realpath",
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+ free(errmsg);
+ sshbuf_free(msg);
+ return NULL;
+ }
+ } else {
+ error("%s %s: %s", expand ? "expand" : "realpath",
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+ free(errmsg);
+ sshbuf_free(msg);
+ return NULL;
+ }
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
@@ -1078,9 +1110,9 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
}
char *
-sftp_realpath(struct sftp_conn *conn, const char *path)
+sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir)
{
- return sftp_realpath_expand(conn, path, 0);
+ return sftp_realpath_expand(conn, path, 0, create_dir);
}
int
@@ -1094,9 +1126,9 @@ sftp_expand_path(struct sftp_conn *conn, const char *path)
{
if (!sftp_can_expand_path(conn)) {
debug3_f("no server support, fallback to realpath");
- return sftp_realpath_expand(conn, path, 0);
+ return sftp_realpath_expand(conn, path, 0, 0);
}
- return sftp_realpath_expand(conn, path, 1);
+ return sftp_realpath_expand(conn, path, 1, 0);
}
int
@@ -2016,7 +2048,7 @@ sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst,
char *src_canon;
int ret;
- if ((src_canon = sftp_realpath(conn, src)) == NULL) {
+ if ((src_canon = sftp_realpath(conn, src, 0)) == NULL) {
error("download \"%s\": path canonicalization failed", src);
return -1;
}
@@ -2366,12 +2398,12 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int
sftp_upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
int preserve_flag, int print_flag, int resume, int fsync_flag,
- int follow_link_flag, int inplace_flag)
+ int follow_link_flag, int inplace_flag, int create_dir)
{
char *dst_canon;
int ret;
- if ((dst_canon = sftp_realpath(conn, dst)) == NULL) {
+ if ((dst_canon = sftp_realpath(conn, dst, create_dir)) == NULL) {
error("upload \"%s\": path canonicalization failed", dst);
return -1;
}
@@ -2826,7 +2858,7 @@ sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
char *from_path_canon;
int ret;
- if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) {
+ if ((from_path_canon = sftp_realpath(from, from_path, 0)) == NULL) {
error("crossload \"%s\": path canonicalization failed",
from_path);
return -1;
diff --git a/sftp-client.h b/sftp-client.h
index 74cdae7d..00ed6630 100644
--- a/sftp-client.h
+++ b/sftp-client.h
@@ -111,7 +111,7 @@ int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
/* Canonicalise 'path' - caller must free result */
-char *sftp_realpath(struct sftp_conn *, const char *);
+char *sftp_realpath(struct sftp_conn *, const char *, int);
/* Canonicalisation with tilde expansion (requires server extension) */
char *sftp_expand_path(struct sftp_conn *, const char *);
@@ -163,7 +163,7 @@ int sftp_upload(struct sftp_conn *, const char *, const char *,
* times if 'pflag' is set
*/
int sftp_upload_dir(struct sftp_conn *, const char *, const char *,
- int, int, int, int, int, int);
+ int, int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to
diff --git a/sftp.c b/sftp.c
index bdedd141..322e6d1f 100644
--- a/sftp.c
+++ b/sftp.c
@@ -809,7 +809,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
(rflag || global_rflag)) {
if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
- fflag || global_fflag, 0, 0) == -1)
+ fflag || global_fflag, 0, 0, 0) == -1)
err = -1;
} else {
if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
@@ -1644,7 +1644,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
path1 = sftp_make_absolute(path1, *pwd);
- if ((tmp = sftp_realpath(conn, path1)) == NULL) {
+ if ((tmp = sftp_realpath(conn, path1, 0)) == NULL) {
err = 1;
break;
}
@@ -2249,7 +2249,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
}
#endif /* USE_LIBEDIT */
- if ((remote_path = sftp_realpath(conn, ".")) == NULL)
+ if ((remote_path = sftp_realpath(conn, ".", 0)) == NULL)
fatal("Need cwd");
startdir = xstrdup(remote_path);
--
2.49.0

View file

@ -1,37 +0,0 @@
From 286bc4a302b5130f732c857095ae665f7bea01dd 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/50] openssh-8.7p1-minrsabits
---
readconf.c | 1 +
servconf.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/readconf.c b/readconf.c
index 6c04ed43..f340bf50 100644
--- a/readconf.c
+++ b/readconf.c
@@ -343,6 +343,7 @@ static struct {
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
{ "requiredrsasize", oRequiredRSASize },
+ { "rsaminsize", oRequiredRSASize }, /* alias */
{ "enableescapecommandline", oEnableEscapeCommandline },
{ "obscurekeystroketiming", oObscureKeystrokeTiming },
{ "channeltimeout", oChannelTimeout },
diff --git a/servconf.c b/servconf.c
index 15c99b30..84891544 100644
--- a/servconf.c
+++ b/servconf.c
@@ -788,6 +788,7 @@ static struct {
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
+ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */
{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },
{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
{ "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL },
--
2.49.0

View file

@ -1,25 +0,0 @@
From 26af04432f6404eb03780265a5cce948ecfec8dc Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 38/50] 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 f6112458..417c2048 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.49.0

View file

@ -1,265 +0,0 @@
From 80d967a18261156573e7385f8e534a89d2767d67 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/50] 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 a49abb92..c6f56553 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 d484b82b..dcfde3a9 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;
@@ -66,7 +66,7 @@ linux_audit_user_logxxx(int uid, const char *username,
}
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);
@@ -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_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);
@@ -179,26 +211,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
@@ -211,31 +251,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:
@@ -255,9 +305,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);
}
@@ -266,12 +318,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("%s: unhandled event %d", __func__, event);
break;
}
+ free(audit_hostname);
}
void
diff --git a/audit.c b/audit.c
index d0433c3a..28d51a14 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 45d66ccf..05ac132c 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.49.0

View file

@ -1,763 +0,0 @@
From 79f9b2763d85ec592cb7e54dcf1c695d8dd138b1 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 28 Aug 2025 14:01:38 +0200
Subject: [PATCH 42/54] 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 | 16 ++++++---
ssh-ed25519.c | 9 +++++
ssh-gss.h | 5 +++
ssh-keygen.c | 22 ++++++++++--
ssh-rsa.c | 3 ++
ssh.c | 5 +++
sshconnect2.c | 9 ++++-
sshd-session.c | 1 +
sshd.c | 13 +++++++
sshkey.c | 37 ++++++++++++++++++++
19 files changed, 272 insertions(+), 30 deletions(-)
diff --git a/dh.c b/dh.c
index 168dea1dd..8c9a29fa7 100644
--- a/dh.c
+++ b/dh.c
@@ -36,6 +36,7 @@
#include <openssl/bn.h>
#include <openssl/dh.h>
+#include <openssl/fips.h>
#include "dh.h"
#include "pathnames.h"
@@ -164,6 +165,12 @@ choose_dh(int min, int wantbits, int max)
int best, bestcount, which, linenum;
struct dhgroup dhg;
+ if (FIPS_mode()) {
+ verbose("Using arbitrary primes is not allowed in FIPS mode."
+ " Falling back to known groups.");
+ return (dh_new_group_fallback(max));
+ }
+
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)
return 8192;
}
+/*
+ * Compares the received DH parameters with known-good groups,
+ * which might be either from group14, group16 or group18.
+ */
+int
+dh_is_known_group(const DH *dh)
+{
+ const BIGNUM *p, *g;
+ const BIGNUM *known_p, *known_g;
+ DH *known = NULL;
+ int bits = 0, rv = 0;
+
+ DH_get0_pqg(dh, &p, NULL, &g);
+ bits = BN_num_bits(p);
+
+ if (bits <= 3072) {
+ known = dh_new_group14();
+ } else if (bits <= 6144) {
+ known = dh_new_group16();
+ } else {
+ known = dh_new_group18();
+ }
+
+ DH_get0_pqg(known, &known_p, NULL, &known_g);
+
+ if (BN_cmp(g, known_g) == 0 &&
+ BN_cmp(p, known_p) == 0) {
+ rv = 1;
+ }
+
+ DH_free(known);
+ return rv;
+}
+
#endif /* WITH_OPENSSL */
diff --git a/dh.h b/dh.h
index c6326a39d..e51e292b8 100644
--- a/dh.h
+++ b/dh.h
@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);
int dh_pub_is_valid(const DH *, const BIGNUM *);
+int dh_is_known_group(const DH *);
u_int dh_estimate(int);
void dh_set_moduli_file(const char *);
diff --git a/kex-names.c b/kex-names.c
index 6c0b7c2b3..cd3902ad2 100644
--- a/kex-names.c
+++ b/kex-names.c
@@ -33,6 +33,7 @@
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
+#include <openssl/fips.h>
#include <openssl/evp.h>
#endif
@@ -206,7 +207,10 @@ kex_names_valid(const char *names)
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (kex_alg_by_name(p) == NULL) {
- error("Unsupported KEX algorithm \"%.100s\"", p);
+ if (FIPS_mode())
+ error("\"%.100s\" is not allowed in FIPS mode", p);
+ else
+ error("Unsupported KEX algorithm \"%.100s\"", p);
free(s);
return 0;
}
diff --git a/kex.c b/kex.c
index 62f607d6f..71fbe5cbe 100644
--- a/kex.c
+++ b/kex.c
@@ -40,6 +40,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>
@@ -109,7 +110,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 15df591ca..eecdceba2 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
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
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
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 e99e0cf21..4c3feae09 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -28,6 +28,7 @@
#ifdef WITH_OPENSSL
+#include <openssl/fips.h>
#include <sys/types.h>
#include <openssl/dh.h>
@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
+ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
p = g = NULL; /* belong to kex->dh now */
/* generate and send 'e', client DH public key */
diff --git a/myproposal.h b/myproposal.h
index 8fe9276c2..3e0ec6826 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -58,6 +58,18 @@
"rsa-sha2-512," \
"rsa-sha2-256"
+#define KEX_FIPS_PK_ALG \
+ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
+ "rsa-sha2-512-cert-v01@openssh.com," \
+ "rsa-sha2-256-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp256," \
+ "ecdsa-sha2-nistp384," \
+ "ecdsa-sha2-nistp521," \
+ "rsa-sha2-512," \
+ "rsa-sha2-256"
+
#define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \
"aes128-gcm@openssh.com,aes256-gcm@openssh.com," \
@@ -79,6 +91,27 @@
#define KEX_CLIENT_MAC KEX_SERVER_MAC
+#define KEX_FIPS_ENCRYPT \
+ "aes128-ctr,aes192-ctr,aes256-ctr," \
+ "aes128-cbc,3des-cbc," \
+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
+ "aes128-gcm@openssh.com,aes256-gcm@openssh.com"
+#define KEX_DEFAULT_KEX_FIPS \
+ "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"
+#define KEX_FIPS_MAC \
+ "hmac-sha1," \
+ "hmac-sha2-256," \
+ "hmac-sha2-512," \
+ "hmac-sha1-etm@openssh.com," \
+ "hmac-sha2-256-etm@openssh.com," \
+ "hmac-sha2-512-etm@openssh.com"
+
/* 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 f340bf501..ea9d293c3 100644
--- a/readconf.c
+++ b/readconf.c
@@ -43,6 +43,7 @@
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
+#include <openssl/fips.h>
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
@@ -3043,11 +3044,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 */
- def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher);
- def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac);
- def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex);
- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
+ def_cipher = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher);
+ def_mac = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac);
+ def_kex = match_filter_allowlist((FIPS_mode() ?
+ KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex);
+ def_key = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key);
+ def_sig = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig);
#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 1fabf99d0..ccb61586e 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -230,6 +230,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_open
SC_DENY(__NR_open, EACCES),
#endif
+#ifdef __NR_socket
+ SC_DENY(__NR_socket, EACCES),
+#endif
#ifdef __NR_openat
SC_DENY(__NR_openat, EACCES),
#endif
diff --git a/servconf.c b/servconf.c
index 84891544b..8b708cbf4 100644
--- a/servconf.c
+++ b/servconf.c
@@ -37,6 +37,7 @@
#include <limits.h>
#include <stdarg.h>
#include <errno.h>
+#include <openssl/fips.h>
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
@@ -247,11 +248,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 */
- def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
- def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
- def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
+ def_cipher = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher);
+ def_mac = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac);
+ def_kex = match_filter_allowlist((FIPS_mode() ?
+ KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex);
+ def_key = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key);
+ def_sig = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig);
#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 22d8db026..41942f4e5 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"
@@ -164,6 +165,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;
@@ -221,6 +226,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 16cff9473..792aafde0 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -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
@@ -68,6 +69,7 @@
#include "cipher.h"
#define DEFAULT_KEY_TYPE_NAME "ed25519"
+#define FIPS_DEFAULT_KEY_TYPE_NAME "rsa"
/*
* Default number of bits in the RSA, DSA and ECDSA keys. These value can be
@@ -202,6 +204,12 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
#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)
@@ -259,7 +267,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 WITH_DSA
@@ -1144,9 +1152,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_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_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));
@@ -3849,7 +3865,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 3ad1fddc4..6c2f771a3 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -23,6 +23,7 @@
#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 98b103c9e..abc8b8439 100644
--- a/ssh.c
+++ b/ssh.c
@@ -78,6 +78,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#endif
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
#include "openbsd-compat/sys-queue.h"
@@ -1642,6 +1643,10 @@ main(int ac, char **av)
exit(0);
}
+ if (FIPS_mode()) {
+ debug("FIPS mode initialized");
+ }
+
/* 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 0af15bcc1..3e02f485d 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -45,6 +45,8 @@
#include <vis.h>
#endif
+#include <openssl/fips.h>
+
#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,
#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];
@@ -281,7 +286,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
}
gss = ssh_gssapi_client_mechanisms(gss_host,
- options.gss_client_identity, options.gss_kex_algorithms);
+ options.gss_client_identity, gss_kex_filtered);
+ free(gss_kex_filtered);
+
if (gss) {
debug("Offering GSSAPI proposal: %s", gss);
xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
diff --git a/sshd-session.c b/sshd-session.c
index a808ac9a6..a67a78391 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -62,6 +62,7 @@
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
#endif
diff --git a/sshd.c b/sshd.c
index 8a99f0b29..5ff0b5ff0 100644
--- a/sshd.c
+++ b/sshd.c
@@ -52,6 +52,7 @@
#endif
#include <pwd.h>
#include <signal.h>
+#include <syslog.h>
#include <stdarg.h>
#include <time.h>
#include <stdio.h>
@@ -63,6 +64,7 @@
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
#include <openssl/rand.h>
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
#endif
@@ -1611,6 +1613,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]);
+ if (FIPS_mode() && key != NULL && (sshkey_type_plain(key->type) == KEY_ED25519_SK
+ || sshkey_type_plain(key->type) == KEY_ED25519)) {
+ logit_f("sshd: Ed25519 keys are not allowed in FIPS mode, skipping %s", options.host_key_files[i]);
+ sshkey_free(key);
+ key = NULL;
+ continue;
+ }
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
@@ -1830,6 +1839,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);
+ if (FIPS_mode()) {
+ debug("FIPS mode initialized");
+ }
+
/*
* Chdir to the root directory so that the current disk can be
* unmounted if desired.
diff --git a/sshkey.c b/sshkey.c
index 4e41a78c7..ca1cdb642 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -35,6 +35,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/pem.h>
+#include <openssl/fips.h>
#endif
#include "crypto_api.h"
@@ -59,6 +60,7 @@
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "match.h"
+#include "log.h"
#include "ssh-sk.h"
#ifdef WITH_XMSS
@@ -408,6 +410,18 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
impl = keyimpls[i];
if (impl->name == NULL || impl->type == KEY_NULL)
continue;
+ if (FIPS_mode()) {
+ switch (impl->type) {
+ case KEY_ED25519:
+ case KEY_ED25519_SK:
+ case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
if (!include_sigonly && impl->sigonly)
continue;
if ((certs_only && !impl->cert) || (plain_only && impl->cert))
@@ -1441,6 +1455,20 @@ sshkey_read(struct sshkey *ret, char **cpp)
return SSH_ERR_EC_CURVE_MISMATCH;
}
+ switch (type) {
+ case KEY_ED25519:
+ case KEY_ED25519_SK:
+ case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
+ if (FIPS_mode()) {
+ sshkey_free(k);
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ break;
+ default:
+ break;
+ }
/* Fill in ret from parsed key */
sshkey_free_contents(ret);
*ret = *k;
@@ -2275,6 +2303,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 ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
if ((r = sshkey_unshield_private(key)) != 0)
@@ -2311,6 +2344,10 @@ sshkey_verify(const struct sshkey *key,
*detailsp = NULL;
if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
if ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
return impl->funcs->verify(key, sig, siglen, data, dlen,
--
2.51.0

View file

@ -1,47 +0,0 @@
From 299a602802d7c7d121306eb2aeae1502871a35cb 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/50] openssh-8.7p1-ssh-manpage
---
ssh.1 | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/ssh.1 b/ssh.1
index 6a9fbdc5..755cdef2 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.49.0

View file

@ -1,133 +0,0 @@
From 5c92430c08ac392b5b2ace899cc043247c923734 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/50] 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 28dcfe17..b9e716dc 100644
--- a/regress/hostkey-agent.sh
+++ b/regress/hostkey-agent.sh
@@ -17,8 +17,21 @@ trace "make CA key"
${SSHKEYGEN} -qt ed25519 -f $OBJ/agent-ca -N '' || fatal "ssh-keygen CA"
+PUBKEY_ACCEPTED_ALGOS=`$SSH -G "example.com" | \
+ grep -i "PubkeyAcceptedAlgorithms" | cut -d ' ' -f2- | tr "," "|"`
+SSH_ACCEPTED_KEYTYPES=`echo "$SSH_KEYTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
+echo $PUBKEY_ACCEPTED_ALGOS | grep "rsa"
+r=$?
+if [ $r == 0 ]; then
+echo $SSH_ACCEPTED_KEYTYPES | grep "rsa"
+r=$?
+if [ $r -ne 0 ]; then
+SSH_ACCEPTED_KEYTYPES="$SSH_ACCEPTED_KEYTYPES ssh-rsa"
+fi
+fi
+
trace "load hostkeys"
-for k in $SSH_KEYTYPES ; do
+for k in $SSH_ACCEPTED_KEYTYPES ; do
${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
unset SSH_AUTH_SOCK
-for k in $SSH_KEYTYPES ; do
+for k in $SSH_ACCEPTED_KEYTYPES ; do
verbose "key type $k"
+ hka=$k
+ if [ $k = "ssh-rsa" ]; then
+ hka="rsa-sha2-512"
+ fi
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
- echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy
+ echo "HostKeyAlgorithms $hka" >> $OBJ/sshd_proxy
echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy
- opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"
+ opts="-oHostKeyAlgorithms=$hka -F $OBJ/ssh_proxy"
( 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
done
SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com' | maybe_filter_sk`
+SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
# Prepare sshd_proxy for certificates.
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
HOSTKEYALGS=""
-for k in $SSH_CERTTYPES ; do
+for k in $SSH_ACCEPTED_CERTTYPES ; do
test -z "$HOSTKEYALGS" || HOSTKEYALGS="${HOSTKEYALGS},"
HOSTKEYALGS="${HOSTKEYALGS}${k}"
done
-for k in $SSH_KEYTYPES ; do
+for k in $SSH_ACCEPTED_KEYTYPES ; do
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
( printf '@cert-authority localhost-with-alias ' ;
cat $OBJ/agent-ca.pub) > $OBJ/known_hosts
-for k in $SSH_CERTTYPES ; do
+for k in $SSH_ACCEPTED_CERTTYPES ; do
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 14f7671a..ad3f560f 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
const struct ssh_conn_info *cinfo)
{
char *myproposal[PROPOSAL_MAX];
- char *all_key, *hkalgs = NULL;
+ char *all_key, *hkalgs = NULL, *filtered_algs = NULL;
int r, use_known_hosts_order = 0;
#if defined(GSSAPI) && defined(WITH_OPENSSL)
@@ -257,10 +257,22 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
if (use_known_hosts_order)
hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);
+ filtered_algs = hkalgs ? match_filter_allowlist(hkalgs, options.pubkey_accepted_algos)
+ : match_filter_allowlist(options.hostkeyalgorithms,
+ options.pubkey_accepted_algos);
+ if (filtered_algs == NULL) {
+ if (hkalgs)
+ fatal_f("No match between algorithms for %s (host %s) and pubkey accepted algorithms %s",
+ hkalgs, host, options.pubkey_accepted_algos);
+ else
+ fatal_f("No match between host key algorithms %s and pubkey accepted algorithms %s",
+ options.hostkeyalgorithms, options.pubkey_accepted_algos);
+ }
+
kex_proposal_populate_entries(ssh, myproposal,
options.kex_algorithms, options.ciphers, options.macs,
compression_alg_list(options.compression),
- hkalgs ? hkalgs : options.hostkeyalgorithms);
+ filtered_algs);
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {
@@ -304,6 +316,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
#endif
free(hkalgs);
+ free(filtered_algs);
/* start key exchange */
if ((r = kex_setup(ssh, myproposal)) != 0)
--
2.49.0

View file

@ -1,616 +0,0 @@
From be23afbab800c9b5ffea56b3f410a04156c08df2 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 45/50] 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 8c9a29fa..ea0a0b09 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 71fbe5cb..ce6a7b81 100644
--- a/kex.c
+++ b/kex.c
@@ -1614,3 +1614,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 6a55aadf..48f3bb87 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 */
@@ -311,6 +314,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 0faab21b..32e1de51 100644
--- a/kexdh.c
+++ b/kexdh.c
@@ -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 @@ 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= ");
@@ -100,24 +107,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 efb2e55a..d92ba54f 100644
--- a/kexecdh.c
+++ b/kexecdh.c
@@ -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 @@ 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;
}
@@ -101,11 +137,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;
}
@@ -140,11 +172,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) {
@@ -153,45 +195,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.49.0

View file

@ -1,334 +0,0 @@
From e4ca3b9dba1cc832a9974493c91207d42e218a68 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 46/50] 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 | 32 +++++++++++++++++---------
serverloop.c | 6 ++++-
ssh-rsa.c | 3 ++-
sshconnect2.c | 8 +++++++
sshd-session.c | 21 +++++++++++++++++
11 files changed, 90 insertions(+), 24 deletions(-)
diff --git a/compat.c b/compat.c
index b59f0bfc..4e611dc3 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 1a19060f..2e6db5bf 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 fbc35782..19cb058e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -747,11 +747,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");
@@ -809,18 +810,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 caf8f57f..09016aea 100644
--- a/regress/unittests/kex/test_kex.c
+++ b/regress/unittests/kex/test_kex.c
@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype, int bits)
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);
diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c
index 3babe604..cc80fe97 100644
--- a/regress/unittests/sshkey/test_file.c
+++ b/regress/unittests/sshkey/test_file.c
@@ -109,6 +109,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);
@@ -116,7 +117,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 0aff7c9b..951122e1 100644
--- a/regress/unittests/sshkey/test_fuzz.c
+++ b/regress/unittests/sshkey/test_fuzz.c
@@ -338,13 +338,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 5bf4b65c..6d0a35bb 100644
--- a/regress/unittests/sshkey/test_sshkey.c
+++ b/regress/unittests/sshkey/test_sshkey.c
@@ -61,6 +61,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);
@@ -102,8 +105,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);
@@ -120,16 +124,22 @@ 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 cp in RHEL, permitted in Fedora */
+ int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 0) : 0;
+ if (k && (sshkey_type_plain(k->type) == KEY_DSA || sshkey_type_plain(k->type) == KEY_DSA_CERT))
+ expected = sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 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);
}
@@ -526,7 +536,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 40ddfb04..9c5b1567 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -80,6 +80,7 @@
#include "auth-options.h"
#include "serverloop.h"
#include "ssherr.h"
+#include "compat.h"
extern ServerOptions options;
@@ -699,7 +700,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 6c2f771a..8dd4ab01 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -509,7 +509,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 ad3f560f..3941e089 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 a808ac9a..c3349a8a 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1316,6 +1316,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.49.0

View file

@ -1,25 +0,0 @@
From 497de886faaddec60b7ad1013396c7d4f3145968 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 47/50] openssh-9.6p1-pam-rhost
---
auth-pam.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/auth-pam.c b/auth-pam.c
index a042c3c8..a321e0d3 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -741,7 +741,7 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt)
sshpam_laddr = get_local_ipaddr(
ssh_packet_get_connection_in(ssh));
}
- if (sshpam_rhost != NULL) {
+ if (sshpam_rhost != NULL && strcmp(sshpam_rhost, "UNKNOWN") != 0) {
debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost);
sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST,
sshpam_rhost);
--
2.49.0

View file

@ -1,25 +0,0 @@
From b97b1040bc0918fe9be89cdb482d046270e92d9c Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 48/50] 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 a43b2a27..9d5da2a6 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.49.0

View file

@ -1,398 +0,0 @@
From 0a621a2ccb8444e4c6da906b0e112e0522658122 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 49/50] openssh-9.9p1-openssl-mlkem
---
kex-names.c | 20 +++
kexmlkem768x25519.c | 291 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 311 insertions(+)
diff --git a/kex-names.c b/kex-names.c
index cd3902ad..36a953ab 100644
--- a/kex-names.c
+++ b/kex-names.c
@@ -108,6 +108,19 @@ static const struct kexalg gss_kexalgs[] = {
{ NULL, 0, -1, -1},
};
+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,6 +129,9 @@ kex_alg_list_internal(char sep, const struct kexalg *algs)
const struct kexalg *k;
for (k = algs; k->name != NULL; k++) {
+ if (strcmp(k->name, KEX_MLKEM768X25519_SHA256) == 0
+ && !is_mlkem768_available())
+ continue;
if (ret != NULL)
ret[rlen++] = sep;
nlen = strlen(k->name);
@@ -147,6 +163,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 2b5d3960..670049dc 100644
--- a/kexmlkem768x25519.c
+++ b/kexmlkem768x25519.c
@@ -48,10 +48,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;
@@ -86,6 +203,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
@@ -93,6 +240,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;
@@ -185,12 +333,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;
@@ -258,6 +491,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.49.0

View file

@ -1,25 +0,0 @@
From fd32e753ae7f3b314712e6aa8b2bed3c1fca1ef5 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Fri, 16 May 2025 14:53:54 +0200
Subject: [PATCH 50/51] 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 798bf9b6..dfb6ac72 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1377,6 +1377,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.49.0

View file

@ -1,27 +0,0 @@
From 4965cdbc1ee1e6a0c665797bb8b944d96d3d411f Mon Sep 17 00:00:00 2001
From: Zoltan Fridrich <zfridric@redhat.com>
Date: Wed, 16 Apr 2025 15:11:59 +0200
Subject: [PATCH 51/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 ca1cdb642..aada474e0 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -3582,6 +3582,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.49.0

View file

@ -1,86 +0,0 @@
From 9ed09ef158a113e21be7b3fefa7c5f932632749b Mon Sep 17 00:00:00 2001
From: Zoltan Fridrich <zfridric@redhat.com>
Date: Mon, 5 May 2025 11:52:25 +0200
Subject: [PATCH 52/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 c5669c703..5c402f501 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 abc8b8439..33787a8d4 100644
--- a/ssh.c
+++ b/ssh.c
@@ -110,6 +110,7 @@
#include "ssherr.h"
#include "myproposal.h"
#include "utf8.h"
+#include "hostfile.h"
#ifdef ENABLE_PKCS11
#include "ssh-pkcs11.h"
@@ -1397,6 +1398,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.49.0

View file

@ -1,450 +0,0 @@
From 5d5a66e96ad03132f65371070f4fa475f10207d9 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 10 Jun 2024 23:00:03 +0300
Subject: [PATCH] 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 d92a85809..2cbe20bf3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5004,6 +5004,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 9d5435eda..5c0491cf1 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 e7e4ad046..aab653244 100644
--- a/servconf.c
+++ b/servconf.c
@@ -147,6 +147,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;
@@ -598,7 +599,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,
@@ -694,6 +695,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 },
@@ -703,6 +705,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 },
@@ -1730,6 +1733,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;
@@ -3351,6 +3363,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 7c7e5d434..7c41df417 100644
--- a/servconf.h
+++ b/servconf.h
@@ -181,6 +181,7 @@ typedef struct {
char **allow_groups;
u_int num_deny_groups;
char **deny_groups;
+ char *gss_indicators;
u_int num_subsystems;
char **subsystem_name;
@@ -310,6 +311,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 a894e23c9..59cf46d47 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
@@ -107,6 +113,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 583a01cdb..90ab87edd 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.49.0

View file

@ -1,257 +0,0 @@
From 24c411970682dc67873c36bac05b4b460d68a628 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:29 +0200
Subject: [PATCH 50/50] 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 +-
ssh-agent.c | 1 +
ssh-keygen.c | 3 +++
13 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/auth-krb5.c b/auth-krb5.c
index bae153c9..209a3265 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 3034370c..c357e973 100644
--- a/gss-genr.c
+++ b/gss-genr.c
@@ -168,8 +168,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 0d0f6953..d8517f12 100644
--- a/krl.c
+++ b/krl.c
@@ -1202,6 +1202,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;
@@ -1212,6 +1213,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;
@@ -1223,6 +1225,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 c4a9bd48..2583612c 100644
--- a/loginrec.c
+++ b/loginrec.c
@@ -683,9 +683,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 09722962..cd71c1b2 100644
--- a/misc.c
+++ b/misc.c
@@ -1556,6 +1556,8 @@ sanitise_stdfd(void)
}
if (nullfd > STDERR_FILENO)
close(nullfd);
+ /* coverity[leaked_handle : FALSE]*/
+ /* coverity[leaked_handle : FALSE]*/
}
char *
@@ -2749,6 +2751,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 19cb058e..58fbac9d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -415,7 +415,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)
;
if (pmonitor->m_recvfd >= 0)
@@ -1813,7 +1813,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 346c7fe5..f42792fd 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 26bdc3e0..8e2939b9 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 ea9d293c..9680c38c 100644
--- a/readconf.c
+++ b/readconf.c
@@ -2164,6 +2164,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 8b708cbf..e7e4ad04 100644
--- a/servconf.c
+++ b/servconf.c
@@ -2293,8 +2293,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 9c5b1567..768ee9fa 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -511,7 +511,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 --git a/ssh-agent.c b/ssh-agent.c
index 798bf9b6..0e39dff7 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1593,6 +1593,7 @@ sanitize_pkcs11_provider(const char *provider)
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 --git a/ssh-keygen.c b/ssh-keygen.c
index 792aafde..96b3474d 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -2424,6 +2424,9 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
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;
--
2.49.0

File diff suppressed because it is too large Load diff

View file

@ -1,2 +0,0 @@
#Type Name ID GECOS Home directory Shell
u sshd 74 "Privilege-separated SSH" /usr/share/empty.sshd -

View file

@ -10,6 +10,10 @@
%global _hardened_build 1
# OpenSSH privilege separation requires a user & group ID
%global sshd_uid 74
%global sshd_gid 74
# Build position-independent executables (requires toolchain support)?
%global pie 1
@ -23,175 +27,165 @@
# Do we want libedit support
%global libedit 1
%global openssh_ver 10.0p1
%global openssh_ver 8.4p1
%global openssh_rel 10
Summary: An implementation of the SSH protocol with GSI authentication
Name: gsi-openssh
Version: %{openssh_ver}
Release: 4%{?dist}
Release: %{openssh_rel}%{?dist}
Provides: gsissh = %{version}-%{release}
Obsoletes: gsissh < 5.8p2-2
URL: http://www.openssh.com/portable.html
Source0: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
Source1: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc
Source2: gsisshd.pam
Source3: gpgkey-736060BA.gpg
Source3: DJM-GPG-KEY.gpg
Source7: gsisshd.sysconfig
Source9: gsisshd@.service
Source10: gsisshd.socket
Source11: gsisshd.service
Source12: gsisshd-keygen@.service
Source13: gsisshd-keygen
Source14: gsisshd.tmpfiles
Source15: gsisshd-keygen.target
Source19: %{name}-server-systemd-sysusers.conf
Source20: gsissh-host-keys-migration.sh
Source21: gsissh-host-keys-migration.service
Source99: README.sshd-and-gsisshd
#https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
Patch0001: 0001-openssh-7.8p1-role-mls.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=781634
Patch0002: 0002-openssh-6.6p1-privsep-selinux.patch
Patch0003: 0003-openssh-6.6p1-keycat.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1644
Patch0004: 0004-openssh-6.6p1-allow-ip-opts.patch
#(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925
Patch0005: 0005-openssh-5.9p1-ipv6man.patch
Patch0006: 0006-openssh-5.8p2-sigpipe.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1789
Patch0007: 0007-openssh-7.2p2-x11.patch
Patch0008: 0008-openssh-5.1p1-askpass-progress.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=198332
Patch0009: 0009-openssh-4.3p2-askpass-grab-info.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
Patch0010: 0010-openssh-8.7p1-redhat.patch
# warn users for unsupported UsePAM=no (#757545)
Patch0011: 0011-openssh-7.8p1-UsePAM-warning.patch
# GSSAPI Key Exchange (RFC 4462 + RFC 8732)
# from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master
# and
# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures
# upstream MR:
# https://github.com/openssh-gsskex/openssh-gsskex/pull/21
Patch0012: 0012-openssh-9.6p1-gssapi-keyex.patch
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
Patch0013: 0013-openssh-6.6p1-force_krb.patch
# Improve ccache handling in openssh (#991186, #1199363, #1566494)
# https://bugzilla.mindrot.org/show_bug.cgi?id=2775
Patch0014: 0014-openssh-7.7p1-gssapi-new-unique.patch
# Respect k5login_directory option in krk5.conf (#1328243)
Patch0015: 0015-openssh-7.2p2-k5login_directory.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
Patch0016: 0016-openssh-6.6p1-kuserok.patch
# Use tty allocation for a remote scp (#985650)
Patch0017: 0017-openssh-6.4p1-fromto-remote.patch
# privsep_preauth: use SELinux context from selinux-policy (#1008580)
Patch0018: 0018-openssh-6.6.1p1-selinux-contexts.patch
# log via monitor in chroots without /dev/log (#2681)
Patch0019: 0019-openssh-6.6.1p1-log-in-chroot.patch
# scp file into non-existing directory (#1142223)
Patch0020: 0020-openssh-6.6.1p1-scp-non-existing-directory.patch
# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843)
# CVE-2014-9278
Patch0021: 0021-openssh-6.6p1-GSSAPIEnablek5users.patch
# apply upstream patch and make sshd -T more consistent (#1187521)
Patch0022: 0022-openssh-6.8p1-sshdT-output.patch
# Add sftp option to force mode of created files (#1191055)
Patch0023: 0023-openssh-6.7p1-sftp-force-permission.patch
# make s390 use /dev/ crypto devices -- ignore closefrom
Patch0024: 0024-openssh-7.2p2-s390-closefrom.patch
# Move MAX_DISPLAYS to a configuration option (#1341302)
Patch0025: 0025-openssh-7.3p1-x11-max-displays.patch
# Pass inetd flags for SELinux down to openbsd compat level
Patch0026: 0026-openssh-7.6p1-cleanup-selinux.patch
# Sandbox adjustments for s390 and audit
Patch0027: 0027-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
Patch0028: 0028-openssh-8.0p1-pkcs11-uri.patch
# Unbreak scp between two IPv6 hosts (#1620333)
Patch0029: 0029-openssh-7.8p1-scp-ipv6.patch
# Mention crypto-policies in manual pages (#1668325)
# clarify rhbz#2068423 on the man page of ssh_config
Patch0030: 0030-openssh-8.0p1-crypto-policies.patch
# Use OpenSSL KDF (#1631761)
Patch0031: 0031-openssh-8.0p1-openssl-kdf.patch
# sk-dummy.so built with -fvisibility=hidden does not work
Patch0032: 0032-openssh-8.2p1-visibility.patch
# Do not break X11 without IPv6
Patch0033: 0033-openssh-8.2p1-x11-without-ipv6.patch
# sshd provides PAM an incorrect error code (#1879503)
Patch0034: 0034-openssh-8.0p1-preserve-pam-errors.patch
# Implement kill switch for SCP protocol
Patch0035: 0035-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
Patch0036: 0036-openssh-8.7p1-recursive-scp.patch
# Downstream alias for MinRSABits
Patch0037: 0037-openssh-8.7p1-minrsabits.patch
# downstream only, IBMCA tentative fix
# From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14
Patch0038: 0038-openssh-8.7p1-ibmca.patch
#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
Patch0039: 0039-openssh-7.6p1-audit.patch
Patch200: openssh-7.6p1-audit.patch
# Audit race condition in forked child (#1310684)
Patch0040: 0040-openssh-7.1p2-audit-race-condition.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2049947
Patch0041: 0041-openssh-9.0p1-audit-log.patch
Patch0042: 0042-openssh-7.7p1-fips.patch
# Add missing options from ssh_config into ssh manpage
# upstream bug:
# https://bugzilla.mindrot.org/show_bug.cgi?id=3455
Patch0043: 0043-openssh-8.7p1-ssh-manpage.patch
# Don't propose disallowed algorithms during hostkey negotiation
# upstream MR:
# https://github.com/openssh/openssh-portable/pull/323
Patch0044: 0044-openssh-8.7p1-negotiate-supported-algs.patch
Patch0045: 0045-openssh-9.0p1-evp-fips-kex.patch
Patch0046: 0046-openssh-8.7p1-nohostsha1proof.patch
Patch0047: 0047-openssh-9.6p1-pam-rhost.patch
Patch0048: 0048-openssh-9.9p1-separate-keysign.patch
Patch0049: 0049-openssh-9.9p1-openssl-mlkem.patch
# https://www.openwall.com/lists/oss-security/2025/02/22/1
Patch0050: 0050-openssh-9.9p2-error_processing.patch
# https://github.com/openssh/openssh-portable/pull/564
Patch0051: 0051-Provide-better-error-for-non-supported-private-keys.patch
# https://github.com/openssh/openssh-portable/pull/567
Patch0052: 0052-Ignore-bad-hostkeys-in-known_hosts-file.patch
# https://github.com/openssh/openssh-portable/pull/500
Patch0053: 0053-support-authentication-indicators-in-GSSAPI.patch
Patch201: openssh-7.1p2-audit-race-condition.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=2581
Patch1000: 1000-openssh-coverity.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
Patch400: openssh-7.8p1-role-mls.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=781634
Patch404: openssh-6.6p1-privsep-selinux.patch
#?
Patch502: openssh-6.6p1-keycat.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1644
Patch601: openssh-6.6p1-allow-ip-opts.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1893 (WONTFIX)
Patch604: openssh-6.6p1-keyperm.patch
#(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925
Patch606: openssh-5.9p1-ipv6man.patch
#?
Patch607: openssh-5.8p2-sigpipe.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1789
Patch609: openssh-7.2p2-x11.patch
#?
Patch700: openssh-7.7p1-fips.patch
#?
Patch702: openssh-5.1p1-askpass-progress.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=198332
Patch703: openssh-4.3p2-askpass-grab-info.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
Patch707: openssh-7.7p1-redhat.patch
# warn users for unsupported UsePAM=no (#757545)
Patch711: openssh-7.8p1-UsePAM-warning.patch
# make aes-ctr ciphers use EVP engines such as AES-NI from OpenSSL
Patch712: openssh-6.3p1-ctr-evp-fast.patch
# add cavs test binary for the aes-ctr
Patch713: openssh-6.6p1-ctr-cavstest.patch
# add SSH KDF CAVS test driver
Patch714: openssh-6.7p1-kdf-cavs.patch
# GSSAPI Key Exchange (RFC 4462 + RFC 8732)
# from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master
Patch800: openssh-8.0p1-gssapi-keyex.patch
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
Patch801: openssh-6.6p1-force_krb.patch
# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843)
# CVE-2014-9278
Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch
# 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)
Patch922: openssh-6.8p1-sshdT-output.patch
# Add sftp option to force mode of created files (#1191055)
Patch926: openssh-6.7p1-sftp-force-permission.patch
# make s390 use /dev/ crypto devices -- ignore closefrom
Patch939: openssh-7.2p2-s390-closefrom.patch
# Move MAX_DISPLAYS to a configuration option (#1341302)
Patch944: openssh-7.3p1-x11-max-displays.patch
# Help systemd to track the running service
Patch948: openssh-7.4p1-systemd.patch
# Pass inetd flags for SELinux down to openbsd compat level
Patch949: openssh-7.6p1-cleanup-selinux.patch
# Sandbox adjustments for s390 and audit
Patch950: openssh-7.5p1-sandbox.patch
# PKCS#11 URIs (upstream #2817, 2nd iteration)
# https://github.com/Jakuje/openssh-portable/commits/jjelen-pkcs11
# git show > ~/devel/fedora/openssh/openssh-8.0p1-pkcs11-uri.patch
Patch951: openssh-8.0p1-pkcs11-uri.patch
# Unbreak scp between two IPv6 hosts (#1620333)
Patch953: openssh-7.8p1-scp-ipv6.patch
# ssh-copy-id is unmaintained: Aggreagete patches
# https://gitlab.com/phil_hands/ssh-copy-id/-/merge_requests/2
Patch958: openssh-7.9p1-ssh-copy-id.patch
# Mention crypto-policies in manual pages (#1668325)
Patch962: openssh-8.0p1-crypto-policies.patch
# Use OpenSSL high-level API to produce and verify signatures (#1707485)
Patch963: openssh-8.0p1-openssl-evp.patch
# Use OpenSSL KDF (#1631761)
Patch964: openssh-8.0p1-openssl-kdf.patch
# sk-dummy.so built with -fvisibility=hidden does not work
Patch965: openssh-8.2p1-visibility.patch
# Do not break X11 without IPv6
Patch966: openssh-8.2p1-x11-without-ipv6.patch
Patch967: openssh-8.4p1-ssh-copy-id.patch
# https://bugzilla.mindrot.org/show_bug.cgi?id=3232
Patch968: openssh-8.4p1-sandbox-seccomp.patch
# https://bugzilla.mindrot.org/show_bug.cgi?id=3213
Patch969: openssh-8.4p1-debian-compat.patch
# https://ftp.openbsd.org/pub/OpenBSD/patches/6.8/common/015_sshagent.patch.sig
Patch970: openssh-8.4p1-cve-2021-28041.patch
# CVE-2021-41617
Patch978: openssh-8.7p1-upstream-cve-2021-41617.patch
# Fix issue with read-only ssh buffer during gssapi key exchange (#1938224)
# https://github.com/openssh-gsskex/openssh-gsskex/pull/19
Patch97: openssh-8.0p1-sshbuf-readonly.patch
# This is the patch that adds GSI support
# Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream
Patch2000: 2000-openssh-10.0p1-gsissh.patch
Patch98: openssh-8.4p1-gsissh.patch
# This is the HPN patch
# Based on https://github.com/rapier1/hpn-ssh/ tag: hpn-18.7.0
Patch2001: 2001-openssh-10.0p1-hpn-18.7.0.patch
# Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v1%208.4p1/
Patch99: openssh-8.4p1-hpn-15.1-modified.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
License: BSD
Requires: /sbin/nologin
Requires: openssl-libs >= 3.5.0
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: systemd-devel
BuildRequires: systemd-rpm-macros
BuildRequires: gcc make
BuildRequires: p11-kit-devel
BuildRequires: libfido2-devel
BuildRequires: libxcrypt-devel
Recommends: p11-kit
%if %{kerberos5}
@ -224,11 +218,7 @@ Summary: SSH client applications with GSI authentication
Provides: gsissh-clients = %{version}-%{release}
Obsoletes: gsissh-clients < 5.8p2-2
Requires: %{name} = %{version}-%{release}
Requires: crypto-policies >= 20220824-1
%package keysign
Summary: A helper program used for host-based authentication
Requires: %{name} = %{version}-%{release}
Requires: crypto-policies >= 20200610-1
%package server
Summary: SSH server daemon with GSI authentication
@ -237,10 +227,8 @@ Obsoletes: gsissh-server < 5.8p2-2
Requires: %{name} = %{version}-%{release}
Requires(pre): /usr/sbin/useradd
Requires: pam >= 1.0.1-3
Requires: crypto-policies >= 20220824-1
Requires: crypto-policies >= 20200610-1
%{?systemd_requires}
Requires(pre): policycoreutils-python-utils
Requires(postun): policycoreutils-python-utils
%description
SSH (Secure SHell) is a program for logging into and executing
@ -265,11 +253,6 @@ the clients necessary to make encrypted connections to SSH servers.
This version of OpenSSH has been modified to support GSI authentication.
%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
@ -280,18 +263,80 @@ This version of OpenSSH has been modified to support GSI authentication.
%prep
gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%autosetup -T -b 0 -p1 -n openssh-%{version}
%setup -q -n openssh-%{version}
%patch400 -p1 -b .role-mls
%patch404 -p1 -b .privsep-selinux
%patch502 -p1 -b .keycat
%patch601 -p1 -b .ip-opts
%patch604 -p1 -b .keyperm
%patch606 -p1 -b .ipv6man
%patch607 -p1 -b .sigpipe
%patch609 -p1 -b .x11
%patch702 -p1 -b .progress
%patch703 -p1 -b .grab-info
%patch707 -p1 -b .redhat
%patch711 -p1 -b .log-usepam-no
%patch712 -p1 -b .evp-ctr
%patch713 -p1 -b .ctr-cavs
%patch714 -p1 -b .kdf-cavs
%patch800 -p1 -b .gsskex
%patch801 -p1 -b .force_krb
%patch804 -p1 -b .ccache_name
%patch805 -p1 -b .k5login
%patch901 -p1 -b .kuserok
%patch906 -p1 -b .fromto-remote
%patch916 -p1 -b .contexts
%patch918 -p1 -b .log-in-chroot
%patch919 -p1 -b .scp
%patch802 -p1 -b .GSSAPIEnablek5users
%patch922 -p1 -b .sshdt
%patch926 -p1 -b .sftp-force-mode
%patch939 -p1 -b .s390-dev
%patch944 -p1 -b .x11max
%patch948 -p1 -b .systemd
%patch949 -p1 -b .refactor
%patch950 -p1 -b .sandbox
%patch951 -p1 -b .pkcs11-uri
%patch953 -p1 -b .scp-ipv6
%patch958 -p1 -b .ssh-copy-id
%patch962 -p1 -b .crypto-policies
%patch963 -p1 -b .openssl-evp
%patch964 -p1 -b .openssl-kdf
%patch965 -p1 -b .visibility
%patch966 -p1 -b .x11-ipv6
%patch967 -p1 -b .ssh-copy-id
%patch968 -p1 -b .seccomp
%patch969 -p0 -b .debian
%patch970 -p1 -b .cve-2021-28041
%patch978 -p1 -b .cve-2021-41617
%patch200 -p1 -b .audit
%patch201 -p1 -b .audit-race
%patch700 -p1 -b .fips
%patch100 -p1 -b .coverity
%patch97 -p1 -b .sshbuf-ro
%patch98 -p1 -b .gsi
%patch99 -p1 -b .hpn
sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h
sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in
sed 's!/etc/pam.d/sshd!/etc/pam.d/gsisshd!' -i sshd_config_redhat
sed 's!/etc/sysconfig/sshd!/etc/sysconfig/gsisshd!' -i sshd_config
sed 's!/etc/pam.d/sshd!/etc/pam.d/gsisshd!' -i sshd_config
cp -p %{SOURCE99} .
autoreconf
%build
%set_build_flags
CFLAGS="$RPM_OPT_FLAGS"; export CFLAGS
%if %{pie}
%ifarch s390 s390x sparc sparcv9 sparc64
CFLAGS="$CFLAGS -fPIC"
@ -324,11 +369,12 @@ fi
--sysconfdir=%{_sysconfdir}/gsissh \
--libexecdir=%{_libexecdir}/gsissh \
--datadir=%{_datadir}/gsissh \
--with-default-path=%{_libexecdir}/gsissh/bin:/usr/local/bin:/usr/bin \
--with-superuser-path=%{_libexecdir}/gsissh/bin:/usr/local/bin:/usr/bin \
--with-privsep-path=%{_datadir}/empty.sshd \
--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=%{_var}/empty/gsisshd \
--disable-strip \
--without-zlib-version-check \
--with-ssl-engine \
--with-ipaddr-display \
--with-pie=no \
--without-hardening `# The hardening flags are configured by system` \
@ -336,7 +382,6 @@ fi
--with-default-pkcs11-provider=yes \
--with-security-key-builtin=yes \
--with-pam \
--with-pam-service=gsisshd \
%if %{WITH_SELINUX}
--with-selinux --with-audit=linux \
--with-sandbox=seccomp_filter \
@ -366,6 +411,7 @@ mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/gsissh
mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/ssh_config.d
mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/sshd_config.d
mkdir -p -m755 $RPM_BUILD_ROOT%{_libexecdir}/gsissh
mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/gsisshd
%make_install
install -d $RPM_BUILD_ROOT/etc/pam.d/
@ -373,9 +419,8 @@ install -d $RPM_BUILD_ROOT/etc/sysconfig/
install -d $RPM_BUILD_ROOT%{_libexecdir}/gsissh
install -m644 %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/gsisshd
install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/sysconfig/gsisshd
install -m644 ssh_config_redhat $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/ssh_config.d/50-redhat.conf
install -m644 sshd_config_redhat_cp $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/sshd_config.d/40-redhat-crypto-policies.conf
install -m644 sshd_config_redhat $RPM_BUILD_ROOT%{_sysconfdir}/gsissh/sshd_config.d/50-redhat.conf
install -m644 ssh_config_redhat $RPM_BUILD_ROOT/etc/gsissh/ssh_config.d/50-redhat.conf
install -m644 sshd_config_redhat $RPM_BUILD_ROOT/etc/gsissh/sshd_config.d/50-redhat.conf
install -d -m755 $RPM_BUILD_ROOT/%{_unitdir}
install -m644 %{SOURCE9} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd@.service
install -m644 %{SOURCE10} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd.socket
@ -383,56 +428,41 @@ install -m644 %{SOURCE11} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd.service
install -m644 %{SOURCE12} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd-keygen@.service
install -m644 %{SOURCE15} $RPM_BUILD_ROOT/%{_unitdir}/gsisshd-keygen.target
install -m755 %{SOURCE13} $RPM_BUILD_ROOT/%{_libexecdir}/gsissh/sshd-keygen
install -d -m711 ${RPM_BUILD_ROOT}/%{_datadir}/empty.sshd
install -p -D -m 0644 %{SOURCE19} $RPM_BUILD_ROOT%{_sysusersdir}/%{name}-server.conf
# Migration service/script for Fedora 38 change to remove group ownership for standard host keys
# See https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
install -m744 %{SOURCE20} $RPM_BUILD_ROOT/%{_libexecdir}/gsissh/ssh-host-keys-migration.sh
# Pulled-in via a `Wants=` in `gsisshd.service` & `gsisshd@.service`
install -m644 %{SOURCE21} $RPM_BUILD_ROOT/%{_unitdir}/gsissh-host-keys-migration.service
install -d $RPM_BUILD_ROOT/%{_localstatedir}/lib
touch $RPM_BUILD_ROOT/%{_localstatedir}/lib/.gsissh-host-keys-migration
install -m644 -D %{SOURCE14} $RPM_BUILD_ROOT%{_tmpfilesdir}/gsissh.conf
rm $RPM_BUILD_ROOT%{_bindir}/ssh-add
rm $RPM_BUILD_ROOT%{_bindir}/ssh-agent
rm $RPM_BUILD_ROOT%{_bindir}/ssh-keyscan
rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ctr-cavstest
rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-cavs
rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-cavs_driver.pl
rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-keycat
rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-pkcs11-helper
rm $RPM_BUILD_ROOT%{_libexecdir}/gsissh/ssh-sk-helper
rm $RPM_BUILD_ROOT%{_mandir}/man1/ssh-add.1*
rm $RPM_BUILD_ROOT%{_mandir}/man1/ssh-agent.1*
rm $RPM_BUILD_ROOT%{_mandir}/man1/ssh-keyscan.1*
rm $RPM_BUILD_ROOT%{_mandir}/man8/ssh-pkcs11-helper.8*
rm $RPM_BUILD_ROOT%{_mandir}/man8/ssh-sk-helper.8*
for f in $RPM_BUILD_ROOT%{_bindir}/* \
%if "%{_sbindir}" != "%{_bindir}"
$RPM_BUILD_ROOT%{_sbindir}/* \
%endif
$RPM_BUILD_ROOT%{_mandir}/man*/* ; do
mv $f `dirname $f`/gsi`basename $f`
done
# Add scp and hpnscp symlinks in gsisshd's path
mkdir $RPM_BUILD_ROOT%{_libexecdir}/gsissh/bin
ln -nrs $RPM_BUILD_ROOT%{_bindir}/gsiscp \
$RPM_BUILD_ROOT%{_libexecdir}/gsissh/bin/scp
ln -nrs $RPM_BUILD_ROOT%{_bindir}/gsiscp \
$RPM_BUILD_ROOT%{_libexecdir}/gsissh/bin/hpnscp
perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/*
%pre
getent group ssh_keys >/dev/null || groupadd -r ssh_keys || :
%pre server
%sysusers_create_compat %{SOURCE19}
semanage port -a -t ssh_port_t -p tcp 2222 2>/dev/null || :
getent group sshd >/dev/null || groupadd -g %{sshd_uid} -r sshd || :
getent passwd sshd >/dev/null || \
useradd -c "Privilege-separated SSH" -u %{sshd_uid} -g sshd \
-s /sbin/nologin -r -d /var/empty/sshd sshd 2> /dev/null || :
%post server
if [ $1 -gt 1 ]; then
# In the case of an upgrade (never true on OSTree systems) run the migration
# script for Fedora 38 to remove group ownership for host keys.
%{_libexecdir}/gsissh/ssh-host-keys-migration.sh
# Prevent the systemd unit that performs the same service (useful for
# OSTree systems) from running.
touch /var/lib/.gsissh-host-keys-migration
fi
%systemd_post gsisshd.service gsisshd.socket
%preun server
@ -440,9 +470,6 @@ fi
%postun server
%systemd_postun_with_restart gsisshd.service
if [ $1 -eq 0 ]; then
semanage port -d -t ssh_port_t -p tcp 2222 2>/dev/null || :
fi
%files
%license LICENCE
@ -452,6 +479,8 @@ fi
%attr(0755,root,root) %{_bindir}/gsissh-keygen
%attr(0644,root,root) %{_mandir}/man1/gsissh-keygen.1*
%attr(0755,root,root) %dir %{_libexecdir}/gsissh
%attr(2755,root,ssh_keys) %{_libexecdir}/gsissh/ssh-keysign
%attr(0644,root,root) %{_mandir}/man8/gsissh-keysign.8*
%files clients
%attr(0755,root,root) %{_bindir}/gsissh
@ -463,22 +492,11 @@ fi
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/ssh_config.d/50-redhat.conf
%attr(0644,root,root) %{_mandir}/man5/gsissh_config.5*
%attr(0755,root,root) %{_bindir}/gsisftp
%attr(0755,root,root) %{_libexecdir}/gsissh/ssh-sk-helper
%attr(0644,root,root) %{_mandir}/man1/gsisftp.1*
%attr(0644,root,root) %{_mandir}/man8/gsissh-sk-helper.8*
%attr(0755,root,root) %dir %{_libexecdir}/gsissh/bin
%{_libexecdir}/gsissh/bin/scp
%{_libexecdir}/gsissh/bin/hpnscp
%files keysign
%attr(4555,root,root) %{_libexecdir}/gsissh/ssh-keysign
%attr(0644,root,root) %{_mandir}/man8/gsissh-keysign.8*
%files server
%dir %attr(0711,root,root) %{_datadir}/empty.sshd
%dir %attr(0711,root,root) %{_var}/empty/gsisshd
%attr(0755,root,root) %{_sbindir}/gsisshd
%attr(0755,root,root) %{_libexecdir}/gsissh/sshd-session
%attr(0755,root,root) %{_libexecdir}/gsissh/sshd-auth
%attr(0755,root,root) %{_libexecdir}/gsissh/sftp-server
%attr(0755,root,root) %{_libexecdir}/gsissh/sshd-keygen
%attr(0644,root,root) %{_mandir}/man5/gsisshd_config.5*
@ -487,7 +505,6 @@ fi
%attr(0644,root,root) %{_mandir}/man8/gsisftp-server.8*
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/gsissh/sshd_config
%dir %attr(0700,root,root) %{_sysconfdir}/gsissh/sshd_config.d/
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/gsissh/sshd_config.d/40-redhat-crypto-policies.conf
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/gsissh/sshd_config.d/50-redhat.conf
%attr(0644,root,root) %config(noreplace) /etc/pam.d/gsisshd
%attr(0640,root,root) %config(noreplace) /etc/sysconfig/gsisshd
@ -496,173 +513,30 @@ fi
%attr(0644,root,root) %{_unitdir}/gsisshd.socket
%attr(0644,root,root) %{_unitdir}/gsisshd-keygen@.service
%attr(0644,root,root) %{_unitdir}/gsisshd-keygen.target
%attr(0644,root,root) %{_sysusersdir}/%{name}-server.conf
%attr(0644,root,root) %{_unitdir}/gsissh-host-keys-migration.service
%attr(0744,root,root) %{_libexecdir}/gsissh/ssh-host-keys-migration.sh
%ghost %attr(0644,root,root) %{_localstatedir}/lib/.gsissh-host-keys-migration
%attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf
%changelog
* Mon Sep 01 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 10.0p1-4
- Based on openssh-10.0p1-6.fc44
* Sat Oct 23 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-10
- Based on openssh-8.4p1-8.fc33
* Mon Sep 01 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 10.0p1-3
- Based on openssh-10.0p1-4.fc43
* Mon Jun 21 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-9
- Based on openssh-8.4p1-7.fc33
* Thu Jul 24 2025 Fedora Release Engineering <releng@fedoraproject.org> - 10.0p1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Tue May 25 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-8
- Based on openssh-8.4p1-6.fc33
* Mon Jun 16 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 10.0p1-1
- Based on openssh-10.0p1-3.fc43
* Sun Apr 20 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.9p1-6
- Based on openssh-9.9p1-15.fc43
* Wed Mar 05 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.9p1-5
- Based on openssh-9.9p1-11.fc43
* Wed Mar 05 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.9p1-4
- Based on openssh-9.9p1-9.fc42
* Wed Feb 05 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.9p1-3
- Based on openssh-9.9p1-8.fc42
* Wed Feb 05 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.9p1-2
- Based on openssh-9.9p1-7.fc42 / openssh-9.9p1-2.fc41
* Sat Feb 01 2025 Björn Esser <besser82@fedoraproject.org> - 9.9p1-1.1
- Add explicit BR: libxcrypt-devel
* Mon Jan 20 2025 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.9p1-1
- Based on openssh-9.9p1-5.fc42 / openssh-9.9p1-1.fc41
* Fri Jan 17 2025 Fedora Release Engineering <releng@fedoraproject.org> - 9.8p1-2.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Wed Oct 02 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.8p1-2
- Based on openssh-9.8p1-4.fc42
* Fri Sep 27 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.8p1-1
- Based on openssh-9.8p1-3.fc41.1
* Thu Jul 18 2024 Fedora Release Engineering <releng@fedoraproject.org> - 9.6p1-3.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Fri Jul 12 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.6p1-3
- Add scp and hpnscp symlinks in gsisshd's path
* Sat Jul 06 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.6p1-2
- Based on openssh-9.6p1-1.fc41.13
* Sat Jul 06 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.6p1-1
- Based on openssh-9.6p1-1.fc40.4
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 9.3p1-7.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Sat Jan 20 2024 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.3p1-7
- Based on openssh-9.3p1-13.fc40.1
* Sat Jan 20 2024 Fedora Release Engineering <releng@fedoraproject.org> - 9.3p1-6.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Tue Oct 24 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.3p1-6
- Based on openssh-9.3p1-13.fc40
- Drop patch openssh-8.0p1-sshbuf-readonly.patch (now included in
openssh-8.0p1-gssapi-keyex.patch)
* Tue Oct 17 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.3p1-5
- Based on openssh-9.3p1-12.fc40
* Tue Oct 17 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.3p1-4
- Based on openssh-9.3p1-9.fc39
* Fri Aug 11 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.3p1-3
- Based on openssh-9.3p1-8.fc39
* Sun Jul 23 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.3p1-2
- Based on openssh-9.3p1-5.fc39.1
* Wed Jul 19 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.3p1-1
- Based on openssh-9.3p1-3.fc39
- Fix keyex patch
* Sun Apr 16 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.0p1-6
- Based on openssh-9.0p1-17.fc39
* Wed Apr 12 2023 Florian Weimer <fweimer@redhat.com> - 9.0p1-5.1
- C99 compatiblity fixes
* Sat Mar 11 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.0p1-5
- Based on openssh-9.0p1-12.fc38
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 9.0p1-4.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Tue Jan 10 2023 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.0p1-4
- Based on openssh-9.0p1-9.fc38
* Wed Nov 09 2022 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.0p1-3
- Based on openssh-9.0p1-7.fc38
* Tue Oct 04 2022 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.0p1-2
- Based on openssh-9.0p1-5.fc38
* Tue Aug 30 2022 Mattias Ellert <mattias.ellert@physics.uu.se> - 9.0p1-1
- Based on openssh-9.0p1-3.fc38
* Tue Aug 30 2022 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.8p1-3
- Based on openssh-8.8p1-6.fc37
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 8.8p1-2.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Sun May 08 2022 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.8p1-2
- Based on openssh-8.8p1-2.fc37
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 8.8p1-1.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Wed Dec 01 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.8p1-1
- Based on openssh-8.8p1-1.fc36
* Sun Oct 24 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.7p1-2
- Based on openssh-8.7p1-3.fc36
* Sun Oct 24 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.7p1-1
- Based on openssh-8.7p1-2.fc35
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 8.6p1-3.2
- Rebuilt with OpenSSL 3.0.0
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 8.6p1-3.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon Jun 21 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.6p1-3
- Based on openssh-8.6p1-5.fc35
* Mon Jun 21 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.6p1-2
- Based on openssh-8.6p1-4.fc34
* Sat May 22 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.6p1-1
- Based on openssh-8.6p1-3.fc35
* Tue Mar 30 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.5p1-3
* Tue Mar 30 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-7
- Disable MTAES
* Tue Mar 16 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.5p1-1
- Based on openssh-8.5p1-1.fc34
* Tue Mar 16 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-6
- Fix issue with read-only ssh buffer during gssapi key exchange
- Clean up HPN patch
* Thu Mar 11 2021 Frank Scheiner <scheiner@hlrs.de> - 8.4p1-5
- Add HPN patch
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 8.4p1-4.1
- Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
* Fri Feb 05 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-4
- Based on openssh-8.4p1-5.fc34
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 8.4p1-3.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
- Based on openssh-8.4p1-5.fc33
* Wed Dec 09 2020 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-3
- Based on openssh-8.4p1-4.fc33

View file

@ -1,15 +0,0 @@
[Unit]
Description=Update gsissh host key permissions
Documentation=https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
Before=gsisshd.service
After=gsissh-keygen.target
ConditionPathExists=!/var/lib/.gsissh-host-keys-migration
[Service]
Type=oneshot
ExecStart=-/usr/libexec/gsissh/ssh-host-keys-migration.sh
ExecStart=touch /var/lib/.gsissh-host-keys-migration
RemainAfterExit=yes
[Install]
WantedBy=gsisshd.service

View file

@ -1,36 +0,0 @@
#!/usr/bin/bash
set -eu -o pipefail
# Detect existing non-conforming host keys and perform the permissions migration
# https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
#
# Example output looks like:
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Permissions 0640 for '/etc/ssh/ssh_host_rsa_key' are too open.
# It is required that your private key files are NOT accessible by others.
# This private key will be ignored.
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Permissions 0640 for '/etc/ssh/ssh_host_ecdsa_key' are too open.
# It is required that your private key files are NOT accessible by others.
# This private key will be ignored.
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Permissions 0640 for '/etc/ssh/ssh_host_ed25519_key' are too open.
# It is required that your private key files are NOT accessible by others.
# This private key will be ignored.
# gsisshd: no hostkeys available -- exiting.
#
output="$(gsisshd -T 2>&1 || true)" # expected to fail
while read line; do
if [[ $line =~ ^Permissions\ [0-9]+\ for\ \'(.*)\'\ are\ too\ open. ]]; then
keyfile=${BASH_REMATCH[1]}
echo $line
echo -e "\t-> changing permissions on $keyfile"
chmod --verbose g-r $keyfile
chown --verbose root:root $keyfile
fi
done <<< "$output"

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,12 +25,13 @@ 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
# sanitize permissions
/usr/bin/chmod 600 $KEY
/usr/bin/chgrp ssh_keys $KEY
/usr/bin/chmod 640 $KEY
/usr/bin/chmod 644 $KEY.pub
if [[ -x /usr/sbin/restorecon ]]; then
/usr/sbin/restorecon $KEY{,.pub}

View file

@ -4,9 +4,6 @@ ConditionFileNotEmpty=|!/etc/gsissh/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/gsisshd
ExecStart=/usr/libexec/gsissh/sshd-keygen %i

View file

@ -3,15 +3,9 @@ Description=gsissh server daemon
Documentation=man:gsisshd(8) man:gsisshd_config(5)
After=network.target gsisshd-keygen.target
Wants=gsisshd-keygen.target
# Migration for Fedora 38 change to remove group ownership for standard host keys
# See https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
Wants=gsissh-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/gsisshd
ExecStart=/usr/sbin/gsisshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID

View file

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

1
gsisshd.tmpfiles Normal file
View file

@ -0,0 +1 @@
d /var/empty/gsisshd 711 root root -

View file

@ -3,16 +3,8 @@ Description=gsissh per-connection server daemon
Documentation=man:gsisshd(8) man:gsisshd_config(5)
Wants=gsisshd-keygen.target
After=gsisshd-keygen.target
# Migration for Fedora 38 change to remove group ownership for standard host keys
# See https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
Wants=gsissh-host-keys-migration.service
[Service]
# 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/gsisshd
ExecStart=-/usr/sbin/gsisshd -i $OPTIONS
ExecStart=-/usr/sbin/gsisshd -i $OPTIONS -o "AuthorizedKeysFile ${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys"
StandardInput=socket
ImportCredential=ssh.ephemeral-authorized_keys-all

View file

@ -0,0 +1,19 @@
diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-7.4p1/contrib/gnome-ssh-askpass2.c
--- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info 2016-12-23 13:31:22.645213115 +0100
+++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:40.997216691 +0100
@@ -65,9 +65,12 @@ report_failed_grab (GtkWidget *parent_wi
err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
- "Could not grab %s. "
- "A malicious client may be eavesdropping "
- "on your session.", what);
+ "SSH password dialog could not grab the %s input.\n"
+ "This might be caused by application such as screensaver, "
+ "however it could also mean that someone may be eavesdropping "
+ "on your session.\n"
+ "Either close the application which grabs the %s or "
+ "log out and log in again to prevent this from happening.", what, what);
gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
gtk_dialog_run(GTK_DIALOG(err));

View file

@ -1,17 +1,7 @@
From 6b2a33044583e892badb9ac86cd2c6252b1a532f 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/50] 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 a62f9815..cb7152dc 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 a62f9815..cb7152dc 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 a62f9815..cb7152dc 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 a62f9815..cb7152dc 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 a62f9815..cb7152dc 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,9 +58,9 @@ index a62f9815..cb7152dc 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);
G_CALLBACK(check_none), dialog);
}
+
+ hbox = gtk_hbox_new(FALSE, 0);
@ -91,6 +81,3 @@ index a62f9815..cb7152dc 100644
}
/* Grab focus */
--
2.49.0

View file

@ -0,0 +1,12 @@
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,8 @@ main(int argc, char **argv)
fdlim_set(maxfd);
fdcon = xcalloc(maxfd, sizeof(con));
+ signal(SIGPIPE, SIG_IGN);
+
read_wait_nfdset = howmany(maxfd, NFDBITS);
read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask));

View file

@ -1,18 +1,7 @@
From 388be633842a9f3e4b0a76fe40cf7035912a913a 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/50] openssh-5.9p1-ipv6man
---
ssh.1 | 2 ++
sshd.8 | 2 ++
2 files changed, 4 insertions(+)
diff --git a/ssh.1 b/ssh.1
index 697f4e42..db92ac9a 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 697f4e42..db92ac9a 100644
.Sh SEE ALSO
.Xr scp 1 ,
.Xr sftp 1 ,
diff --git a/sshd.8 b/sshd.8
index 08ebf53a..2aa73271 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 08ebf53a..2aa73271 100644
.Sh SEE ALSO
.Xr scp 1 ,
.Xr sftp 1 ,
--
2.49.0

View file

@ -0,0 +1,101 @@
diff -up openssh-5.9p1/cipher-ctr.c.ctr-evp openssh-5.9p1/cipher-ctr.c
--- openssh-5.9p1/cipher-ctr.c.ctr-evp 2012-01-11 09:24:06.000000000 +0100
+++ openssh-5.9p1/cipher-ctr.c 2012-01-11 15:54:04.675956600 +0100
@@ -38,7 +38,7 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, in
struct ssh_aes_ctr_ctx
{
- AES_KEY aes_ctx;
+ EVP_CIPHER_CTX ecbctx;
u_char aes_counter[AES_BLOCK_SIZE];
};
@@ -63,21 +63,42 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char
{
struct ssh_aes_ctr_ctx *c;
size_t n = 0;
- u_char buf[AES_BLOCK_SIZE];
+ u_char ctrbuf[AES_BLOCK_SIZE*256];
+ u_char buf[AES_BLOCK_SIZE*256];
if (len == 0)
return (1);
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
return (0);
- while ((len--) > 0) {
+ for (; len > 0; len -= sizeof(u_int)) {
+ u_int r,a,b;
+
if (n == 0) {
- AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
- ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
+ int outl, i, buflen;
+
+ buflen = MIN(len, sizeof(ctrbuf));
+
+ for(i = 0; i < buflen; i += AES_BLOCK_SIZE) {
+ memcpy(&ctrbuf[i], c->aes_counter, AES_BLOCK_SIZE);
+ ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
+ }
+
+ EVP_EncryptUpdate(&c->ecbctx, buf, &outl,
+ ctrbuf, buflen);
}
- *(dest++) = *(src++) ^ buf[n];
- n = (n + 1) % AES_BLOCK_SIZE;
+
+ memcpy(&a, src, sizeof(a));
+ memcpy(&b, &buf[n], sizeof(b));
+ r = a ^ b;
+ memcpy(dest, &r, sizeof(r));
+ src += sizeof(a);
+ dest += sizeof(r);
+
+ n = (n + sizeof(b)) % sizeof(buf);
}
+ memset(ctrbuf, '\0', sizeof(ctrbuf));
+ memset(buf, '\0', sizeof(buf));
return (1);
}
@@ -91,9 +112,28 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co
c = xmalloc(sizeof(*c));
EVP_CIPHER_CTX_set_app_data(ctx, c);
}
- if (key != NULL)
- AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
- &c->aes_ctx);
+
+ EVP_CIPHER_CTX_init(&c->ecbctx);
+
+ if (key != NULL) {
+ const EVP_CIPHER *cipher;
+ switch(EVP_CIPHER_CTX_key_length(ctx)*8) {
+ case 128:
+ cipher = EVP_aes_128_ecb();
+ break;
+ case 192:
+ cipher = EVP_aes_192_ecb();
+ break;
+ case 256:
+ cipher = EVP_aes_256_ecb();
+ break;
+ default:
+ fatal("ssh_aes_ctr_init: wrong aes key length");
+ }
+ if(!EVP_EncryptInit_ex(&c->ecbctx, cipher, NULL, key, NULL))
+ fatal("ssh_aes_ctr_init: cannot initialize aes encryption");
+ EVP_CIPHER_CTX_set_padding(&c->ecbctx, 0);
+ }
if (iv != NULL)
memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
return (1);
@@ -105,6 +145,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
struct ssh_aes_ctr_ctx *c;
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+ EVP_CIPHER_CTX_cleanup(&c->ecbctx);
memset(c, 0, sizeof(*c));
free(c);
EVP_CIPHER_CTX_set_app_data(ctx, NULL);

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

@ -0,0 +1,263 @@
diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c
--- openssh-7.4p1/log.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/log.c 2016-12-23 15:14:33.330168088 +0100
@@ -250,6 +250,11 @@ debug3(const char *fmt,...)
void
log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
{
+ log_init_handler(av0, level, facility, on_stderr, 1);
+}
+
+void
+log_init_handler(char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) {
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
struct syslog_data sdata = SYSLOG_DATA_INIT;
#endif
@@ -273,8 +278,10 @@ log_init(char *av0, LogLevel level, Sysl
exit(1);
}
- log_handler = NULL;
- log_handler_ctx = NULL;
+ if (reset_handler) {
+ log_handler = NULL;
+ log_handler_ctx = NULL;
+ }
log_on_stderr = on_stderr;
if (on_stderr)
diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h
--- openssh-7.4p1/log.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/log.h 2016-12-23 15:14:33.330168088 +0100
@@ -49,6 +49,7 @@ typedef enum {
typedef void (log_handler_fn)(LogLevel, const char *, void *);
void log_init(char *, LogLevel, SyslogFacility, int);
+void log_init_handler(char *, LogLevel, SyslogFacility, int, int);
LogLevel log_level_get(void);
int log_change_level(LogLevel);
int log_is_on_stderr(void);
diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c
--- openssh-7.4p1/monitor.c.log-in-chroot 2016-12-23 15:14:33.311168085 +0100
+++ openssh-7.4p1/monitor.c 2016-12-23 15:16:42.154193100 +0100
@@ -307,6 +307,8 @@ monitor_child_preauth(Authctxt *_authctx
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;
@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p
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);
@@ -472,7 +476,7 @@ monitor_read_log(struct monitor *pmonito
if (log_level_name(level) == NULL)
fatal("%s: invalid log level %u (corrupted message?)",
__func__, level);
- do_log2(level, "%s [preauth]", msg);
+ do_log2(level, "%s [%s]", msg, pmonitor->m_state);
sshbuf_free(logmsg);
free(msg);
@@ -1719,13 +1723,28 @@ monitor_init(void)
mon = xcalloc(1, sizeof(*mon));
monitor_openfds(mon, 1);
+ mon->m_state = "";
+
return mon;
}
void
-monitor_reinit(struct monitor *mon)
+monitor_reinit(struct monitor *mon, const char *chroot_dir)
{
- monitor_openfds(mon, 0);
+ struct stat dev_log_stat;
+ char *dev_log_path;
+ int do_logfds = 0;
+
+ if (chroot_dir != NULL) {
+ xasprintf(&dev_log_path, "%s/dev/log", chroot_dir);
+
+ if (stat(dev_log_path, &dev_log_stat) != 0) {
+ debug("%s: /dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", __func__, chroot_dir);
+ do_logfds = 1;
+ }
+ free(dev_log_path);
+ }
+ monitor_openfds(mon, do_logfds);
}
#ifdef GSSAPI
diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h
--- openssh-7.4p1/monitor.h.log-in-chroot 2016-12-23 15:14:33.330168088 +0100
+++ openssh-7.4p1/monitor.h 2016-12-23 15:16:28.372190424 +0100
@@ -83,10 +83,11 @@ struct monitor {
int m_log_sendfd;
struct kex **m_pkex;
pid_t m_pid;
+ char *m_state;
};
struct monitor *monitor_init(void);
-void monitor_reinit(struct monitor *);
+void monitor_reinit(struct monitor *, const char *);
struct Authctxt;
void monitor_child_preauth(struct ssh *, struct monitor *);
diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c
--- openssh-7.4p1/session.c.log-in-chroot 2016-12-23 15:14:33.319168086 +0100
+++ openssh-7.4p1/session.c 2016-12-23 15:18:18.742211853 +0100
@@ -160,6 +160,7 @@ login_cap_t *lc;
static int is_child = 0;
static int in_chroot = 0;
+static int have_dev_log = 1;
/* File containing userauth info, if ExposeAuthInfo set */
static char *auth_info_file = NULL;
@@ -619,6 +620,7 @@ do_exec(Session *s, const char *command)
int ret;
const char *forced = NULL, *tty = NULL;
char session_type[1024];
+ struct stat dev_log_stat;
if (options.adm_forced_command) {
original_command = command;
@@ -676,6 +678,10 @@ do_exec(Session *s, const char *command)
tty += 5;
}
+ if (lstat("/dev/log", &dev_log_stat) != 0) {
+ have_dev_log = 0;
+ }
+
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d",
session_type,
tty == NULL ? "" : " on ",
@@ -1486,14 +1492,6 @@ child_close_fds(void)
/* Stop directing logs to a high-numbered fd before we close it */
log_redirect_stderr_to(NULL);
-
- /*
- * Close any extra open file descriptors so that we don't have them
- * hanging around in clients. Note that we want to do this after
- * initgroups, because at least on Solaris 2.3 it leaves file
- * descriptors open.
- */
- closefrom(STDERR_FILENO + 1);
}
/*
@@ -1629,8 +1627,6 @@ do_child(Session *s, const char *command
exit(1);
}
- closefrom(STDERR_FILENO + 1);
-
do_rc_files(ssh, s, shell);
/* restore SIGPIPE for child */
@@ -1653,9 +1649,17 @@ do_child(Session *s, const char *command
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));
}
+ /*
+ * Close any extra open file descriptors so that we don't have them
+ * hanging around in clients. Note that we want to do this after
+ * initgroups, because at least on Solaris 2.3 it leaves file
+ * descriptors open.
+ */
+ closefrom(STDERR_FILENO + 1);
+
fflush(NULL);
/* Get the last component of the shell name. */
diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h
--- openssh-7.4p1/sftp.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/sftp.h 2016-12-23 15:14:33.331168088 +0100
@@ -97,5 +97,5 @@
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-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c
--- openssh-7.4p1/sftp-server.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/sftp-server.c 2016-12-23 15:14:33.331168088 +0100
@@ -1497,7 +1497,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)
{
fd_set *rset, *wset;
int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0;
@@ -1511,7 +1511,7 @@ sftp_server_main(int argc, char **argv,
extern char *__progname;
__progname = ssh_get_progname(argv[0]);
- log_init(__progname, log_level, log_facility, log_stderr);
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
pw = pwcopy(user_pw);
@@ -1582,7 +1582,7 @@ sftp_server_main(int argc, char **argv,
}
}
- log_init(__progname, log_level, log_facility, log_stderr);
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
/*
* On platforms where we can, avoid making /proc/self/{mem,maps}
diff -up openssh-7.4p1/sftp-server-main.c.log-in-chroot openssh-7.4p1/sftp-server-main.c
--- openssh-7.4p1/sftp-server-main.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/sftp-server-main.c 2016-12-23 15:14:33.331168088 +0100
@@ -49,5 +49,5 @@ main(int argc, char **argv)
return 1;
}
- return (sftp_server_main(argc, argv, user_pw));
+ return (sftp_server_main(argc, argv, user_pw, 0));
}
diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c
--- openssh-7.4p1/sshd.c.log-in-chroot 2016-12-23 15:14:33.328168088 +0100
+++ openssh-7.4p1/sshd.c 2016-12-23 15:14:33.332168088 +0100
@@ -650,7 +650,7 @@ privsep_postauth(Authctxt *authctxt)
}
/* New socket pair */
- monitor_reinit(pmonitor);
+ monitor_reinit(pmonitor, options.chroot_directory);
pmonitor->m_pid = fork();
if (pmonitor->m_pid == -1)
@@ -668,6 +668,11 @@ privsep_postauth(Authctxt *authctxt)
close(pmonitor->m_sendfd);
pmonitor->m_sendfd = -1;
+ close(pmonitor->m_log_recvfd);
+ pmonitor->m_log_recvfd = -1;
+
+ if (pmonitor->m_log_sendfd != -1)
+ set_log_handler(mm_log_handler, pmonitor);
/* Demote the private keys to public keys. */
demote_sensitive_data();

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

@ -1,20 +1,8 @@
From 6481ac7fbd0027a7038560e0f51dd0af056cc229 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/50] openssh-6.6.1p1-selinux-contexts
---
openbsd-compat/port-linux-sshd.c | 69 +++++++++++++++++++++++++++++++-
openbsd-compat/port-linux.c | 2 +-
openbsd-compat/port-linux.h | 1 +
sshd-auth.c | 2 +-
4 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
index 8c5fc1fe..646f0887 100644
index 8f32464..18a2ca4 100644
--- a/openbsd-compat/port-linux-sshd.c
+++ b/openbsd-compat/port-linux-sshd.c
@@ -33,6 +33,7 @@
@@ -32,6 +32,7 @@
#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */
#include "servconf.h"
#include "port-linux.h"
@ -22,7 +10,7 @@ index 8c5fc1fe..646f0887 100644
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
@@ -450,7 +451,7 @@ sshd_selinux_setup_exec_context(char *pwname)
@@ -445,7 +446,7 @@ sshd_selinux_setup_exec_context(char *pwname)
void
sshd_selinux_copy_context(void)
{
@ -31,7 +19,7 @@ index 8c5fc1fe..646f0887 100644
if (!sshd_selinux_enabled())
return;
@@ -469,6 +470,72 @@ sshd_selinux_copy_context(void)
@@ -461,6 +462,72 @@ sshd_selinux_copy_context(void)
}
}
@ -46,19 +34,19 @@ index 8c5fc1fe..646f0887 100644
+
+ contexts_path = selinux_openssh_contexts_path();
+ if (contexts_path == NULL) {
+ debug3_f("Failed to get the path to SELinux context");
+ debug3("%s: Failed to get the path to SELinux context", __func__);
+ return;
+ }
+
+ if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
+ debug_f("Failed to open SELinux context file");
+ debug("%s: Failed to open SELinux context file", __func__);
+ 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");
+ logit("%s: SELinux context file needs to be owned by root"
+ " and not writable by anyone else", __func__);
+ fclose(contexts_file);
+ return;
+ }
@ -82,7 +70,7 @@ index 8c5fc1fe..646f0887 100644
+ if (arg && strcmp(arg, "privsep_preauth") == 0) {
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\0') {
+ debug_f("privsep_preauth is empty");
+ debug("%s: privsep_preauth is empty", __func__);
+ fclose(contexts_file);
+ return;
+ }
@ -92,8 +80,8 @@ index 8c5fc1fe..646f0887 100644
+ fclose(contexts_file);
+
+ if (preauth_context == NULL) {
+ debug_f("Unable to find 'privsep_preauth' option in"
+ " SELinux context file");
+ debug("%s: Unable to find 'privsep_preauth' option in"
+ " SELinux context file", __func__);
+ return;
+ }
+
@ -105,23 +93,23 @@ index 8c5fc1fe..646f0887 100644
#endif
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index 7426f6f7..9a6b1d6e 100644
index 22ea8ef..1fc963d 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -188,7 +188,7 @@ ssh_selinux_change_context(const char *newname)
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);
@@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname)
strlcpy(newctx + len, newname, newlen - len);
if ((cx = index(cx + 1, ':')))
strlcat(newctx, cx, newlen);
- debug3("%s: setting context from '%s' to '%s'", __func__,
+ debug("%s: setting context from '%s' to '%s'", __func__,
oldctx, newctx);
if (setcon(newctx) < 0)
do_log2_f(log_level, "setcon %s from %s failed with %s",
newctx, oldctx, strerror(errno));
switchlog("%s: setcon %s from %s failed with %s", __func__,
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 1b745a76..7f8ba200 100644
index cb51f99..8b7cda2 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -27,6 +27,7 @@ int sshd_selinux_enabled(void);
@@ -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);
@ -129,19 +117,16 @@ index 1b745a76..7f8ba200 100644
#endif
#ifdef LINUX_OOM_ADJUST
diff --git a/sshd-auth.c b/sshd-auth.c
index d51e4636..e4a8edfd 100644
--- a/sshd-auth.c
+++ b/sshd-auth.c
@@ -188,7 +188,7 @@ privsep_child_demote(void)
fatal_f("ssh_sandbox_init failed");
#endif
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 */
--
2.49.0

View file

@ -1,21 +1,7 @@
From 9c75c175e3555377328fc5fc9b06e94f129b7cd7 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/50] 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 187faf92..03188d9b 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 187faf92..03188d9b 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 187faf92..03188d9b 100644
return ssh_krb5_kuserok(krb_context, principal, luser,
k5login_exists);
}
diff --git a/servconf.c b/servconf.c
index 5dd5ca21..c0de7110 100644
--- a/servconf.c
+++ b/servconf.c
@@ -146,6 +146,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;
@@ -402,6 +403,8 @@ fill_default_server_options(ServerOptions *options)
options->challenge_response_authentication = -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 5dd5ca21..c0de7110 100644
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -585,7 +588,7 @@ typedef enum {
sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
sPerSourcePenalties, sPerSourcePenaltyExemptList,
@@ -418,7 +421,7 @@ typedef enum {
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
sHostKeyAlgorithms,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
- sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
+ sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
@@ -681,6 +684,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 5dd5ca21..c0de7110 100644
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
@@ -689,6 +693,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 5dd5ca21..c0de7110 100644
#endif
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
@@ -2450,6 +2455,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 5dd5ca21..c0de7110 100644
+ intptr = &options->enable_k5users;
+ goto parse_flag;
+
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
@@ -3005,6 +3014,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
case sPermitListen:
case sPermitOpen:
if (opcode == sPermitListen) {
@@ -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 5dd5ca21..c0de7110 100644
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
@@ -3314,6 +3324,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 5dd5ca21..c0de7110 100644
#endif
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
diff --git a/servconf.h b/servconf.h
index 11de36a2..c08cf6a7 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 ea5a878e..33713c88 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 0fcb409a..fe246fc2 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 0fcb409a..fe246fc2 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.49.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 28333f1dfe68b0ffc80c2a4799759587b4c32d3e 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/50] 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 4a148db4..a365f26f 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -778,12 +778,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,29 @@ check_ip_options(struct ssh *ssh)
if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts,
&option_size) >= 0 && option_size != 0) {
@ -31,14 +21,11 @@ index 4a148db4..a365f26f 100644
+ case 130:
+ case 133:
+ case 134:
+ if (i + 1 < option_size && opts[i + 1] >= 2) {
+ i += opts[i + 1];
+ break;
+ }
+ /* FALLTHROUGH */
+ i += opts[i + 1];
+ break;
+ default:
+ /* Fail, fatally, if we detect either loose or strict
+ * or incorrect source routing options. */
+ * source routing options. */
+ text[0] = '\0';
+ for (i = 0; i < option_size; i++)
+ snprintf(text + i*3, sizeof(text) - i*3,
@ -48,8 +35,5 @@ index 4a148db4..a365f26f 100644
+ }
+ } while (i < option_size);
}
return;
#endif /* IP_OPTIONS */
}
--
2.49.0

View file

@ -0,0 +1,257 @@
diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in
--- openssh-6.8p1/Makefile.in.ctr-cavs 2015-03-18 11:22:05.493289018 +0100
+++ openssh-6.8p1/Makefile.in 2015-03-18 11:22:44.504196316 +0100
@@ -28,6 +28,7 @@ SSH_KEYSIGN=$(libexecdir)/ssh-keysign
SFTP_SERVER=$(libexecdir)/sftp-server
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
SSH_KEYCAT=$(libexecdir)/ssh-keycat
+CTR_CAVSTEST=$(libexecdir)/ctr-cavstest
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper
PRIVSEP_PATH=@PRIVSEP_PATH@
@@ -66,7 +67,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) ssh-keycat$(EXEEXT)
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT)
XMSS_OBJS=\
ssh-xmss.o \
@@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l
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)
+ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o
+ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
@@ -326,6 +330,7 @@ install-files:
$(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) ctr-cavstest$(EXEEXT) $(DESTDIR)$(libexecdir)/ctr-cavstest$(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-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c
--- openssh-6.8p1/ctr-cavstest.c.ctr-cavs 2015-03-18 11:22:05.521288952 +0100
+++ openssh-6.8p1/ctr-cavstest.c 2015-03-18 11:22:05.521288952 +0100
@@ -0,0 +1,215 @@
+/*
+ *
+ * invocation (all of the following are equal):
+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6
+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 --iv 00000000000000000000000000000000
+ * echo -n a6deca405eef2e8e4609abf3c3ccf4a6 | ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "xmalloc.h"
+#include "log.h"
+#include "ssherr.h"
+#include "cipher.h"
+
+/* compatibility with old or broken OpenSSL versions */
+#include "openbsd-compat/openssl-compat.h"
+
+void usage(void) {
+ fprintf(stderr, "Usage: ctr-cavstest --algo <ssh-crypto-algorithm>\n"
+ " --key <hexadecimal-key> --mode <encrypt|decrypt>\n"
+ " [--iv <hexadecimal-iv>] --data <hexadecimal-data>\n\n"
+ "Hexadecimal output is printed to stdout.\n"
+ "Hexadecimal input data can be alternatively read from stdin.\n");
+ exit(1);
+}
+
+void *fromhex(char *hex, size_t *len)
+{
+ unsigned char *bin;
+ char *p;
+ size_t n = 0;
+ int shift = 4;
+ unsigned char out = 0;
+ unsigned char *optr;
+
+ bin = xmalloc(strlen(hex)/2);
+ optr = bin;
+
+ for (p = hex; *p != '\0'; ++p) {
+ unsigned char c;
+
+ c = *p;
+ if (isspace(c))
+ continue;
+
+ if (c >= '0' && c <= '9') {
+ c = c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ c = c - 'A' + 10;
+ } else if (c >= 'a' && c <= 'f') {
+ c = c - 'a' + 10;
+ } else {
+ /* truncate on nonhex cipher */
+ break;
+ }
+
+ out |= c << shift;
+ shift = (shift + 4) % 8;
+
+ if (shift) {
+ *(optr++) = out;
+ out = 0;
+ ++n;
+ }
+ }
+
+ *len = n;
+ return bin;
+}
+
+#define READ_CHUNK 4096
+#define MAX_READ_SIZE 1024*1024*100
+char *read_stdin(void)
+{
+ char *buf;
+ size_t n, total = 0;
+
+ buf = xmalloc(READ_CHUNK);
+
+ do {
+ n = fread(buf + total, 1, READ_CHUNK, stdin);
+ if (n < READ_CHUNK) /* terminate on short read */
+ break;
+
+ total += n;
+ buf = xreallocarray(buf, total + READ_CHUNK, 1);
+ } while(total < MAX_READ_SIZE);
+ return buf;
+}
+
+int main (int argc, char *argv[])
+{
+
+ const struct sshcipher *c;
+ struct sshcipher_ctx *cc;
+ char *algo = "aes128-ctr";
+ char *hexkey = NULL;
+ char *hexiv = "00000000000000000000000000000000";
+ char *hexdata = NULL;
+ char *p;
+ int i, r;
+ int encrypt = 1;
+ void *key;
+ size_t keylen;
+ void *iv;
+ size_t ivlen;
+ void *data;
+ size_t datalen;
+ void *outdata;
+
+ for (i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "--algo") == 0) {
+ algo = argv[++i];
+ } else if (strcmp(argv[i], "--key") == 0) {
+ hexkey = argv[++i];
+ } else if (strcmp(argv[i], "--mode") == 0) {
+ ++i;
+ if (argv[i] == NULL) {
+ usage();
+ }
+ if (strncmp(argv[i], "enc", 3) == 0) {
+ encrypt = 1;
+ } else if (strncmp(argv[i], "dec", 3) == 0) {
+ encrypt = 0;
+ } else {
+ usage();
+ }
+ } else if (strcmp(argv[i], "--iv") == 0) {
+ hexiv = argv[++i];
+ } else if (strcmp(argv[i], "--data") == 0) {
+ hexdata = argv[++i];
+ }
+ }
+
+ if (hexkey == NULL || algo == NULL) {
+ usage();
+ }
+
+ OpenSSL_add_all_algorithms();
+
+ c = cipher_by_name(algo);
+ if (c == NULL) {
+ fprintf(stderr, "Error: unknown algorithm\n");
+ return 2;
+ }
+
+ if (hexdata == NULL) {
+ hexdata = read_stdin();
+ } else {
+ hexdata = xstrdup(hexdata);
+ }
+
+ key = fromhex(hexkey, &keylen);
+
+ if (keylen != 16 && keylen != 24 && keylen == 32) {
+ fprintf(stderr, "Error: unsupported key length\n");
+ return 2;
+ }
+
+ iv = fromhex(hexiv, &ivlen);
+
+ if (ivlen != 16) {
+ fprintf(stderr, "Error: unsupported iv length\n");
+ return 2;
+ }
+
+ data = fromhex(hexdata, &datalen);
+
+ if (data == NULL || datalen == 0) {
+ fprintf(stderr, "Error: no data to encrypt/decrypt\n");
+ return 2;
+ }
+
+ if ((r = cipher_init(&cc, c, key, keylen, iv, ivlen, encrypt)) != 0) {
+ fprintf(stderr, "Error: cipher_init failed: %s\n", ssh_err(r));
+ return 2;
+ }
+
+ free(key);
+ free(iv);
+
+ outdata = malloc(datalen);
+ if(outdata == NULL) {
+ fprintf(stderr, "Error: memory allocation failure\n");
+ return 2;
+ }
+
+ if ((r = cipher_crypt(cc, 0, outdata, data, datalen, 0, 0)) != 0) {
+ fprintf(stderr, "Error: cipher_crypt failed: %s\n", ssh_err(r));
+ return 2;
+ }
+
+ free(data);
+
+ cipher_free(cc);
+
+ for (p = outdata; datalen > 0; ++p, --datalen) {
+ printf("%02X", (unsigned char)*p);
+ }
+
+ free(outdata);
+
+ printf("\n");
+ return 0;
+}
+

View file

@ -1,17 +1,5 @@
From f5e5ee321def2a3674600714ad98fd1ca9b2cff1 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/50] 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 8d2b677f..14502c5a 100644
index 413b845..54dd383 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -32,7 +32,9 @@
@ -24,7 +12,7 @@ index 8d2b677f..14502c5a 100644
#include "xmalloc.h"
#include "sshkey.h"
@@ -44,6 +46,7 @@
@@ -45,6 +47,7 @@
#include "ssh-gss.h"
@ -32,7 +20,7 @@ index 8d2b677f..14502c5a 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 8d2b677f..14502c5a 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 8d2b677f..14502c5a 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 8d2b677f..14502c5a 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 8d2b677f..14502c5a 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 cbfbcee8..89b3a9cf 100644
index 28659ec..9c94d8e 100644
--- a/session.c
+++ b/session.c
@@ -680,6 +680,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 cbfbcee8..89b3a9cf 100644
if (forced != NULL) {
s->forced = 1;
diff --git a/ssh-gss.h b/ssh-gss.h
index 8ec45192..db34d77f 100644
index 0374c88..509109a 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -49,6 +49,10 @@
@ -266,10 +254,10 @@ index 8ec45192..db34d77f 100644
/* draft-ietf-secsh-gsskeyex-06 */
diff --git a/sshd.8 b/sshd.8
index 2aa73271..049d0a94 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 2aa73271..049d0a94 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 2aa73271..049d0a94 100644
.It Pa ~/.ssh/
This directory is the default location for all user-specific configuration
and authentication information.
--
2.49.0

View file

@ -1,26 +1,24 @@
From 5e35e18a419a5a66b6e1cb2b98beaaf4d9db0dc6 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/50] openssh-6.6p1-keycat
---
HOWTO.ssh-keycat | 12 ++
Makefile.in | 8 +-
configure.ac | 6 +
misc.c | 7 +
openbsd-compat/port-linux-sshd.c | 44 +++++-
openbsd-compat/port-linux.h | 2 +
platform.c | 2 +-
ssh-keycat.c | 241 +++++++++++++++++++++++++++++++
8 files changed, 314 insertions(+), 8 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 00000000..630ec628
--- /dev/null
+++ b/HOWTO.ssh-keycat
diff -up openssh/auth.c.keycat openssh/misc.c
--- openssh/auth.c.keycat 2015-06-24 10:57:50.158849606 +0200
+++ openssh/auth.c 2015-06-24 11:04:23.989868638 +0200
@@ -966,6 +966,14 @@ subprocess(const char *tag, struct passw
_exit(1);
}
+#ifdef WITH_SELINUX
+ if (sshd_selinux_setup_env_variables() < 0) {
+ error ("failed to copy environment: %s",
+ strerror(errno));
+ _exit(127);
+ }
+#endif
+
execve(av[0], av, child_env);
error("%s exec \"%s\": %s", tag, command, strerror(errno));
_exit(127);
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
@ -34,46 +32,45 @@ index 00000000..630ec628
+ PubkeyAuthentication yes
+
+
diff --git a/Makefile.in b/Makefile.in
index 4617cebc..438efc51 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -23,6 +23,7 @@ SSH_PROGRAM=@bindir@/ssh
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
SSHD_SESSION=$(libexecdir)/sshd-session
SSHD_AUTH=$(libexecdir)/sshd-auth
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
@@ -57,6 +58,7 @@ CHANNELLIBS=@CHANNELLIBS@
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@
LIBWTMPDB=@LIBWTMPDB@
@@ -74,7 +76,7 @@ MKDIR_P=@MKDIR_P@
AR=@AR@
@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@
.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)
-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 \
@@ -260,6 +262,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS)
@@ -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)
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2)
+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)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
@@ -447,6 +452,7 @@ install-files:
@@ -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)
@ -81,69 +78,26 @@ index 4617cebc..438efc51 100644
$(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 ee77a048..d546788c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3566,6 +3566,7 @@ AC_ARG_WITH([pam],
PAM_MSG="yes"
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 *);
SSHDLIBS="$SSHDLIBS -lpam"
+ KEYCATLIBS="$KEYCATLIBS -lpam"
AC_DEFINE([USE_PAM], [1],
[Define if you want to enable PAM support])
+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
@@ -3576,6 +3577,7 @@ AC_ARG_WITH([pam],
;;
*)
SSHDLIBS="$SSHDLIBS -ldl"
+ KEYCATLIBS="$KEYCATLIBS -ldl"
;;
esac
fi
@@ -4801,6 +4803,7 @@ AC_ARG_WITH([selinux],
fi ]
)
AC_SUBST([SSHDLIBS])
+AC_SUBST([KEYCATLIBS])
# Check whether user wants Kerberos 5 support
KRB5_MSG="no"
@@ -5812,6 +5815,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 c932f9bb..1e31acc9 100644
--- a/misc.c
+++ b/misc.c
@@ -2897,6 +2897,13 @@ subprocess(const char *tag, const char *command,
error("%s: dup2: %s", tag, strerror(errno));
_exit(1);
}
+#ifdef WITH_SELINUX
+ if (sshd_selinux_setup_env_variables() < 0) {
+ error ("failed to copy environment: %s",
+ strerror(errno));
+ _exit(127);
+ }
+#endif
if (env != NULL)
execve(av[0], av, env);
else
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
index dfafc622..8c5fc1fe 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;
#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 +116,7 @@ index dfafc622..8c5fc1fe 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 +125,14 @@ index dfafc622..8c5fc1fe 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 +145,7 @@ index dfafc622..8c5fc1fe 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 +170,7 @@ index dfafc622..8c5fc1fe 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,7 +179,7 @@ index dfafc622..8c5fc1fe 100644
return;
if (options.use_pam) {
@@ -420,7 +452,7 @@ sshd_selinux_copy_context(void)
@@ -415,7 +447,7 @@ sshd_selinux_copy_context(void)
{
security_context_t *ctx;
@ -234,26 +188,10 @@ index dfafc622..8c5fc1fe 100644
return;
if (getexeccon((security_context_t *)&ctx) != 0) {
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 498d242a..1b745a76 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -23,8 +23,10 @@ void ssh_selinux_setup_pty(char *, const char *);
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 --git a/platform.c b/platform.c
index 1bfb4bea..0d12f311 100644
--- a/platform.c
+++ b/platform.c
@@ -55,7 +55,7 @@ platform_setusercontext(struct passwd *pw)
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 */
@ -262,11 +200,9 @@ index 1bfb4bea..0d12f311 100644
#endif
#ifdef USE_SOLARIS_PROJECTS
diff --git a/ssh-keycat.c b/ssh-keycat.c
new file mode 100644
index 00000000..5678be07
--- /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
@ -509,6 +445,41 @@ index 00000000..5678be07
+ }
+ return ev;
+}
--
2.49.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

@ -0,0 +1,31 @@
diff -up openssh-8.2p1/authfile.c.keyperm openssh-8.2p1/authfile.c
--- openssh-8.2p1/authfile.c.keyperm 2020-02-14 01:40:54.000000000 +0100
+++ openssh-8.2p1/authfile.c 2020-02-17 11:55:12.841729758 +0100
@@ -31,6 +31,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <grp.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
@@ -101,7 +102,19 @@ sshkey_perm_ok(int fd, const char *filen
#ifdef HAVE_CYGWIN
if (check_ntsec(filename))
#endif
+
if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
+ if (st.st_mode & 040) {
+ struct group *gr;
+
+ if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid)) {
+ /* The only additional bit is read
+ * for ssh_keys group, which is fine */
+ if ((st.st_mode & 077) == 040 ) {
+ return 0;
+ }
+ }
+ }
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");

View file

@ -1,22 +1,7 @@
From bac7a9d1a654c8c2e0c71f979195e300b25d6232 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/50] 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 74f56d47..bae153c9 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 74f56d47..bae153c9 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 74f56d47..bae153c9 100644
problem = -1;
goto out;
}
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index 820f794c..187faf92 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 820f794c..187faf92 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,17 +150,17 @@ index 820f794c..187faf92 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. */
- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) {
+ if (k5login_exists &&
+ ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)) {
+ if (ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)
+ && k5login_exists) {
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 820f794c..187faf92 100644
}
if ((fp = fopen(file, "r")) == NULL) {
int saved_errno = errno;
diff --git a/servconf.c b/servconf.c
index 55aa5bf0..5dd5ca21 100644
--- a/servconf.c
+++ b/servconf.c
@@ -145,6 +145,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;
@@ -399,6 +400,8 @@ fill_default_server_options(ServerOptions *options)
options->challenge_response_authentication = -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 55aa5bf0..5dd5ca21 100644
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -567,7 +570,7 @@ typedef enum {
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
@@ -399,7 +402,7 @@ typedef enum {
sPermitRootLogin, sLogFacility, sLogLevel,
sRhostsRSAAuthentication, sRSAAuthentication,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
- sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication,
+ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -659,12 +662,14 @@ static struct {
- sKerberosGetAFSToken, sKerberosUniqueCCache,
+ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok,
sChallengeResponseAuthentication,
sPasswordAuthentication, sKbdInteractiveAuthentication,
sListenAddress, sAddressFamily,
@@ -478,12 +481,14 @@ static struct {
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL },
@ -233,18 +216,18 @@ index 55aa5bf0..5dd5ca21 100644
#endif
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
@@ -2441,6 +2446,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
}
@@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions
*inc_flags &= ~SSHCFG_MATCH_ONLY;
break;
+ case sKerberosUseKuserok:
+ intptr = &options->use_kuserok;
+ goto parse_flag;
+
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
@@ -2995,6 +3004,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
case sPermitListen:
case sPermitOpen:
if (opcode == sPermitListen) {
@@ -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 55aa5bf0..5dd5ca21 100644
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
@@ -3303,6 +3313,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 a4a38d6d..11de36a2 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 a4a38d6d..11de36a2 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 8db9f0fb..ea5a878e 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 1251d4d5..0fcb409a 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1041,6 +1041,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 1251d4d5..0fcb409a 100644
+The default is
+.Cm yes .
.It Cm KexAlgorithms
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
@@ -1355,6 +1359,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 1251d4d5..0fcb409a 100644
.Cm LogLevel ,
.Cm MaxAuthTries ,
.Cm MaxSessions ,
--
2.49.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("%s: done", __func__);
}
+void
+sshd_selinux_copy_context(void)
+{
+ security_context_t *ctx;
+
+ if (!ssh_selinux_enabled())
+ return;
+
+ if (getexeccon((security_context_t *)&ctx) != 0) {
+ logit("%s: getexeccon failed with %s", __func__, strerror(errno));
+ return;
+ }
+ if (ctx != NULL) {
+ /* unset exec context before we will lose this capabililty */
+ if (setexeccon(NULL) != 0)
+ fatal("%s: setexeccon failed with %s", __func__, strerror(errno));
+ if (setcon(ctx) != 0)
+ fatal("%s: setcon failed with %s", __func__, 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,185 @@
diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c
--- openssh-7.4p1/channels.c.coverity 2016-12-23 16:40:26.881788686 +0100
+++ openssh-7.4p1/channels.c 2016-12-23 16:42:36.244818763 +0100
@@ -288,11 +288,11 @@ channel_register_fds(Channel *c, int rfd
/* enable nonblocking mode */
if (nonblock) {
- if (rfd != -1)
+ if (rfd >= 0)
set_nonblock(rfd);
- if (wfd != -1)
+ if (wfd >= 0)
set_nonblock(wfd);
- if (efd != -1)
+ if (efd >= 0)
set_nonblock(efd);
}
}
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)
diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c
--- openssh-7.4p1/monitor_wrap.c.coverity 2016-12-23 16:40:26.892788689 +0100
+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:40:26.900788691 +0100
@@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd,
if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
(tmp2 = dup(pmonitor->m_recvfd)) == -1) {
error("%s: cannot allocate fds for pty", __func__);
- if (tmp1 > 0)
+ if (tmp1 >= 0)
close(tmp1);
- if (tmp2 > 0)
- close(tmp2);
+ /*DEAD CODE if (tmp2 >= 0)
+ close(tmp2);*/
return 0;
}
close(tmp1);
diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c
--- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/openbsd-compat/bindresvport.c 2016-12-23 16:40:26.901788691 +0100
@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr
struct sockaddr_in6 *in6;
u_int16_t *portp;
u_int16_t port;
- socklen_t salen;
+ socklen_t salen = sizeof(struct sockaddr_storage);
int i;
if (sa == NULL) {
diff -up openssh-7.4p1/scp.c.coverity openssh-7.4p1/scp.c
--- openssh-7.4p1/scp.c.coverity 2016-12-23 16:40:26.856788681 +0100
+++ openssh-7.4p1/scp.c 2016-12-23 16:40:26.901788691 +0100
@@ -157,7 +157,7 @@ killchild(int signo)
{
if (do_cmd_pid > 1) {
kill(do_cmd_pid, signo ? signo : SIGTERM);
- waitpid(do_cmd_pid, NULL, 0);
+ (void) waitpid(do_cmd_pid, NULL, 0);
}
if (signo)
diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c
--- openssh-7.4p1/servconf.c.coverity 2016-12-23 16:40:26.896788690 +0100
+++ openssh-7.4p1/servconf.c 2016-12-23 16:40:26.901788691 +0100
@@ -1547,7 +1547,7 @@ process_server_config_line(ServerOptions
fatal("%s line %d: Missing subsystem name.",
filename, linenum);
if (!*activep) {
- arg = strdelim(&cp);
+ /*arg =*/ (void) strdelim(&cp);
break;
}
for (i = 0; i < options->num_subsystems; i++)
@@ -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-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c
--- openssh-7.4p1/serverloop.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/serverloop.c 2016-12-23 16:40:26.902788691 +0100
@@ -125,13 +125,13 @@ notify_setup(void)
static void
notify_parent(void)
{
- if (notify_pipe[1] != -1)
+ if (notify_pipe[1] >= 0)
(void)write(notify_pipe[1], "", 1);
}
static void
notify_prepare(fd_set *readset)
{
- if (notify_pipe[0] != -1)
+ if (notify_pipe[0] >= 0)
FD_SET(notify_pipe[0], readset);
}
static void
@@ -139,8 +139,8 @@ 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("%s: reading", __func__);
}
@@ -518,7 +518,7 @@ server_request_tun(void)
debug("%s: invalid tun", __func__);
goto done;
}
- if (auth_opts->force_tun_device != -1) {
+ if (auth_opts->force_tun_device >= 0) {
if (tun != SSH_TUNID_ANY &&
auth_opts->force_tun_device != (int)tun)
goto done;
diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
--- openssh-7.4p1/sftp.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/sftp.c 2016-12-23 16:40:26.903788691 +0100
@@ -224,7 +224,7 @@ killchild(int signo)
pid = sshpid;
if (pid > 1) {
kill(pid, SIGTERM);
- waitpid(pid, NULL, 0);
+ (void) waitpid(pid, NULL, 0);
}
_exit(1);
diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c
--- openssh-7.4p1/ssh-agent.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/ssh-agent.c 2016-12-23 16:40:26.903788691 +0100
@@ -1220,8 +1220,8 @@ main(int ac, char **av)
sanitise_stdfd();
/* drop */
- setegid(getgid());
- setgid(getgid());
+ (void) setegid(getgid());
+ (void) setgid(getgid());
platform_disable_tracing(0); /* strict=no */
diff -up openssh-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;
}
@@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so
explicit_bzero(rnd, sizeof(rnd));
}
}
+
+ if (fdset != NULL)
+ free(fdset);
}
/*

View file

@ -0,0 +1,618 @@
diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in
--- openssh-6.8p1/Makefile.in.kdf-cavs 2015-03-18 11:23:46.346049359 +0100
+++ openssh-6.8p1/Makefile.in 2015-03-18 11:24:20.395968445 +0100
@@ -29,6 +29,7 @@ SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-h
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
SSH_KEYCAT=$(libexecdir)/ssh-keycat
CTR_CAVSTEST=$(libexecdir)/ctr-cavstest
+SSH_CAVS=$(libexecdir)/ssh-cavs
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper
PRIVSEP_PATH=@PRIVSEP_PATH@
@@ -67,7 +68,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) ssh-keycat$(EXEEXT) ctr-cavstest$(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) ctr-cavstest$(EXEEXT) ssh-cavs$(EXEEXT)
XMSS_OBJS=\
ssh-xmss.o \
@@ -198,6 +199,9 @@ ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHD
ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o
$(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o $(SKOBJS)
+ $(LD) -o $@ ssh-cavs.o $(SKOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
@@ -331,6 +335,8 @@ install-files:
$(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) ctr-cavstest$(EXEEXT) $(DESTDIR)$(libexecdir)/ctr-cavstest$(EXEEXT)
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-cavs$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-cavs$(EXEEXT)
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-cavs_driver.pl $(DESTDIR)$(libexecdir)/ssh-cavs_driver.pl
$(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-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
--- openssh-6.8p1/ssh-cavs.c.kdf-cavs 2015-03-18 11:23:46.348049354 +0100
+++ openssh-6.8p1/ssh-cavs.c 2015-03-18 11:23:46.348049354 +0100
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL2
+ * are required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#include "includes.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+
+#include "xmalloc.h"
+#include "sshbuf.h"
+#include "sshkey.h"
+#include "cipher.h"
+#include "kex.h"
+#include "packet.h"
+#include "digest.h"
+
+static int bin_char(unsigned char hex)
+{
+ if (48 <= hex && 57 >= hex)
+ return (hex - 48);
+ if (65 <= hex && 70 >= hex)
+ return (hex - 55);
+ if (97 <= hex && 102 >= hex)
+ return (hex - 87);
+ return 0;
+}
+
+/*
+ * Convert hex representation into binary string
+ * @hex input buffer with hex representation
+ * @hexlen length of hex
+ * @bin output buffer with binary data
+ * @binlen length of already allocated bin buffer (should be at least
+ * half of hexlen -- if not, only a fraction of hexlen is converted)
+ */
+static void hex2bin(const char *hex, size_t hexlen,
+ unsigned char *bin, size_t binlen)
+{
+ size_t i = 0;
+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen;
+
+ for (i = 0; i < chars; i++) {
+ bin[i] = bin_char(hex[(i*2)]) << 4;
+ bin[i] |= bin_char(hex[((i*2)+1)]);
+ }
+}
+
+/*
+ * Allocate sufficient space for binary representation of hex
+ * and convert hex into bin
+ *
+ * Caller must free bin
+ * @hex input buffer with hex representation
+ * @hexlen length of hex
+ * @bin return value holding the pointer to the newly allocated buffer
+ * @binlen return value holding the allocated size of bin
+ *
+ * return: 0 on success, !0 otherwise
+ */
+static int hex2bin_alloc(const char *hex, size_t hexlen,
+ unsigned char **bin, size_t *binlen)
+{
+ unsigned char *out = NULL;
+ size_t outlen = 0;
+
+ if (!hexlen)
+ return -EINVAL;
+
+ outlen = (hexlen + 1) / 2;
+
+ out = calloc(1, outlen);
+ if (!out)
+ return -errno;
+
+ hex2bin(hex, hexlen, out, outlen);
+ *bin = out;
+ *binlen = outlen;
+ return 0;
+}
+
+static char hex_char_map_l[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+static char hex_char_map_u[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+static char hex_char(unsigned int bin, int u)
+{
+ if (bin < sizeof(hex_char_map_l))
+ return (u) ? hex_char_map_u[bin] : hex_char_map_l[bin];
+ return 'X';
+}
+
+/*
+ * Convert binary string into hex representation
+ * @bin input buffer with binary data
+ * @binlen length of bin
+ * @hex output buffer to store hex data
+ * @hexlen length of already allocated hex buffer (should be at least
+ * twice binlen -- if not, only a fraction of binlen is converted)
+ * @u case of hex characters (0=>lower case, 1=>upper case)
+ */
+static void bin2hex(const unsigned char *bin, size_t binlen,
+ char *hex, size_t hexlen, int u)
+{
+ size_t i = 0;
+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen;
+
+ for (i = 0; i < chars; i++) {
+ hex[(i*2)] = hex_char((bin[i] >> 4), u);
+ hex[((i*2)+1)] = hex_char((bin[i] & 0x0f), u);
+ }
+}
+
+struct kdf_cavs {
+ unsigned char *K;
+ size_t Klen;
+ unsigned char *H;
+ size_t Hlen;
+ unsigned char *session_id;
+ size_t session_id_len;
+
+ unsigned int iv_len;
+ unsigned int ek_len;
+ unsigned int ik_len;
+};
+
+static int sshkdf_cavs(struct kdf_cavs *test)
+{
+ int ret = 0;
+ struct kex kex;
+ struct sshbuf *Kb = NULL;
+ BIGNUM *Kbn = NULL;
+ int mode = 0;
+ struct newkeys *ctoskeys;
+ struct newkeys *stockeys;
+ struct ssh *ssh = NULL;
+
+#define HEXOUTLEN 500
+ char hex[HEXOUTLEN];
+
+ memset(&kex, 0, sizeof(struct kex));
+
+ Kbn = BN_new();
+ BN_bin2bn(test->K, test->Klen, Kbn);
+ if (!Kbn) {
+ printf("cannot convert K into bignum\n");
+ ret = 1;
+ goto out;
+ }
+ Kb = sshbuf_new();
+ if (!Kb) {
+ printf("cannot convert K into sshbuf\n");
+ ret = 1;
+ goto out;
+ }
+ sshbuf_put_bignum2(Kb, Kbn);
+
+ kex.session_id = test->session_id;
+ kex.session_id_len = test->session_id_len;
+
+ /* setup kex */
+
+ /* select the right hash based on struct ssh_digest digests */
+ switch (test->ik_len) {
+ case 20:
+ kex.hash_alg = SSH_DIGEST_SHA1;
+ break;
+ case 32:
+ kex.hash_alg = SSH_DIGEST_SHA256;
+ break;
+ case 48:
+ kex.hash_alg = SSH_DIGEST_SHA384;
+ break;
+ case 64:
+ kex.hash_alg = SSH_DIGEST_SHA512;
+ break;
+ default:
+ printf("Wrong hash type %u\n", test->ik_len);
+ ret = 1;
+ goto out;
+ }
+
+ /* implement choose_enc */
+ for (mode = 0; mode < 2; mode++) {
+ kex.newkeys[mode] = calloc(1, sizeof(struct newkeys));
+ if (!kex.newkeys[mode]) {
+ printf("allocation of newkeys failed\n");
+ ret = 1;
+ goto out;
+ }
+ kex.newkeys[mode]->enc.iv_len = test->iv_len;
+ kex.newkeys[mode]->enc.key_len = test->ek_len;
+ kex.newkeys[mode]->enc.block_size = (test->iv_len == 64) ? 8 : 16;
+ kex.newkeys[mode]->mac.key_len = test->ik_len;
+ }
+
+ /* implement kex_choose_conf */
+ kex.we_need = kex.newkeys[0]->enc.key_len;
+ if (kex.we_need < kex.newkeys[0]->enc.block_size)
+ kex.we_need = kex.newkeys[0]->enc.block_size;
+ if (kex.we_need < kex.newkeys[0]->enc.iv_len)
+ kex.we_need = kex.newkeys[0]->enc.iv_len;
+ if (kex.we_need < kex.newkeys[0]->mac.key_len)
+ kex.we_need = kex.newkeys[0]->mac.key_len;
+
+ /* MODE_OUT (1) -> server to client
+ * MODE_IN (0) -> client to server */
+ kex.server = 1;
+
+ /* do it */
+ if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL){
+ printf("Allocation error\n");
+ goto out;
+ }
+ ssh->kex = &kex;
+ kex_derive_keys(ssh, test->H, test->Hlen, Kb);
+
+ ctoskeys = kex.newkeys[0];
+ stockeys = kex.newkeys[1];
+
+ /* get data */
+ memset(hex, 0, HEXOUTLEN);
+ bin2hex(ctoskeys->enc.iv, (size_t)ctoskeys->enc.iv_len,
+ hex, HEXOUTLEN, 0);
+ printf("Initial IV (client to server) = %s\n", hex);
+ memset(hex, 0, HEXOUTLEN);
+ bin2hex(stockeys->enc.iv, (size_t)stockeys->enc.iv_len,
+ hex, HEXOUTLEN, 0);
+ printf("Initial IV (server to client) = %s\n", hex);
+
+ memset(hex, 0, HEXOUTLEN);
+ bin2hex(ctoskeys->enc.key, (size_t)ctoskeys->enc.key_len,
+ hex, HEXOUTLEN, 0);
+ printf("Encryption key (client to server) = %s\n", hex);
+ memset(hex, 0, HEXOUTLEN);
+ bin2hex(stockeys->enc.key, (size_t)stockeys->enc.key_len,
+ hex, HEXOUTLEN, 0);
+ printf("Encryption key (server to client) = %s\n", hex);
+
+ memset(hex, 0, HEXOUTLEN);
+ bin2hex(ctoskeys->mac.key, (size_t)ctoskeys->mac.key_len,
+ hex, HEXOUTLEN, 0);
+ printf("Integrity key (client to server) = %s\n", hex);
+ memset(hex, 0, HEXOUTLEN);
+ bin2hex(stockeys->mac.key, (size_t)stockeys->mac.key_len,
+ hex, HEXOUTLEN, 0);
+ printf("Integrity key (server to client) = %s\n", hex);
+
+out:
+ if (Kbn)
+ BN_free(Kbn);
+ if (Kb)
+ sshbuf_free(Kb);
+ if (ssh)
+ ssh_packet_close(ssh);
+ return ret;
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "\nOpenSSH KDF CAVS Test\n\n");
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "\t-K\tShared secret string\n");
+ fprintf(stderr, "\t-H\tHash string\n");
+ fprintf(stderr, "\t-s\tSession ID string\n");
+ fprintf(stderr, "\t-i\tIV length to be generated\n");
+ fprintf(stderr, "\t-e\tEncryption key length to be generated\n");
+ fprintf(stderr, "\t-m\tMAC key length to be generated\n");
+}
+
+/*
+ * Test command example:
+ * ./ssh-cavs -K 0055d50f2d163cc07cd8a93cc7c3430c30ce786b572c01ad29fec7597000cf8618d664e2ec3dcbc8bb7a1a7eb7ef67f61cdaf291625da879186ac0a5cb27af571b59612d6a6e0627344d846271959fda61c78354aa498773d59762f8ca2d0215ec590d8633de921f920d41e47b3de6ab9a3d0869e1c826d0e4adebf8e3fb646a15dea20a410b44e969f4b791ed6a67f13f1b74234004d5fa5e87eff7abc32d49bbdf44d7b0107e8f10609233b7e2b7eff74a4daf25641de7553975dac6ac1e5117df6f6dbaa1c263d23a6c3e5a3d7d49ae8a828c1e333ac3f85fbbf57b5c1a45be45e43a7be1a4707eac779b8285522d1f531fe23f890fd38a004339932b93eda4 -H d3ab91a850febb417a25d892ec48ed5952c7a5de -s d3ab91a850febb417a25d892ec48ed5952c7a5de -i 8 -e 24 -m 20
+ *
+ * Initial IV (client to server) = 4bb320d1679dfd3a
+ * Initial IV (server to client) = 43dea6fdf263a308
+ * Encryption key (client to server) = 13048cc600b9d3cf9095aa6cf8e2ff9cf1c54ca0520c89ed
+ * Encryption key (server to client) = 1e483c5134e901aa11fc4e0a524e7ec7b75556148a222bb0
+ * Integrity key (client to server) = ecef63a092b0dcc585bdc757e01b2740af57d640
+ * Integrity key (server to client) = 7424b05f3c44a72b4ebd281fb71f9cbe7b64d479
+ */
+int main(int argc, char *argv[])
+{
+ struct kdf_cavs test;
+ int ret = 1;
+ int opt = 0;
+
+ memset(&test, 0, sizeof(struct kdf_cavs));
+ while((opt = getopt(argc, argv, "K:H:s:i:e:m:")) != -1)
+ {
+ size_t len = 0;
+ switch(opt)
+ {
+ /*
+ * CAVS K is MPINT
+ * we want a hex (i.e. the caller must ensure the
+ * following transformations already happened):
+ * 1. cut off first four bytes
+ * 2. if most significant bit of value is
+ * 1, prepend 0 byte
+ */
+ case 'K':
+ len = strlen(optarg);
+ ret = hex2bin_alloc(optarg, len,
+ &test.K, &test.Klen);
+ if (ret)
+ goto out;
+ break;
+ case 'H':
+ len = strlen(optarg);
+ ret = hex2bin_alloc(optarg, len,
+ &test.H, &test.Hlen);
+ if (ret)
+ goto out;
+ break;
+ case 's':
+ len = strlen(optarg);
+ ret = hex2bin_alloc(optarg, len,
+ &test.session_id,
+ &test.session_id_len);
+ if (ret)
+ goto out;
+ break;
+ case 'i':
+ test.iv_len = strtoul(optarg, NULL, 10);
+ break;
+ case 'e':
+ test.ek_len = strtoul(optarg, NULL, 10);
+ break;
+ case 'm':
+ test.ik_len = strtoul(optarg, NULL, 10);
+ break;
+ default:
+ usage();
+ goto out;
+ }
+ }
+
+ ret = sshkdf_cavs(&test);
+
+out:
+ if (test.session_id)
+ free(test.session_id);
+ if (test.K)
+ free(test.K);
+ if (test.H)
+ free(test.H);
+ return ret;
+
+}
diff -up openssh-6.8p1/ssh-cavs_driver.pl.kdf-cavs openssh-6.8p1/ssh-cavs_driver.pl
--- openssh-6.8p1/ssh-cavs_driver.pl.kdf-cavs 2015-03-18 11:23:46.348049354 +0100
+++ openssh-6.8p1/ssh-cavs_driver.pl 2015-03-18 11:23:46.348049354 +0100
@@ -0,0 +1,184 @@
+#!/usr/bin/env perl
+#
+# CAVS test driver for OpenSSH
+#
+# Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# NO WARRANTY
+#
+# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+# REPAIR OR CORRECTION.
+#
+# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES.
+#
+use strict;
+use warnings;
+use IPC::Open2;
+
+# Executing a program by feeding STDIN and retrieving
+# STDOUT
+# $1: data string to be piped to the app on STDIN
+# rest: program and args
+# returns: STDOUT of program as string
+sub pipe_through_program($@) {
+ my $in = shift;
+ my @args = @_;
+
+ my ($CO, $CI);
+ my $pid = open2($CO, $CI, @args);
+
+ my $out = "";
+ my $len = length($in);
+ my $first = 1;
+ while (1) {
+ my $rin = "";
+ my $win = "";
+ # Output of prog is FD that we read
+ vec($rin,fileno($CO),1) = 1;
+ # Input of prog is FD that we write
+ # check for $first is needed because we can have NULL input
+ # that is to be written to the app
+ if ( $len > 0 || $first) {
+ (vec($win,fileno($CI),1) = 1);
+ $first=0;
+ }
+ # Let us wait for 100ms
+ my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1);
+ if ( $wout ) {
+ my $written = syswrite($CI, $in, $len);
+ die "broken pipe" if !defined $written;
+ $len -= $written;
+ substr($in, 0, $written) = "";
+ if ($len <= 0) {
+ close $CI or die "broken pipe: $!";
+ }
+ }
+ if ( $rout ) {
+ my $tmp_out = "";
+ my $bytes_read = sysread($CO, $tmp_out, 4096);
+ $out .= $tmp_out;
+ last if ($bytes_read == 0);
+ }
+ }
+ close $CO or die "broken pipe: $!";
+ waitpid $pid, 0;
+
+ return $out;
+}
+
+# Parser of CAVS test vector file
+# $1: Test vector file
+# $2: Output file for test results
+# return: nothing
+sub parse($$) {
+ my $infile = shift;
+ my $outfile = shift;
+
+ my $out = "";
+
+ my $K = "";
+ my $H = "";
+ my $session_id = "";
+ my $ivlen = 0;
+ my $eklen = "";
+ my $iklen = "";
+
+ open(IN, "<$infile");
+ while(<IN>) {
+
+ my $line = $_;
+ chomp($line);
+ $line =~ s/\r//;
+
+ if ($line =~ /\[SHA-1\]/) {
+ $iklen = 20;
+ } elsif ($line =~ /\[SHA-256\]/) {
+ $iklen = 32;
+ } elsif ($line =~ /\[SHA-384\]/) {
+ $iklen = 48;
+ } elsif ($line =~ /\[SHA-512\]/) {
+ $iklen = 64;
+ } elsif ($line =~ /^\[IV length\s*=\s*(.*)\]/) {
+ $ivlen = $1;
+ $ivlen = $ivlen / 8;
+ } elsif ($line =~ /^\[encryption key length\s*=\s*(.*)\]/) {
+ $eklen = $1;
+ $eklen = $eklen / 8;
+ } elsif ($line =~ /^K\s*=\s*(.*)/) {
+ $K = $1;
+ $K = substr($K, 8);
+ $K = "00" . $K;
+ } elsif ($line =~ /^H\s*=\s*(.*)/) {
+ $H = $1;
+ } elsif ($line =~ /^session_id\s*=\s*(.*)/) {
+ $session_id = $1;
+ }
+ $out .= $line . "\n";
+
+ if ($K ne "" && $H ne "" && $session_id ne "" &&
+ $ivlen ne "" && $eklen ne "" && $iklen > 0) {
+ $out .= pipe_through_program("", "./ssh-cavs -H $H -K $K -s $session_id -i $ivlen -e $eklen -m $iklen");
+
+ $K = "";
+ $H = "";
+ $session_id = "";
+ }
+ }
+ close IN;
+ $out =~ s/\n/\r\n/g; # make it a dos file
+ open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?";
+ print OUT $out;
+ close OUT;
+}
+
+############################################################
+#
+# let us pretend to be C :-)
+sub main() {
+
+ my $infile=$ARGV[0];
+ die "Error: Test vector file $infile not found" if (! -f $infile);
+
+ my $outfile = $infile;
+ # let us add .rsp regardless whether we could strip .req
+ $outfile =~ s/\.req$//;
+ $outfile .= ".rsp";
+ if (-f $outfile) {
+ die "Output file $outfile could not be removed: $?"
+ unless unlink($outfile);
+ }
+ print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n";
+
+ # Do the job
+ parse($infile, $outfile);
+}
+
+###########################################
+# Call it
+main();
+1;

View file

@ -1,17 +1,6 @@
From 34b196198018059bed294fa7a08e70606b4cbc36 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/50] 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 5311bf92..5e6e3aa4 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 5311bf92..5e6e3aa4 100644
.El
.Pp
On some systems,
diff --git a/sftp-server.c b/sftp-server.c
index 4985da38..6ed1c27f 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -76,6 +76,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 4985da38..6ed1c27f 100644
/* SSH2_FXP_INIT received */
static int init_done;
@@ -745,6 +749,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 4985da38..6ed1c27f 100644
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */
@@ -754,6 +759,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 4985da38..6ed1c27f 100644
logit("open \"%s\" flags %s mode 0%o",
name, string_from_portable(pflags), mode);
if (readonly &&
@@ -775,6 +784,8 @@ process_open(u_int32_t id)
@@ -713,6 +722,8 @@ process_open(u_int32_t id)
}
}
}
@ -76,7 +64,7 @@ index 4985da38..6ed1c27f 100644
if (status != SSH2_FX_OK)
send_status(id, status);
free(name);
@@ -1894,7 +1905,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 4985da38..6ed1c27f 100644
" %s -Q protocol_feature\n",
__progname, __progname);
exit(1);
@@ -1918,7 +1929,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 4985da38..6ed1c27f 100644
switch (ch) {
case 'Q':
if (strcasecmp(optarg, "requests") != 0) {
@@ -1980,6 +1991,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 4985da38..6ed1c27f 100644
case 'h':
default:
sftp_server_usage();
--
2.49.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 c288d4a26ad44dc481c9d18d2920c9d70474833c 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/50] 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 1a079c15..768a59f9 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1415,4 +1415,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);
}
@ -25,33 +13,33 @@ index 1a079c15..768a59f9 100644
+ struct sshbuf *m;
+ int r, ret = 0;
+
+ debug3_f("entering");
+ debug3("%s: entering", __func__);
+ if ((m = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ fatal("%s: sshbuf_new failed", __func__);
+ do {
+ blen = atomicio(read, fdin, buf, sizeof(buf));
+ if (blen == 0) /* closed pipe */
+ break;
+ if (blen != sizeof(buf)) {
+ error_f("Failed to read the buffer from child");
+ error("%s: Failed to read the buffer from child", __func__);
+ ret = -1;
+ break;
+ }
+
+ msg_len = get_u32(buf);
+ if (msg_len > 256 * 1024)
+ fatal_f("read: bad msg_len %d", msg_len);
+ fatal("%s: read: bad msg_len %d", __func__, msg_len);
+ sshbuf_reset(m);
+ if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0)
+ fatal_fr(r, "buffer error");
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
+ error_f("Failed to read the the buffer content from the child");
+ error("%s: Failed to read the the buffer content from the child", __func__);
+ ret = -1;
+ break;
+ }
+ if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen ||
+ atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
+ error_f("Failed to write the message to the monitor");
+ error("%s: Failed to write the message to the monitor", __func__);
+ ret = -1;
+ break;
+ }
@ -64,11 +52,10 @@ index 1a079c15..768a59f9 100644
+ pmonitor->m_recvfd = fd;
+}
#endif /* SSH_AUDIT_EVENTS */
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 661ed63b..e957ba6e 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -93,6 +93,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 661ed63b..e957ba6e 100644
#endif
struct Session;
diff --git a/session.c b/session.c
index 83fc9418..b4753d93 100644
--- a/session.c
+++ b/session.c
@@ -167,6 +167,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 83fc9418..b4753d93 100644
static int is_child = 0;
static int in_chroot = 0;
static int have_dev_log = 1;
@@ -390,6 +394,8 @@ xauth_valid_string(const char *s)
@@ -289,6 +293,8 @@ xauth_valid_string(const char *s)
return 1;
}
@ -101,7 +87,7 @@ index 83fc9418..b4753d93 100644
#define USE_PIPES 1
/*
* This is called to fork and execute a command when we have no tty. This
@@ -513,6 +519,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 83fc9418..b4753d93 100644
/* Do processing for the child (exec command etc). */
do_child(ssh, s, command);
/* NOTREACHED */
@@ -630,6 +638,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 83fc9418..b4753d93 100644
/* record login, etc. similar to login(1) */
#ifndef HAVE_OSF_SIA
do_login(ssh, s, command);
@@ -766,6 +777,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);
@@ -781,6 +794,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 83fc9418..b4753d93 100644
return ret;
}
@@ -1532,6 +1559,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 83fc9418..b4753d93 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 83fc9418..b4753d93 100644
/*
* Performs common processing for the child, such as setting up the
* environment, closing extra file descriptors, setting the user and group
@@ -1549,13 +1603,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 83fc9418..b4753d93 100644
/* Force a password change */
if (s->authctxt->force_pwchange) {
do_setusercontext(pw);
--
2.49.0

View file

@ -1,20 +1,8 @@
From 25540939422660b024b8832f67eab82267aa8df6 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/50] 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 77714e3d..74f56d47 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 77714e3d..74f56d47 100644
#endif /* !HEIMDAL */
#endif /* KRB5 */
diff --git a/auth.h b/auth.h
index 10e88e11..39163035 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 10e88e11..39163035 100644
#endif /* AUTH_H */
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index df55512d..820f794c 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;
@ -61,7 +49,7 @@ index df55512d..820f794c 100644
+ int ret = 0;
+
+ ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory);
+ debug3_f("k5login_directory = %s (rv=%d)", k5login_directory, ret);
+ debug3("%s: k5login_directory = %s (rv=%d)", __func__, k5login_directory, ret);
+ if (k5login_directory == NULL || ret != 0) {
+ /* If not set, the library will look for k5login
+ * files in the user's home directory, with the filename .k5login.
@ -76,17 +64,17 @@ index df55512d..820f794c 100644
+ k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "",
+ pw->pw_name);
+ }
+ debug_f("Checking existence of file %s", file);
+ debug("%s: Checking existence of file %s", __func__, file);
- snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
return access(file, F_OK) == 0;
}
diff --git a/sshd.8 b/sshd.8
index 049d0a94..6784286d 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 049d0a94..6784286d 100644
.Pp
.It Pa ~/.ssh/
This directory is the default location for all user-specific configuration
--
2.49.0

View file

@ -1,17 +1,21 @@
From 9bb31b63142adaaf949e20c2d86c97f9b787217b 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/50] 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 49a4f35f..f6112458 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 49a4f35f..f6112458 100644
}
(void) closedir(dirp);
return;
--
2.49.0

View file

@ -1,17 +1,7 @@
From cf6d48305cf6601448ea7a0d96ae825cbbbf0a2c 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/50] openssh-7.2p2-x11
---
channels.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/channels.c b/channels.c
index bfe2e3b2..d46531ce 100644
--- a/channels.c
+++ b/channels.c
@@ -5098,11 +5098,13 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c
--- openssh-7.2p2/channels.c.x11 2016-03-09 19:04:48.000000000 +0100
+++ openssh-7.2p2/channels.c 2016-06-03 10:42:04.775164520 +0200
@@ -3990,21 +3990,24 @@ x11_create_display_inet(int x11_display_
}
static int
@ -24,10 +14,8 @@ index bfe2e3b2..d46531ce 100644
+ if (len <= 0)
+ return -1;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
if (sock == -1)
error("socket: %.100s", strerror(errno));
@@ -5110,11 +5112,12 @@ connect_local_xsocket_path(const char *pathname)
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
- strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
@ -42,7 +30,7 @@ index bfe2e3b2..d46531ce 100644
return -1;
}
@@ -5122,8 +5125,18 @@ static int
@@ -4012,8 +4015,18 @@ static int
connect_local_xsocket(u_int dnr)
{
char buf[1024];
@ -63,6 +51,3 @@ index bfe2e3b2..d46531ce 100644
}
#ifdef __APPLE__
--
2.49.0

View file

@ -1,22 +1,18 @@
From 36e3430d1f81397d5f40600e075272a81f7effce 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/50] 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 d46531ce..7438c1a5 100644
--- a/channels.c
+++ b/channels.c
@@ -4996,7 +4996,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 select() 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,8 +21,8 @@ index d46531ce..7438c1a5 100644
u_int *display_numberp, int **chanids)
{
Channel *nc = NULL;
@@ -5009,8 +5009,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 */
@ -36,35 +32,67 @@ index d46531ce..7438c1a5 100644
- 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));
@@ -5065,7 +5068,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 >= MAX_DISPLAYS) {
+ if (display_number >= x11_max_displays || port < X11_BASE_PORT ) {
+ 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 134528d5..8a09a820 100644
--- a/channels.h
+++ b/channels.h
@@ -379,7 +379,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);
void channel_set_x11_refuse_time(struct ssh *, u_int);
int x11_connect_display(struct ssh *);
-int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
+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 105e301d..15c99b30 100644
--- a/servconf.c
+++ b/servconf.c
@@ -117,6 +117,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 105e301d..15c99b30 100644
options->x11_use_localhost = -1;
options->permit_tty = -1;
options->permit_user_rc = -1;
@@ -353,6 +354,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 105e301d..15c99b30 100644
if (options->x11_use_localhost == -1)
options->x11_use_localhost = 1;
if (options->xauth_location == NULL)
@@ -576,7 +579,7 @@ typedef enum {
sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
@@ -419,7 +422,7 @@ typedef enum {
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,
@@ -714,6 +717,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 105e301d..15c99b30 100644
{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
@@ -1750,6 +1754,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 105e301d..15c99b30 100644
case sX11UseLocalhost:
intptr = &options->x11_use_localhost;
goto parse_flag;
@@ -3004,6 +3012,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 105e301d..15c99b30 100644
M_CP_INTOPT(x11_use_localhost);
M_CP_INTOPT(permit_tty);
M_CP_INTOPT(permit_user_rc);
@@ -3299,6 +3308,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 105e301d..15c99b30 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 c08cf6a7..7c7e5d43 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 c08cf6a7..7c7e5d43 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 c08cf6a7..7c7e5d43 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 54da09d5..28bbb8a7 100644
--- a/session.c
+++ b/session.c
@@ -2611,8 +2611,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,19 +187,18 @@ index 54da09d5..28bbb8a7 100644
debug("x11_create_display_inet failed.");
return 0;
}
diff --git a/sshd_config.5 b/sshd_config.5
index fe246fc2..26fcdc84 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1391,6 +1391,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 StreamLocalBindUnlink ,
.Cm TrustedUserCAKeys ,
.Cm UnusedConnectionTimeout ,
.Cm X11DisplayOffset ,
+.Cm X11MaxDisplays ,
.Cm X11Forwarding
and
.Cm X11UseLocalhost .
@@ -2111,6 +2112,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 fe246fc2..26fcdc84 100644
.It Cm X11Forwarding
Specifies whether X11 forwarding is permitted.
The argument must be
--
2.49.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([GSSLIBS])
AC_SUBST([K5LIBS])
+# 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_ALLOW(__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

@ -0,0 +1,271 @@
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 @@
extern ServerOptions options;
extern u_char *session_id2;
extern u_int session_id2_len;
+extern int inetd_flag;
+extern int rexeced_flag;
+extern Authctxt *the_authctxt;
static char *
format_key(const struct sshkey *key)
@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command,
ac, av, &f,
- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
goto out;
uid_swapped = 1;
@@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command,
ac, av, &f,
- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
goto out;
uid_swapped = 1;
diff -up openssh/auth.c.refactor openssh/auth.c
--- openssh/auth.c.refactor 2019-04-04 13:19:12.235821686 +0200
+++ openssh/auth.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, struct passwd *pw, const char *command,
- int ac, char **av, FILE **child, u_int flags)
+ int ac, char **av, FILE **child, u_int flags, int inetd,
+ void *the_authctxt)
{
FILE *f = NULL;
struct stat st;
@@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
}
#ifdef WITH_SELINUX
- if (sshd_selinux_setup_env_variables() < 0) {
+ if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) {
error ("failed to copy environment: %s",
strerror(errno));
_exit(127);
diff -up openssh/auth.h.refactor openssh/auth.h
--- openssh/auth.h.refactor 2019-04-04 13:19:12.251821839 +0200
+++ openssh/auth.h 2019-04-04 13:19:12.276822078 +0200
@@ -235,7 +235,7 @@ struct passwd *fakepw(void);
#define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */
#define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */
pid_t subprocess(const char *, struct passwd *,
- const char *, int, char **, FILE **, u_int flags);
+ const char *, int, char **, FILE **, u_int flags, int, void *);
int sys_auth_passwd(struct ssh *, const char *);
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)
@@ -223,7 +218,8 @@ get_user_context(const char *sename, con
}
static void
-ssh_selinux_get_role_level(char **role, const char **level)
+ssh_selinux_get_role_level(char **role, const char **level,
+ Authctxt *the_authctxt)
{
*role = NULL;
*level = NULL;
@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
/* Return the default security context for the given username */
static int
-sshd_selinux_getctxbyname(char *pwname,
- security_context_t *default_sc, security_context_t *user_sc)
+sshd_selinux_getctxbyname(char *pwname, security_context_t *default_sc,
+ security_context_t *user_sc, int inetd, Authctxt *the_authctxt)
{
char *sename, *lvl;
char *role;
@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
int r = 0;
context_t con = NULL;
- ssh_selinux_get_role_level(&role, &reqlvl);
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
#ifdef HAVE_GETSEUSERBYNAME
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
if (r == 0) {
/* If launched from xinetd, we must use current level */
- if (inetd_flag && !rexeced_flag) {
+ if (inetd) {
security_context_t sshdsc=NULL;
if (getcon_raw(&sshdsc) < 0)
@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
/* Setup environment variables for pam_selinux */
static int
-sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
+sshd_selinux_setup_variables(int(*set_it)(char *, const char *), int inetd,
+ Authctxt *the_authctxt)
{
const char *reqlvl;
char *role;
@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
debug3("%s: setting execution context", __func__);
- ssh_selinux_get_role_level(&role, &reqlvl);
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
- if (inetd_flag && !rexeced_flag) {
+ if (inetd) {
use_current = "1";
} else {
use_current = "";
@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
}
static int
-sshd_selinux_setup_pam_variables(void)
+sshd_selinux_setup_pam_variables(int inetd,
+ int(pam_setenv)(char *, const char *), Authctxt *the_authctxt)
{
- return sshd_selinux_setup_variables(do_pam_putenv);
+ return sshd_selinux_setup_variables(pam_setenv, inetd, the_authctxt);
}
static int
@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
}
int
-sshd_selinux_setup_env_variables(void)
+sshd_selinux_setup_env_variables(int inetd, void *the_authctxt)
{
- return sshd_selinux_setup_variables(do_setenv);
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
+ return sshd_selinux_setup_variables(do_setenv, inetd, authctxt);
}
/* Set the execution context to the default for the specified user */
void
-sshd_selinux_setup_exec_context(char *pwname)
+sshd_selinux_setup_exec_context(char *pwname, int inetd,
+ int(pam_setenv)(char *, const char *), void *the_authctxt, int use_pam)
{
security_context_t user_ctx = NULL;
int r = 0;
security_context_t default_ctx = NULL;
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
if (!sshd_selinux_enabled())
return;
- if (options.use_pam) {
+ if (use_pam) {
/* do not compute context, just setup environment for pam_selinux */
- if (sshd_selinux_setup_pam_variables()) {
+ if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) {
switch (security_getenforce()) {
case -1:
fatal("%s: security_getenforce() failed", __func__);
@@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
debug3("%s: setting execution context", __func__);
- r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt);
if (r >= 0) {
r = setexeccon(user_ctx);
if (r < 0) {
diff -up openssh/platform.c.refactor openssh/platform.c
--- openssh/platform.c.refactor 2019-04-04 13:19:12.204821389 +0200
+++ openssh/platform.c 2019-04-04 13:19:12.277822088 +0200
@@ -32,6 +32,9 @@
extern int use_privsep;
extern ServerOptions options;
+extern int inetd_flag;
+extern int rexeced_flag;
+extern Authctxt *the_authctxt;
void
platform_pre_listen(void)
@@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru
}
#endif /* HAVE_SETPCRED */
#ifdef WITH_SELINUX
- sshd_selinux_setup_exec_context(pw->pw_name);
+ sshd_selinux_setup_exec_context(pw->pw_name,
+ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt,
+ options.use_pam);
#endif
}
diff -up openssh/sshd.c.refactor openssh/sshd.c
--- openssh/sshd.c.refactor 2019-04-04 13:19:12.275822068 +0200
+++ openssh/sshd.c 2019-04-04 13:19:51.270195262 +0200
@@ -158,7 +158,7 @@ int debug_flag = 0;
static int test_flag = 0;
/* Flag indicating that the daemon is being started from inetd. */
-static int inetd_flag = 0;
+int inetd_flag = 0;
/* Flag indicating that sshd should not detach and become a daemon. */
static int no_daemon_flag = 0;
@@ -171,7 +171,7 @@ static char **saved_argv;
static int saved_argc;
/* re-exec */
-static int rexeced_flag = 0;
+int rexeced_flag = 0;
static int rexec_flag = 1;
static int rexec_argc = 0;
static char **rexec_argv;
@@ -2192,7 +2192,9 @@ main(int ac, char **av)
}
#endif
#ifdef WITH_SELINUX
- sshd_selinux_setup_exec_context(authctxt->pw->pw_name);
+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name,
+ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt,
+ options.use_pam);
#endif
#ifdef USE_PAM
if (options.use_pam) {

457
openssh-7.7p1-fips.patch Normal file
View file

@ -0,0 +1,457 @@
diff -up openssh-8.0p1/cipher-ctr.c.fips openssh-8.0p1/cipher-ctr.c
--- openssh-8.0p1/cipher-ctr.c.fips 2019-07-23 14:55:45.326525641 +0200
+++ openssh-8.0p1/cipher-ctr.c 2019-07-23 14:55:45.401526401 +0200
@@ -179,7 +179,8 @@ evp_aes_128_ctr(void)
aes_ctr.do_cipher = ssh_aes_ctr;
#ifndef SSH_OLD_EVP
aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV |
+ EVP_CIPH_FLAG_FIPS;
#endif
return (&aes_ctr);
}
diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c
--- openssh-8.0p1/dh.c.fips 2019-04-18 00:52:57.000000000 +0200
+++ openssh-8.0p1/dh.c 2019-07-23 14:55:45.401526401 +0200
@@ -152,6 +152,12 @@ choose_dh(int min, int wantbits, int max
int best, bestcount, which, linenum;
struct dhgroup dhg;
+ if (FIPS_mode()) {
+ logit("Using arbitrary primes is not allowed in FIPS mode."
+ " Falling back to known groups.");
+ return (dh_new_group_fallback(max));
+ }
+
if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) {
logit("WARNING: could not open %s (%s), using fixed modulus",
_PATH_DH_MODULI, strerror(errno));
@@ -489,4 +495,38 @@ dh_estimate(int bits)
return 8192;
}
+/*
+ * Compares the received DH parameters with known-good groups,
+ * which might be either from group14, group16 or group18.
+ */
+int
+dh_is_known_group(const DH *dh)
+{
+ const BIGNUM *p, *g;
+ const BIGNUM *known_p, *known_g;
+ DH *known = NULL;
+ int bits = 0, rv = 0;
+
+ DH_get0_pqg(dh, &p, NULL, &g);
+ bits = BN_num_bits(p);
+
+ if (bits <= 3072) {
+ known = dh_new_group14();
+ } else if (bits <= 6144) {
+ known = dh_new_group16();
+ } else {
+ known = dh_new_group18();
+ }
+
+ DH_get0_pqg(known, &known_p, NULL, &known_g);
+
+ if (BN_cmp(g, known_g) == 0 &&
+ BN_cmp(p, known_p) == 0) {
+ rv = 1;
+ }
+
+ DH_free(known);
+ return rv;
+}
+
#endif /* WITH_OPENSSL */
diff -up openssh-8.0p1/dh.h.fips openssh-8.0p1/dh.h
--- openssh-8.0p1/dh.h.fips 2019-04-18 00:52:57.000000000 +0200
+++ openssh-8.0p1/dh.h 2019-07-23 14:55:45.401526401 +0200
@@ -43,6 +43,7 @@ DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);
int dh_pub_is_valid(const DH *, const BIGNUM *);
+int dh_is_known_group(const DH *);
u_int dh_estimate(int);
diff -up openssh-8.0p1/kex.c.fips openssh-8.0p1/kex.c
--- openssh-8.0p1/kex.c.fips 2019-07-23 14:55:45.395526340 +0200
+++ openssh-8.0p1/kex.c 2019-07-23 14:55:45.402526411 +0200
@@ -199,7 +199,10 @@ kex_names_valid(const char *names)
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (kex_alg_by_name(p) == NULL) {
- error("Unsupported KEX algorithm \"%.100s\"", p);
+ if (FIPS_mode())
+ error("\"%.100s\" is not allowed in FIPS mode", p);
+ else
+ error("Unsupported KEX algorithm \"%.100s\"", p);
free(s);
return 0;
}
diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c
--- openssh-8.0p1/kexgexc.c.fips 2019-04-18 00:52:57.000000000 +0200
+++ openssh-8.0p1/kexgexc.c 2019-07-23 14:55:45.402526411 +0200
@@ -28,6 +28,7 @@
#ifdef WITH_OPENSSL
+#include <openssl/crypto.h>
#include <sys/types.h>
#include <openssl/dh.h>
@@ -113,6 +114,10 @@ input_kex_dh_gex_group(int type, u_int32
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
+ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) {
+ r = SSH_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
p = g = NULL; /* belong to kex->dh now */
/* generate and send 'e', client DH public key */
diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h
--- openssh-8.0p1/myproposal.h.fips 2019-04-18 00:52:57.000000000 +0200
+++ openssh-8.0p1/myproposal.h 2019-07-23 14:55:45.402526411 +0200
@@ -111,6 +111,20 @@
"rsa-sha2-256," \
"ssh-rsa"
+#define KEX_FIPS_PK_ALG \
+ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
+ "rsa-sha2-512-cert-v01@openssh.com," \
+ "rsa-sha2-256-cert-v01@openssh.com," \
+ "ssh-rsa-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp256," \
+ "ecdsa-sha2-nistp384," \
+ "ecdsa-sha2-nistp521," \
+ "rsa-sha2-512," \
+ "rsa-sha2-256," \
+ "ssh-rsa"
+
#define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \
"aes128-ctr,aes192-ctr,aes256-ctr," \
@@ -134,6 +142,27 @@
#define KEX_CLIENT_MAC KEX_SERVER_MAC
+#define KEX_FIPS_ENCRYPT \
+ "aes128-ctr,aes192-ctr,aes256-ctr," \
+ "aes128-cbc,3des-cbc," \
+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
+ "aes128-gcm@openssh.com,aes256-gcm@openssh.com"
+#define KEX_DEFAULT_KEX_FIPS \
+ "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"
+#define KEX_FIPS_MAC \
+ "hmac-sha1," \
+ "hmac-sha2-256," \
+ "hmac-sha2-512," \
+ "hmac-sha1-etm@openssh.com," \
+ "hmac-sha2-256-etm@openssh.com," \
+ "hmac-sha2-512-etm@openssh.com"
+
/* Not a KEX value, but here so all the algorithm defaults are together */
#define SSH_ALLOWED_CA_SIGALGS \
"ecdsa-sha2-nistp256," \
diff -up openssh-8.0p1/readconf.c.fips openssh-8.0p1/readconf.c
--- openssh-8.0p1/readconf.c.fips 2019-07-23 14:55:45.334525723 +0200
+++ openssh-8.0p1/readconf.c 2019-07-23 14:55:45.402526411 +0200
@@ -2179,11 +2179,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 */
- def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher);
- def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac);
- def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex);
- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
+ def_cipher = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher);
+ def_mac = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac);
+ def_kex = match_filter_allowlist((FIPS_mode() ?
+ KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex);
+ def_key = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key);
+ def_sig = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig);
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&options->what, \
diff -up openssh-8.0p1/sandbox-seccomp-filter.c.fips openssh-8.0p1/sandbox-seccomp-filter.c
--- openssh-8.0p1/sandbox-seccomp-filter.c.fips 2019-07-23 14:55:45.373526117 +0200
+++ openssh-8.0p1/sandbox-seccomp-filter.c 2019-07-23 14:55:45.402526411 +0200
@@ -137,6 +137,9 @@ static const struct sock_filter preauth_
#ifdef __NR_open
SC_DENY(__NR_open, EACCES),
#endif
+#ifdef __NR_socket
+ SC_DENY(__NR_socket, EACCES),
+#endif
#ifdef __NR_openat
SC_DENY(__NR_openat, EACCES),
#endif
diff -up openssh-8.0p1/servconf.c.fips openssh-8.0p1/servconf.c
--- openssh-8.0p1/servconf.c.fips 2019-07-23 14:55:45.361525996 +0200
+++ openssh-8.0p1/servconf.c 2019-07-23 14:55:45.403526421 +0200
@@ -208,11 +208,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 */
- def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
- def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
- def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
+ def_cipher = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher);
+ def_mac = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac);
+ def_kex = match_filter_allowlist((FIPS_mode() ?
+ KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex);
+ def_key = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key);
+ def_sig = match_filter_allowlist((FIPS_mode() ?
+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig);
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
diff -up openssh-8.0p1/ssh.c.fips openssh-8.0p1/ssh.c
--- openssh-8.0p1/ssh.c.fips 2019-07-23 14:55:45.378526168 +0200
+++ openssh-8.0p1/ssh.c 2019-07-23 14:55:45.403526421 +0200
@@ -76,6 +76,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#endif
+#include <openssl/crypto.h>
#include "openbsd-compat/openssl-compat.h"
#include "openbsd-compat/sys-queue.h"
@@ -614,6 +626,10 @@ main(int ac, char **av)
dump_client_config(&options, host);
exit(0);
}
+
+ if (FIPS_mode()) {
+ debug("FIPS mode initialized");
+ }
/* Expand SecurityKeyProvider if it refers to an environment variable */
if (options.sk_provider != NULL && *options.sk_provider == '$' &&
diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c
--- openssh-8.0p1/sshconnect2.c.fips 2019-07-23 14:55:45.336525743 +0200
+++ openssh-8.0p1/sshconnect2.c 2019-07-23 14:55:45.403526421 +0200
@@ -44,6 +44,8 @@
#include <vis.h>
#endif
+#include <openssl/crypto.h>
+
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
@@ -198,36 +203,41 @@ ssh_kex2(struct ssh *ssh, char *host, st
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {
- /* Add the GSSAPI mechanisms currently supported on this
- * client to the key exchange algorithm proposal */
- orig = myproposal[PROPOSAL_KEX_ALGS];
-
- if (options.gss_server_identity) {
- gss_host = xstrdup(options.gss_server_identity);
- } else if (options.gss_trust_dns) {
- gss_host = remote_hostname(ssh);
- /* Fall back to specified host if we are using proxy command
- * and can not use DNS on that socket */
- if (strcmp(gss_host, "UNKNOWN") == 0) {
- free(gss_host);
- gss_host = xstrdup(host);
- }
- } else {
- gss_host = xstrdup(host);
- }
-
- gss = ssh_gssapi_client_mechanisms(gss_host,
- options.gss_client_identity, options.gss_kex_algorithms);
- if (gss) {
- debug("Offering GSSAPI proposal: %s", gss);
- xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
- "%s,%s", gss, orig);
-
- /* If we've got GSSAPI algorithms, then we also support the
- * 'null' hostkey, as a last resort */
- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
- "%s,null", orig);
+ 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];
+
+ 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);
+ }
+
+ gss = ssh_gssapi_client_mechanisms(gss_host,
+ options.gss_client_identity, options.gss_kex_algorithms);
+ if (gss) {
+ debug("Offering GSSAPI proposal: %s", gss);
+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
+ "%s,%s", gss, orig);
+
+ /* If we've got GSSAPI algorithms, then we also support the
+ * 'null' hostkey, as a last resort */
+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
+ "%s,null", orig);
+ }
}
}
#endif
diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c
--- openssh-8.0p1/sshd.c.fips 2019-07-23 14:55:45.398526371 +0200
+++ openssh-8.0p1/sshd.c 2019-07-23 14:55:45.403526421 +0200
@@ -66,6 +66,7 @@
#include <grp.h>
#include <pwd.h>
#include <signal.h>
+#include <syslog.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -77,6 +78,7 @@
#include <openssl/dh.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
+#include <openssl/crypto.h>
#include "openbsd-compat/openssl-compat.h"
#endif
@@ -1529,6 +1532,7 @@ main(int ac, char **av)
#endif
__progname = ssh_get_progname(av[0]);
+ OpenSSL_add_all_algorithms();
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
saved_argc = ac;
rexec_argc = ac;
@@ -1992,6 +2007,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);
+ if (FIPS_mode()) {
+ debug("FIPS mode initialized");
+ }
+
/* Chdir to the root directory so that the current disk can be
unmounted if desired. */
if (chdir("/") == -1)
@@ -2382,10 +2401,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.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c
--- openssh-8.0p1/sshkey.c.fips 2019-07-23 14:55:45.398526371 +0200
+++ openssh-8.0p1/sshkey.c 2019-07-23 14:55:45.404526431 +0200
@@ -34,6 +34,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/pem.h>
+#include <openssl/crypto.h>
#endif
#include "crypto_api.h"
@@ -57,6 +58,7 @@
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "match.h"
+#include "log.h"
#include "ssh-sk.h"
#ifdef WITH_XMSS
@@ -1591,6 +1593,8 @@ rsa_generate_private_key(u_int bits, RSA
}
if (!BN_set_word(f4, RSA_F4) ||
!RSA_generate_key_ex(private, bits, f4, NULL)) {
+ if (FIPS_mode())
+ logit("%s: the key length might be unsupported by FIPS mode approved key generation method", __func__);
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c
--- openssh-8.0p1/ssh-keygen.c.fips 2019-07-23 14:55:45.391526300 +0200
+++ openssh-8.0p1/ssh-keygen.c 2019-07-23 14:57:54.118830056 +0200
@@ -199,6 +199,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)
+ fatal("ED25519 keys are not allowed in FIPS mode");
+ }
switch (type) {
case KEY_DSA:
if (*bitsp != 1024)
@@ -1029,9 +1035,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));

View file

@ -1,23 +1,5 @@
From 5fca5946aa97dce23c6824c52b070a92532752a9 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/50] 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 c99e4e43..77714e3d 100644
index a5a81ed2..63f877f2 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -51,6 +51,7 @@
@ -37,18 +19,24 @@ index c99e4e43..77714e3d 100644
char *client, *platform_client;
const char *errmsg;
@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -163,7 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
goto out;
}
- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx,
- &authctxt->krb5_fwd_ccache);
- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache);
+ problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx,
+ &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env);
if (problem)
goto out;
@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -172,21 +174,20 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
if (problem)
goto out;
- problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
+ problem = krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
&creds);
if (problem)
goto out;
#endif
@ -69,7 +57,7 @@ index c99e4e43..77714e3d 100644
do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
#endif
@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -222,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
void
krb5_cleanup_proc(Authctxt *authctxt)
{
@ -125,29 +113,12 @@ index c99e4e43..77714e3d 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)
@@ -237,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 +136,7 @@ index c99e4e43..77714e3d 100644
+ old = *dsc;
+
+ i = asprintf(dsc, "%s%s", *dsc, src);
+ if (i == -1) {
+ *dsc = old;
+ if (i == -1 || src == NULL) {
+ free(src);
+ return -1;
+ }
@ -181,7 +151,7 @@ index c99e4e43..77714e3d 100644
+ssh_krb5_expand_template(char **result, const char *template) {
+ char *p_n, *p_o, *r, *tmp_template;
+
+ debug3_f("called, template = %s", template);
+ debug3("%s: called, template = %s", __func__, template);
+ if (template == NULL)
+ return -1;
+
@ -209,13 +179,12 @@ index c99e4e43..77714e3d 100644
+ } else {
+ p_o = strchr(p_n, '}') + 1;
+ *p_o = '\0';
+ debug_f("unsupported token %s in %s", p_n, template);
+ debug("%s: unsupported token %s in %s", __func__, p_n, template);
+ /* 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;
+
@ -229,13 +198,16 @@ index c99e4e43..77714e3d 100644
+ return -1;
+}
+
+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_get_cctemplate(krb5_context ctx, char **ccname) {
+ profile_t p;
+ int ret = 0;
+ char *value = NULL;
+
+ debug3_f("called");
+ debug3("%s: called", __func__);
+ ret = krb5_get_profile(ctx, &p);
+ if (ret)
+ return ret;
@ -246,7 +218,7 @@ index c99e4e43..77714e3d 100644
+
+ ret = ssh_krb5_expand_template(ccname, value);
+
+ debug3_f("returning with ccname = %s", *ccname);
+ debug3("%s: returning with ccname = %s", __func__, *ccname);
+ return ret;
+}
+
@ -254,10 +226,23 @@ index c99e4e43..77714e3d 100644
+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;
+
+ debug3_f("called");
- 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("%s: called", __func__);
+ if (need_environment)
+ *need_environment = 0;
+ ret = ssh_krb5_get_cctemplate(ctx, &ccname);
@ -271,7 +256,8 @@ index c99e4e43..77714e3d 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;
@ -297,7 +283,7 @@ index c99e4e43..77714e3d 100644
- close(tmpfd);
- return (krb5_cc_resolve(ctx, ccname, ccache));
+ debug3_f("setting default ccname to %s", ccname);
+ debug3("%s: setting default ccname to %s", __func__, ccname);
+ /* set the default with already expanded user IDs */
+ ret = krb5_cc_set_default_name(ctx, ccname);
+ if (ret)
@ -318,13 +304,13 @@ index c99e4e43..77714e3d 100644
+ * a primary cache for this collection, if it supports that (non-FILE)
+ */
+ if (krb5_cc_support_switch(ctx, type)) {
+ debug3_f("calling cc_new_unique(%s)", ccname);
+ debug3("%s: calling cc_new_unique(%s)", __func__, ccname);
+ ret = krb5_cc_new_unique(ctx, type, NULL, ccache);
+ free(type);
+ if (ret)
+ return ret;
+
+ debug3_f("calling cc_switch()");
+ debug3("%s: calling cc_switch()", __func__);
+ return krb5_cc_switch(ctx, *ccache);
+ } else {
+ /* Otherwise, we can not create a unique ccname here (either
@ -332,17 +318,17 @@ index c99e4e43..77714e3d 100644
+ * collections
+ */
+ free(type);
+ debug3_f("calling cc_resolve(%s)", ccname);
+ debug3("%s: calling cc_resolve(%s)", __func__, ccname);
+ return (krb5_cc_resolve(ctx, ccname, ccache));
+ }
}
#endif /* !HEIMDAL */
#endif /* KRB5 */
diff --git a/auth.h b/auth.h
index 83d07ae8..10e88e11 100644
index 29491df9..fdab5040 100644
--- a/auth.h
+++ b/auth.h
@@ -85,6 +85,7 @@ struct Authctxt {
@@ -82,6 +82,7 @@ struct Authctxt {
krb5_principal krb5_user;
char *krb5_ticket_file;
char *krb5_ccname;
@ -350,7 +336,7 @@ index 83d07ae8..10e88e11 100644
#endif
struct sshbuf *loginmsg;
@@ -245,7 +246,7 @@ FILE *auth_openprincipals(const char *, struct passwd *, int);
@@ -238,7 +239,7 @@ int sys_auth_passwd(struct ssh *, const char *);
int sys_auth_passwd(struct ssh *, const char *);
#if defined(KRB5) && !defined(HEIMDAL)
@ -359,11 +345,10 @@ index 83d07ae8..10e88e11 100644
#endif
#endif /* AUTH_H */
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index 14502c5a..df55512d 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,
diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c
--- openssh-7.9p1/gss-serv-krb5.c.ccache_name 2019-03-01 15:17:42.708611802 +0100
+++ openssh-7.9p1/gss-serv-krb5.c 2019-03-01 15:17:42.713611844 +0100
@@ -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 +357,7 @@ index 14502c5a..df55512d 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 +375,7 @@ index 14502c5a..df55512d 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 +394,7 @@ index 14502c5a..df55512d 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 +403,7 @@ index 14502c5a..df55512d 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 +412,7 @@ index 14502c5a..df55512d 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 +450,7 @@ index 14502c5a..df55512d 100644
do_pam_putenv(client->store.envvar, client->store.envval);
#endif
@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
@@ -361,7 +355,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
client->store.data = krb_context;
@ -475,10 +460,10 @@ index 14502c5a..df55512d 100644
int
diff --git a/gss-serv.c b/gss-serv.c
index a5cca797..9d5435ed 100644
index 6cae720e..16e55cbc 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void)
@@ -320,13 +320,15 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
}
/* As user */
@ -496,7 +481,7 @@ index a5cca797..9d5435ed 100644
}
/* This allows GSSAPI methods to do things to the child's environment based
@@ -500,9 +502,7 @@ ssh_gssapi_rekey_creds(void) {
@@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() {
char *envstr;
#endif
@ -506,12 +491,11 @@ index a5cca797..9d5435ed 100644
+ 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 d4f7fd66..55aa5bf0 100644
--- a/servconf.c
+++ b/servconf.c
@@ -138,6 +138,7 @@ initialize_server_options(ServerOptions *options)
ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c
--- openssh-7.9p1/servconf.c.ccache_name 2019-03-01 15:17:42.704611768 +0100
+++ openssh-7.9p1/servconf.c 2019-03-01 15:17:42.713611844 +0100
@@ -123,6 +123,7 @@ initialize_server_options(ServerOptions
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
options->kerberos_get_afs_token = -1;
@ -519,7 +503,7 @@ index d4f7fd66..55aa5bf0 100644
options->gss_authentication=-1;
options->gss_keyex = -1;
options->gss_cleanup_creds = -1;
@@ -382,6 +383,8 @@ fill_default_server_options(ServerOptions *options)
@@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options)
options->kerberos_ticket_cleanup = 1;
if (options->kerberos_get_afs_token == -1)
options->kerberos_get_afs_token = 0;
@ -528,16 +512,17 @@ index d4f7fd66..55aa5bf0 100644
if (options->gss_authentication == -1)
options->gss_authentication = 0;
if (options->gss_keyex == -1)
@@ -564,7 +567,7 @@ typedef enum {
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
@@ -447,7 +450,8 @@ typedef enum {
sPermitRootLogin, sLogFacility, sLogLevel,
sRhostsRSAAuthentication, sRSAAuthentication,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
- sKerberosGetAFSToken, sPasswordAuthentication,
+ sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
- sKerberosGetAFSToken, sChallengeResponseAuthentication,
+ sKerberosGetAFSToken, sKerberosUniqueCCache,
+ sChallengeResponseAuthentication,
sPasswordAuthentication, sKbdInteractiveAuthentication,
sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
@@ -655,11 +658,13 @@ static struct {
@@ -526,11 +530,13 @@ static struct {
#else
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
@ -551,7 +536,7 @@ index d4f7fd66..55aa5bf0 100644
#endif
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
@@ -1668,6 +1673,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
@@ -1437,6 +1443,10 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->kerberos_get_afs_token;
goto parse_flag;
@ -562,7 +547,7 @@ index d4f7fd66..55aa5bf0 100644
case sGssAuthentication:
intptr = &options->gss_authentication;
goto parse_flag;
@@ -3293,6 +3302,7 @@ dump_config(ServerOptions *o)
@@ -2507,6 +2517,7 @@ dump_config(ServerOptions *o)
# ifdef USE_AFS
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
# endif
@ -571,10 +556,10 @@ index d4f7fd66..55aa5bf0 100644
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
diff --git a/servconf.h b/servconf.h
index c3f50140..a4a38d6d 100644
index db8362c6..4fa42d64 100644
--- a/servconf.h
+++ b/servconf.h
@@ -149,6 +149,8 @@ typedef struct {
@@ -123,6 +123,8 @@ typedef struct {
* file on logout. */
int kerberos_get_afs_token; /* If true, try to get AFS token if
* authenticated with Kerberos. */
@ -584,10 +569,10 @@ index c3f50140..a4a38d6d 100644
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 89b3a9cf..2620dd11 100644
index 85df6a27..480a5ead 100644
--- a/session.c
+++ b/session.c
@@ -1025,7 +1025,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
@@ -1033,7 +1033,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
/* Allow any GSSAPI methods that we've used to alter
* the child's environment as they see fit
*/
@ -597,7 +582,7 @@ index 89b3a9cf..2620dd11 100644
#endif
/* Set basic environment. */
@@ -1101,7 +1102,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
@@ -1105,7 +1106,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
}
#endif
#ifdef KRB5
@ -607,10 +592,10 @@ index 89b3a9cf..2620dd11 100644
s->authctxt->krb5_ccname);
#endif
diff --git a/ssh-gss.h b/ssh-gss.h
index db34d77f..a894e23c 100644
index 6593e422..245178af 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -116,7 +116,7 @@ typedef struct ssh_gssapi_mech_struct {
@@ -83,7 +82,7 @@ typedef struct ssh_gssapi_mech_struct {
int (*dochild) (ssh_gssapi_client *);
int (*userok) (ssh_gssapi_client *, char *);
int (*localname) (ssh_gssapi_client *, char **);
@ -619,7 +604,7 @@ index db34d77f..a894e23c 100644
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);
@@ -127,7 +126,7 @@ int ssh_gssapi_userok(char *name);
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);
@ -628,11 +613,11 @@ index db34d77f..a894e23c 100644
const char *ssh_gssapi_displayname(void);
char *ssh_gssapi_server_mechanisms(void);
diff --git a/sshd-session.c b/sshd-session.c
index f8c8a797..478381db 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1349,7 +1349,7 @@ main(int ac, char **av)
diff --git a/sshd.c b/sshd.c
index edbe815c..89514e8a 100644
--- a/sshd.c
+++ b/sshd.c
@@ -2162,7 +2162,7 @@ main(int ac, char **av)
#ifdef GSSAPI
if (options.gss_authentication) {
temporarily_use_uid(authctxt->pw);
@ -642,10 +627,10 @@ index f8c8a797..478381db 100644
}
#endif
diff --git a/sshd_config.5 b/sshd_config.5
index 8bc6586e..1251d4d5 100644
index c0683d4a..2349f477 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1033,6 +1033,14 @@ Specifies whether to automatically destroy the user's ticket cache
@@ -860,6 +860,14 @@ Specifies whether to automatically destroy the user's ticket cache
file on logout.
The default is
.Cm yes .
@ -658,8 +643,5 @@ index 8bc6586e..1251d4d5 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.49.0
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.

View file

@ -1,26 +1,7 @@
From 5f21983f6472b26693babea4d6ca6b95a7dc7b05 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/50] 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 cc566356..18169187 100644
--- a/ssh_config
+++ b/ssh_config
@@ -44,3 +44,10 @@
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
# UserKnownHostsFile ~/.ssh/known_hosts.d/%k
@ -31,12 +12,10 @@ index cc566356..18169187 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 00000000..8b1b5902
--- /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,21 @@
+# 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,18 @@ index 00000000..8b1b5902
+# mode correctly we set this to yes.
+ ForwardX11Trusted yes
+
+# rhbz#2352653 - export COLORTERM
+ SendEnv COLORTERM
+# Send locale-related environment variables
+ SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+ SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+ SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
+ SendEnv XMODIFIERS
+
+# Uncomment this if you want to use .local domain
+# Host *.local
diff --git a/sshd_config b/sshd_config
index 0f4a3a72..608203e4 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 2f77b4f4..49349bb3 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 +53,10 @@ index 2f77b4f4..49349bb3 100644
TCPKeepAlive
Specifies whether the system should send TCP keepalive messages
diff --git a/sshd_config.5 b/sshd_config.5
index c0771737..035a50c8 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1942,7 +1942,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 +65,38 @@ index c0771737..035a50c8 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 00000000..993a28d5
--- /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,28 @@
+# This system is following system-wide crypto policy. The changes to
+# crypto properties (Ciphers, MACs, ...) will not have any effect in
+# this or following included files. To override some configuration option,
+# write it before this block or include it before this file.
+# Please, see manual pages for update-crypto-policies(8) and sshd_config(5).
+Include /etc/crypto-policies/back-ends/opensshserver.config
+
+SyslogFacility AUTHPRIV
+
+KbdInteractiveAuthentication no
+ChallengeResponseAuthentication no
+
+GSSAPIAuthentication yes
+GSSAPICleanupCredentials no
@ -121,26 +105,13 @@ index 00000000..993a28d5
+
+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 00000000..1d592d13
--- /dev/null
+++ b/sshd_config_redhat_cp
@@ -0,0 +1,7 @@
+# This system is following system-wide crypto policy. The changes to
+# crypto properties (Ciphers, MACs, ...) will not have any effect in
+# this or following included files. To override some configuration option,
+# write it before this block or include it before this file.
+# Please, see manual pages for update-crypto-policies(8) and sshd_config(5).
+Include /etc/crypto-policies/back-ends/opensshserver.config
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
+AcceptEnv XMODIFIERS
+
--
2.49.0

View file

@ -0,0 +1,26 @@
diff --git a/sshd.c b/sshd.c
--- a/sshd.c
+++ b/sshd.c
@@ -1701,6 +1701,10 @@ main(int ac, char **av)
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
cfg, &includes, NULL);
+ /* '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.");
+
/* Fill in default values for those options not explicitly set. */
fill_default_server_options(&options);
diff --git a/sshd_config b/sshd_config
--- a/sshd_config
+++ b/sshd_config
@@ -101,6 +101,8 @@ GSSAPICleanupCredentials no
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
+# WARNING: 'UsePAM no' is not supported in Fedora and may cause several
+# problems.
#UsePAM no
#AllowAgentForwarding yes

View file

@ -1,84 +1,58 @@
From 95f4e30195382c3df7104c2ad3e5e9953f8ad554 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/50] 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 13c0a792..b4100ea1 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -1238,7 +1238,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 8d801c68..9dd7ae07 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 98bb23d4..83d07ae8 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 75eb4e3a..f7898ab3 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;
@@ -296,8 +304,15 @@ input_userauth_request(int type, u_int32
use_privsep ? " [net]" : "");
authctxt->service = xstrdup(service);
authctxt->style = style ? xstrdup(style) : NULL;
- if (use_privsep)
+#ifdef WITH_SELINUX
+ authctxt->role = role ? xstrdup(role) : NULL;
+#endif
+ if (use_privsep) {
mm_inform_authserv(service, style);
+#ifdef WITH_SELINUX
+ mm_inform_authrole(role);
+#endif
+ }
userauth_banner(ssh);
if (auth2_setup_methods_lists(authctxt) != 0)
ssh_packet_disconnect(ssh,
diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
--- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200
+++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200
@@ -281,6 +281,7 @@ input_gssapi_mic(int type, u_int32_t ple
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)
fatal_f("sshbuf_new failed");
const char *displayname;
@@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple
fatal("%s: sshbuf_new failed", __func__);
mic.value = p;
mic.length = len;
- ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
@ -89,10 +63,10 @@ index 75eb4e3a..f7898ab3 100644
+#endif
+ micuser = authctxt->user;
+ ssh_gssapi_buildmic(b, micuser, authctxt->service,
"gssapi-with-mic", ssh->kex->session_id);
"gssapi-with-mic");
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,14 +74,13 @@ index 75eb4e3a..f7898ab3 100644
+ free(micuser);
free(mic.value);
authctxt->postponed = 0;
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index eb21479a..a3be6e49 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 ||
if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
+#ifdef WITH_SELINUX
+ (authctxt->role
@ -120,13 +93,12 @@ index eb21479a..a3be6e49 100644
(r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
+#endif
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
(r = sshbuf_put_cstring(b, method)) != 0 ||
(r = sshbuf_put_cstring(b, "hostbased")) != 0 ||
(r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index aa24fda0..267a27d2 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -206,9 +206,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 aa24fda0..267a27d2 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 82f6e621..5ba45c12 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 dd0bd032..c932f9bb 100644
--- a/misc.c
+++ b/misc.c
@@ -806,6 +806,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 dd0bd032..c932f9bb 100644
if (*cp == ':') /* Leading colon is part of file name. */
return NULL;
@@ -821,6 +822,13 @@ colon(char *cp)
@@ -557,6 +558,13 @@ colon(char *cp)
return (cp);
if (*cp == '/')
return NULL;
@ -211,11 +179,10 @@ index dd0bd032..c932f9bb 100644
}
return NULL;
}
diff --git a/monitor.c b/monitor.c
index 2179553d..02b3eaaa 100644
--- a/monitor.c
+++ b/monitor.c
@@ -120,6 +120,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 2179553d..02b3eaaa 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 *);
@@ -194,6 +197,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 2179553d..02b3eaaa 100644
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
#ifdef USE_PAM
@@ -912,6 +918,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 2179553d..02b3eaaa 100644
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
#ifdef USE_PAM
@@ -986,6 +995,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;
}
@ -257,8 +224,8 @@ index 2179553d..02b3eaaa 100644
+ monitor_permit_authentications(1);
+
+ if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0)
+ fatal_f("buffer error: %s", ssh_err(r));
+ debug3_f("role=%s", authctxt->role);
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ debug3("%s: role=%s", __func__, authctxt->role);
+
+ if (strlen(authctxt->role) == 0) {
+ free(authctxt->role);
@ -272,25 +239,25 @@ index 2179553d..02b3eaaa 100644
int
mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
{
@@ -1358,7 +1387,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;
const u_char *p;
- char *userstyle, *cp;
+ char *userstyle, *s, *cp;
size_t len;
u_char type;
int hostbound = 0, r, fail = 0;
@@ -1389,6 +1418,8 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen)
int r, fail = 0;
@@ -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");
fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if ((s = strchr(cp, '/')) != NULL)
+ *s = '\0';
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",
authctxt->style ? authctxt->style : "");
@@ -1439,7 +1470,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,22 +266,21 @@ index 2179553d..02b3eaaa 100644
size_t len;
int r, fail = 0;
u_char type;
@@ -1460,6 +1491,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");
fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if ((s = strchr(cp, '/')) != NULL)
+ *s = '\0';
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",
authctxt->style ? authctxt->style : "");
diff --git a/monitor.h b/monitor.h
index 3f8a9bea..9dcd9c29 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 3f8a9bea..9dcd9c29 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 bd900b2f..ef3ab1b1 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -442,6 +442,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);
}
@ -340,12 +305,12 @@ index bd900b2f..ef3ab1b1 100644
+ int r;
+ struct sshbuf *m;
+
+ debug3_f("entering");
+ debug3("%s entering", __func__);
+
+ if ((m = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ fatal("%s: sshbuf_new failed", __func__);
+ if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0)
+ fatal_f("buffer error: %s", ssh_err(r));
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m);
+
+ sshbuf_free(m);
@ -355,11 +320,10 @@ index bd900b2f..ef3ab1b1 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 7134afee..38a280c8 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -46,6 +46,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,12 +333,11 @@ index 7134afee..38a280c8 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 1d549954..78e6fa5b 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -100,7 +100,8 @@ PORTS= port-aix.o \
port-prngd.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-linux.o \
port-solaris.o \
port-net.o \
- port-uw.o
@ -383,12 +346,79 @@ index 1d549954..78e6fa5b 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 00000000..b9fbe38b
--- /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)
-{
- security_context_t 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("%s: getexeccon: %s", __func__, 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,425 @@
+/*
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
+ * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com>
@ -442,6 +472,7 @@ index 00000000..b9fbe38b
+extern ServerOptions options;
+extern Authctxt *the_authctxt;
+extern int inetd_flag;
+extern int rexeced_flag;
+
+/* Send audit message */
+static int
@ -499,7 +530,7 @@ index 00000000..b9fbe38b
+ access_vector_t bit;
+ security_class_t class;
+
+ debug_f("src:%s dst:%s", src, dst);
+ debug("%s: src:%s dst:%s", __func__, src, dst);
+ class = string_to_security_class("context");
+ if (!class) {
+ error("string_to_security_class failed to translate security class context");
@ -647,7 +678,7 @@ index 00000000..b9fbe38b
+
+ 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)
@ -661,7 +692,7 @@ index 00000000..b9fbe38b
+ /* we actually don't change level */
+ reqlvl = "";
+
+ debug_f("current connection level '%s'", reqlvl);
+ debug("%s: current connection level '%s'", __func__, reqlvl);
+
+ }
+
@ -689,8 +720,8 @@ index 00000000..b9fbe38b
+ }
+ }
+ if (r != 0) {
+ error_f("Failed to get default SELinux security "
+ "context for %s", pwname);
+ error("%s: Failed to get default SELinux security "
+ "context for %s", __func__, pwname);
+ }
+
+#ifdef HAVE_GETSEUSERBYNAME
@ -715,13 +746,13 @@ index 00000000..b9fbe38b
+ char *use_current;
+ int rv;
+
+ debug3_f("setting execution context");
+ debug3("%s: setting execution context", __func__);
+
+ ssh_selinux_get_role_level(&role, &reqlvl);
+
+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
+
+ if (inetd_flag) {
+ if (inetd_flag && !rexeced_flag) {
+ use_current = "1";
+ } else {
+ use_current = "";
@ -752,30 +783,32 @@ index 00000000..b9fbe38b
+ if (sshd_selinux_setup_pam_variables()) {
+ switch (security_getenforce()) {
+ case -1:
+ fatal_f("security_getenforce() failed");
+ fatal("%s: security_getenforce() failed", __func__);
+ case 0:
+ error_f("SELinux PAM variable setup failure. Continuing in permissive mode.");
+ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.",
+ __func__);
+ break;
+ default:
+ fatal_f("SELinux PAM variable setup failure. Aborting connection.");
+ fatal("%s: SELinux PAM variable setup failure. Aborting connection.",
+ __func__);
+ }
+ }
+ return;
+ }
+
+ debug3_f("setting execution context");
+ debug3("%s: setting execution context", __func__);
+
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
+ if (r >= 0) {
+ r = setexeccon(user_ctx);
+ if (r < 0) {
+ error_f("Failed to set SELinux execution context %s for %s",
+ user_ctx, pwname);
+ error("%s: Failed to set SELinux execution context %s for %s",
+ __func__, user_ctx, pwname);
+ }
+#ifdef HAVE_SETKEYCREATECON
+ else if (setkeycreatecon(user_ctx) < 0) {
+ error_f("Failed to set SELinux keyring creation context %s for %s",
+ user_ctx, pwname);
+ error("%s: Failed to set SELinux keyring creation context %s for %s",
+ __func__, user_ctx, pwname);
+ }
+#endif
+ }
@ -790,12 +823,14 @@ index 00000000..b9fbe38b
+ if (r < 0) {
+ switch (security_getenforce()) {
+ case -1:
+ fatal_f("security_getenforce() failed");
+ fatal("%s: security_getenforce() failed", __func__);
+ case 0:
+ error_f("ELinux failure. Continuing in permissive mode.");
+ error("%s: SELinux failure. Continuing in permissive mode.",
+ __func__);
+ break;
+ default:
+ fatal_f("SELinux failure. Aborting connection.");
+ fatal("%s: SELinux failure. Aborting connection.",
+ __func__);
+ }
+ }
+ if (user_ctx != NULL && user_ctx != default_ctx)
@ -803,88 +838,16 @@ index 00000000..b9fbe38b
+ if (default_ctx != NULL)
+ freecon(default_ctx);
+
+ debug3_f("done");
+ debug3("%s: done", __func__);
+}
+
+#endif
+#endif
+
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index c1d54f38..7426f6f7 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 959430de..055c825e 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 4c4fe57e..1bfb4bea 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 +856,10 @@ index 4c4fe57e..1bfb4bea 100644
#endif
}
diff --git a/sshd-session.c b/sshd-session.c
index c64eb29f..74d2cbc7 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1328,6 +1328,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 +868,4 @@ index c64eb29f..74d2cbc7 100644
+#endif
#ifdef USE_PAM
if (options.use_pam) {
do_pam_setcred();
--
2.49.0
do_pam_setcred(1);

View file

@ -1,17 +1,8 @@
From 507e6f245557ae7261806f7ecbd40697cb0dd389 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/50] openssh-7.8p1-scp-ipv6
---
scp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scp.c b/scp.c
index 9554b188..7f9795a5 100644
index 60682c68..9344806e 100644
--- a/scp.c
+++ b/scp.c
@@ -1183,7 +1183,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 9554b188..7f9795a5 100644
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
if (do_local_cmd(&alist) != 0)
--
2.49.0

View file

@ -0,0 +1,27 @@
From 22bfdcf060b632b5a6ff603f8f42ff166c211a66 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 29 Sep 2020 10:02:45 +0000
Subject: [PATCH] Fail hard on the first failed attempt to write the
authorized_keys_file
---
ssh-copy-id | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id
index 392f64f..e69a23f 100755
--- a/contrib/ssh-copy-id
+++ b/contrib/ssh-copy-id
@@ -251,7 +251,7 @@ installkeys_sh() {
cd;
umask 077;
mkdir -p $(dirname "${AUTH_KEY_FILE}") &&
- { [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] || echo >> ${AUTH_KEY_FILE}; } &&
+ { [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] || echo >> ${AUTH_KEY_FILE} || exit 1; } &&
cat >> ${AUTH_KEY_FILE} ||
exit 1;
if type restorecon >/dev/null 2>&1; then
--
GitLab

View file

@ -0,0 +1,502 @@
diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5
--- openssh-8.2p1/ssh_config.5.crypto-policies 2020-03-26 14:40:44.546775605 +0100
+++ openssh-8.2p1/ssh_config.5 2020-03-26 14:52:20.700649727 +0100
@@ -359,17 +359,17 @@ or
.Qq *.c.example.com
domains.
.It Cm CASignatureAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies which algorithms are allowed for signing of certificates
by certificate authorities (CAs).
-The default is:
-.Bd -literal -offset indent
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
-.Ed
-.Pp
.Xr ssh 1
will not accept host certificates signed using algorithms other than those
specified.
+.Pp
.It Cm CertificateFile
Specifies a file from which the user's certificate is read.
A corresponding private key must be provided separately in order
@@ -424,20 +424,25 @@ If the option is set to
.Cm no ,
the check will not be executed.
.It Cm Ciphers
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the ciphers allowed and their order of preference.
Multiple ciphers must be comma-separated.
If the specified list begins with a
.Sq +
-character, then the specified ciphers will be appended to the default set
-instead of replacing them.
+character, then the specified ciphers will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified ciphers (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified ciphers will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The supported ciphers are:
.Bd -literal -offset indent
@@ -453,13 +458,6 @@ aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
.Ed
.Pp
-The default is:
-.Bd -literal -offset indent
-chacha20-poly1305@openssh.com,
-aes128-ctr,aes192-ctr,aes256-ctr,
-aes128-gcm@openssh.com,aes256-gcm@openssh.com
-.Ed
-.Pp
The list of available ciphers may also be obtained using
.Qq ssh -Q cipher .
.It Cm ClearAllForwardings
@@ -812,6 +810,11 @@ command line will be passed untouched to
The default is
.Dq no .
.It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
The list of key exchange algorithms that are offered for GSSAPI
key exchange. Possible values are
.Bd -literal -offset 3n
@@ -824,10 +827,8 @@ gss-nistp256-sha256-,
gss-curve25519-sha256-
.Ed
.Pp
-The default is
-.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,
-gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
This option only applies to connections using GSSAPI.
+.Pp
.It Cm HashKnownHosts
Indicates that
.Xr ssh 1
@@ -1149,29 +1150,25 @@ it may be zero or more of:
and
.Cm pam .
.It Cm KexAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.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 methods will be appended to the default set
-instead of replacing them.
+character, then the specified methods will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified methods (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified methods will be placed at the head of the
-default set.
-The default is:
-.Bd -literal -offset indent
-curve25519-sha256,curve25519-sha256@libssh.org,
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
-diffie-hellman-group-exchange-sha256,
-diffie-hellman-group16-sha512,
-diffie-hellman-group18-sha512,
-diffie-hellman-group14-sha256
-.Ed
+built-in openssh default set.
.Pp
The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q kex .
@@ -1231,37 +1228,33 @@ The default is INFO.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of verbose output.
.It Cm MACs
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the MAC (message authentication code) algorithms
in order of preference.
The MAC algorithm is used for data integrity protection.
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
-instead of replacing them.
+character, then the specified algorithms will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The algorithms that contain
.Qq -etm
calculate the MAC after encryption (encrypt-then-mac).
These are considered safer and their use recommended.
.Pp
-The default is:
-.Bd -literal -offset indent
-umac-64-etm@openssh.com,umac-128-etm@openssh.com,
-hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
-hmac-sha1-etm@openssh.com,
-umac-64@openssh.com,umac-128@openssh.com,
-hmac-sha2-256,hmac-sha2-512,hmac-sha1
-.Ed
-.Pp
The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac .
.It Cm NoHostAuthenticationForLocalhost
@@ -1394,36 +1387,25 @@ instead of continuing to execute and pas
The default is
.Cm no .
.It Cm PubkeyAcceptedKeyTypes
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the key types that will be used for public key authentication
as a comma-separated list of patterns.
If the specified list begins with a
.Sq +
-character, then the key types after it will be appended to the default
-instead of replacing it.
+character, then the key types after it will be appended to the built-in
+openssh default instead of replacing it.
If the specified list begins with a
.Sq -
character, then the specified key types (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified key types will be placed at the head of the
-default set.
-The default for this option is:
-.Bd -literal -offset 3n
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-rsa-cert-v01@openssh.com,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@openssh.com,
-rsa-sha2-512,rsa-sha2-256,ssh-rsa
-.Ed
+built-in openssh default set.
.Pp
The list of available key types may also be obtained using
.Qq ssh -Q PubkeyAcceptedKeyTypes .
diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5
--- openssh-8.2p1/sshd_config.5.crypto-policies 2020-03-26 14:40:44.530775355 +0100
+++ openssh-8.2p1/sshd_config.5 2020-03-26 14:48:56.732468099 +0100
@@ -375,16 +375,16 @@ If the argument is
then no banner is displayed.
By default, no banner is displayed.
.It Cm CASignatureAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies which algorithms are allowed for signing of certificates
by certificate authorities (CAs).
-The default is:
-.Bd -literal -offset indent
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
-.Ed
-.Pp
Certificates signed using other algorithms will not be accepted for
public key or host-based authentication.
+.Pp
.It Cm ChallengeResponseAuthentication
Specifies whether challenge-response authentication is allowed (e.g. via
PAM or through authentication styles supported in
@@ -446,20 +446,25 @@ The default is
indicating not to
.Xr chroot 2 .
.It Cm Ciphers
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the ciphers allowed.
Multiple ciphers must be comma-separated.
If the specified list begins with a
.Sq +
-character, then the specified ciphers will be appended to the default set
-instead of replacing them.
+character, then the specified ciphers will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified ciphers (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified ciphers will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The supported ciphers are:
.Pp
@@ -486,13 +491,6 @@ aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-chacha20-poly1305@openssh.com,
-aes128-ctr,aes192-ctr,aes256-ctr,
-aes128-gcm@openssh.com,aes256-gcm@openssh.com
-.Ed
-.Pp
The list of available ciphers may also be obtained using
.Qq ssh -Q cipher .
.It Cm ClientAliveCountMax
@@ -681,22 +679,24 @@ For this to work
.Cm GSSAPIKeyExchange
needs to be enabled in the server and also used by the client.
.It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
The list of key exchange algorithms that are accepted by GSSAPI
key exchange. Possible values are
.Bd -literal -offset 3n
-gss-gex-sha1-,
-gss-group1-sha1-,
-gss-group14-sha1-,
-gss-group14-sha256-,
-gss-group16-sha512-,
-gss-nistp256-sha256-,
+gss-gex-sha1-
+gss-group1-sha1-
+gss-group14-sha1-
+gss-group14-sha256-
+gss-group16-sha512-
+gss-nistp256-sha256-
gss-curve25519-sha256-
.Ed
-.Pp
-The default is
-.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,
-gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
This option only applies to connections using GSSAPI.
+.Pp
.It Cm HostbasedAcceptedKeyTypes
Specifies the key types that will be accepted for hostbased authentication
as a list of comma-separated patterns.
@@ -793,25 +793,13 @@ is specified, the location of the socket
.Ev SSH_AUTH_SOCK
environment variable.
.It Cm HostKeyAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the host key algorithms
that the server offers.
-The default for this option is:
-.Bd -literal -offset 3n
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-rsa-cert-v01@openssh.com,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@openssh.com,
-rsa-sha2-512,rsa-sha2-256,ssh-rsa
-.Ed
-.Pp
The list of available key types may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts
@@ -943,20 +931,25 @@ Specifies whether to look at .k5login fi
The default is
.Cm yes .
.It Cm KexAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
Alternately if the specified list begins with a
.Sq +
-character, then the specified methods will be appended to the default set
-instead of replacing them.
+character, then the specified methods will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified methods (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified methods will be placed at the head of the
-default set.
+built-in openssh default set.
The supported algorithms are:
.Pp
.Bl -item -compact -offset indent
@@ -988,15 +981,6 @@ ecdh-sha2-nistp521
sntrup4591761x25519-sha512@tinyssh.org
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-curve25519-sha256,curve25519-sha256@libssh.org,
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
-diffie-hellman-group-exchange-sha256,
-diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
-diffie-hellman-group14-sha256
-.Ed
-.Pp
The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress
@@ -1065,21 +1049,26 @@ DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
Logging with a DEBUG level violates the privacy of users and is not recommended.
.It Cm MACs
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the available MAC (message authentication code) algorithms.
The MAC algorithm is used for data integrity protection.
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
-instead of replacing them.
+character, then the specified algorithms will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified algorithms (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The algorithms that contain
.Qq -etm
@@ -1122,15 +1111,6 @@ umac-64-etm@openssh.com
umac-128-etm@openssh.com
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-umac-64-etm@openssh.com,umac-128-etm@openssh.com,
-hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
-hmac-sha1-etm@openssh.com,
-umac-64@openssh.com,umac-128@openssh.com,
-hmac-sha2-256,hmac-sha2-512,hmac-sha1
-.Ed
-.Pp
The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac .
.It Cm Match
@@ -1480,36 +1460,25 @@ or equivalent.)
The default is
.Cm yes .
.It Cm PubkeyAcceptedKeyTypes
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the key types that will be accepted for public key authentication
as a list of comma-separated patterns.
Alternately if the specified list begins with a
.Sq +
-character, then the specified key types will be appended to the default set
-instead of replacing them.
+character, then the specified key types will be appended to the built-in
+openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified key types (including wildcards) will be removed
-from the default set instead of replacing them.
+from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified key types will be placed at the head of the
-default set.
-The default for this option is:
-.Bd -literal -offset 3n
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ssh-ed25519-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-rsa-cert-v01@openssh.com,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ecdsa-sha2-nistp256@openssh.com,
-ssh-ed25519,sk-ssh-ed25519@openssh.com,
-rsa-sha2-512,rsa-sha2-256,ssh-rsa
-.Ed
+built-in openssh default set.
.Pp
The list of available key types may also be obtained using
.Qq ssh -Q PubkeyAcceptedKeyTypes .

View file

@ -0,0 +1,720 @@
From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 14 May 2019 10:45:45 +0200
Subject: [PATCH] Use high-level OpenSSL API for signatures
---
digest-openssl.c | 16 ++++
digest.h | 6 ++
ssh-dss.c | 65 ++++++++++------
ssh-ecdsa.c | 69 ++++++++++-------
ssh-rsa.c | 193 +++++++++--------------------------------------
sshkey.c | 77 +++++++++++++++++++
sshkey.h | 4 +
7 files changed, 221 insertions(+), 209 deletions(-)
diff --git a/digest-openssl.c b/digest-openssl.c
index da7ed72bc..6a21d8adb 100644
--- a/digest-openssl.c
+++ b/digest-openssl.c
@@ -63,6 +63,22 @@ const struct ssh_digest digests[] = {
{ -1, NULL, 0, NULL },
};
+const EVP_MD *
+ssh_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 const struct ssh_digest *
ssh_digest_by_alg(int alg)
{
diff --git a/digest.h b/digest.h
index 274574d0e..c7ceeb36f 100644
--- a/digest.h
+++ b/digest.h
@@ -32,6 +32,12 @@
struct sshbuf;
struct ssh_digest_ctx;
+#ifdef WITH_OPENSSL
+#include <openssl/evp.h>
+/* Converts internal digest representation to the OpenSSL one */
+const EVP_MD *ssh_digest_to_md(int digest_type);
+#endif
+
/* Looks up a digest algorithm by name */
int ssh_digest_alg_by_name(const char *name);
diff --git a/ssh-dss.c b/ssh-dss.c
index a23c383dc..ea45e7275 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -52,11 +52,15 @@ int
ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
{
+ EVP_PKEY *pkey = NULL;
DSA_SIG *sig = NULL;
const BIGNUM *sig_r, *sig_s;
- u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
- size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
+ u_char sigblob[SIGBLOB_LEN];
+ size_t rlen, slen;
+ int len;
struct sshbuf *b = NULL;
+ u_char *sigb = NULL;
+ const u_char *psig = NULL;
int ret = SSH_ERR_INVALID_ARGUMENT;
if (lenp != NULL)
@@ -67,17 +71,24 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
if (key == NULL || key->dsa == NULL ||
sshkey_type_plain(key->type) != KEY_DSA)
return SSH_ERR_INVALID_ARGUMENT;
- if (dlen == 0)
- return SSH_ERR_INTERNAL_ERROR;
- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
- digest, sizeof(digest))) != 0)
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
+ return SSH_ERR_ALLOC_FAIL;
+ ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len,
+ data, datalen);
+ EVP_PKEY_free(pkey);
+ if (ret < 0) {
goto out;
+ }
- if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
+ psig = sigb;
+ if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ free(sigb);
+ sigb = NULL;
DSA_SIG_get0(sig, &sig_r, &sig_s);
rlen = BN_num_bytes(sig_r);
@@ -110,7 +121,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
*lenp = len;
ret = 0;
out:
- explicit_bzero(digest, sizeof(digest));
+ free(sigb);
DSA_SIG_free(sig);
sshbuf_free(b);
return ret;
@@ -121,20 +132,20 @@ ssh_dss_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat)
{
+ EVP_PKEY *pkey = NULL;
DSA_SIG *sig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
- u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
- size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
+ u_char *sigblob = NULL;
+ size_t len, slen;
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL;
char *ktype = NULL;
+ u_char *sigb = NULL, *psig = NULL;
if (key == NULL || key->dsa == NULL ||
sshkey_type_plain(key->type) != KEY_DSA ||
signature == NULL || signaturelen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- if (dlen == 0)
- return SSH_ERR_INTERNAL_ERROR;
/* fetch signature */
if ((b = sshbuf_from(signature, signaturelen)) == NULL)
@@ -176,25 +187,31 @@ ssh_dss_verify(const struct sshkey *key,
}
sig_r = sig_s = NULL; /* transferred */
- /* sha1 the data */
- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
- digest, sizeof(digest))) != 0)
+ if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
-
- switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {
- case 1:
- ret = 0;
- break;
- case 0:
- ret = SSH_ERR_SIGNATURE_INVALID;
+ }
+ if ((sigb = malloc(slen)) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
- default:
+ }
+ psig = sigb;
+ if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen,
+ sigb, slen);
+ EVP_PKEY_free(pkey);
+
out:
- explicit_bzero(digest, sizeof(digest));
+ free(sigb);
DSA_SIG_free(sig);
BN_clear_free(sig_r);
BN_clear_free(sig_s);
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 599c7199d..b036796e8 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -50,11 +50,13 @@ int
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
{
+ EVP_PKEY *pkey = NULL;
ECDSA_SIG *sig = NULL;
+ unsigned char *sigb = NULL;
+ const unsigned char *psig;
const BIGNUM *sig_r, *sig_s;
int hash_alg;
- u_char digest[SSH_DIGEST_MAX_LENGTH];
- size_t len, dlen;
+ int len;
struct sshbuf *b = NULL, *bb = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
@@ -67,18 +69,24 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
sshkey_type_plain(key->type) != KEY_ECDSA)
return SSH_ERR_INVALID_ARGUMENT;
- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
- (dlen = ssh_digest_bytes(hash_alg)) == 0)
+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
return SSH_ERR_INTERNAL_ERROR;
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
- digest, sizeof(digest))) != 0)
+
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
+ return SSH_ERR_ALLOC_FAIL;
+ ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data,
+ datalen);
+ EVP_PKEY_free(pkey);
+ if (ret < 0) {
goto out;
+ }
- if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
+ psig = sigb;
+ if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
-
if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
@@ -102,7 +110,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
*lenp = len;
ret = 0;
out:
- explicit_bzero(digest, sizeof(digest));
+ free(sigb);
sshbuf_free(b);
sshbuf_free(bb);
ECDSA_SIG_free(sig);
@@ -115,22 +123,21 @@ ssh_ecdsa_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat)
{
+ EVP_PKEY *pkey = NULL;
ECDSA_SIG *sig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
- int hash_alg;
- u_char digest[SSH_DIGEST_MAX_LENGTH];
- size_t dlen;
+ int hash_alg, len;
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL, *sigbuf = NULL;
char *ktype = NULL;
+ unsigned char *sigb = NULL, *psig = NULL;
if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA ||
signature == NULL || signaturelen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
- (dlen = ssh_digest_bytes(hash_alg)) == 0)
+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
return SSH_ERR_INTERNAL_ERROR;
/* fetch signature */
@@ -166,28 +173,36 @@ ssh_ecdsa_verify(const struct sshkey *key,
}
sig_r = sig_s = NULL; /* transferred */
- if (sshbuf_len(sigbuf) != 0) {
- ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
+ /* Figure out the length */
+ if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((sigb = malloc(len)) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
- digest, sizeof(digest))) != 0)
+ psig = sigb;
+ if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
+ }
- switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
- case 1:
- ret = 0;
- break;
- case 0:
- ret = SSH_ERR_SIGNATURE_INVALID;
+ if (sshbuf_len(sigbuf) != 0) {
+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
- default:
- ret = SSH_ERR_LIBCRYPTO_ERROR;
+ }
+
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len);
+ EVP_PKEY_free(pkey);
out:
- explicit_bzero(digest, sizeof(digest));
+ free(sigb);
sshbuf_free(sigbuf);
sshbuf_free(b);
ECDSA_SIG_free(sig);
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 9b14f9a9a..8ef3a6aca 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -37,7 +37,7 @@
#include "openbsd-compat/openssl-compat.h"
-static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
+static int openssh_RSA_verify(int, const u_char *, size_t, u_char *, size_t, EVP_PKEY *);
static const char *
rsa_hash_alg_ident(int hash_alg)
@@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg)
return -1;
}
-static int
-rsa_hash_alg_nid(int type)
-{
- switch (type) {
- case SSH_DIGEST_SHA1:
- return NID_sha1;
- case SSH_DIGEST_SHA256:
- return NID_sha256;
- case SSH_DIGEST_SHA512:
- return NID_sha512;
- default:
- return -1;
- }
-}
-
int
ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
{
@@ -164,11 +149,10 @@ int
ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, const char *alg_ident)
{
- const BIGNUM *rsa_n;
- u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
- size_t slen = 0;
- u_int dlen, len;
- int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
+ EVP_PKEY *pkey = NULL;
+ u_char *sig = NULL;
+ int len, slen = 0;
+ int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL;
if (lenp != NULL)
@@ -180,33 +164,24 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
hash_alg = SSH_DIGEST_SHA1;
else
hash_alg = rsa_hash_id_from_keyname(alg_ident);
+
if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
sshkey_type_plain(key->type) != KEY_RSA)
return SSH_ERR_INVALID_ARGUMENT;
- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
- return SSH_ERR_KEY_LENGTH;
slen = RSA_size(key->rsa);
- if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
- return SSH_ERR_INVALID_ARGUMENT;
-
- /* hash the data */
- nid = rsa_hash_alg_nid(hash_alg);
- if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
- return SSH_ERR_INTERNAL_ERROR;
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
- digest, sizeof(digest))) != 0)
- goto out;
+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ return SSH_ERR_KEY_LENGTH;
- if ((sig = malloc(slen)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
+ return SSH_ERR_ALLOC_FAIL;
+ ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,
+ datalen);
+ EVP_PKEY_free(pkey);
+ if (ret < 0) {
goto out;
}
- if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
if (len < slen) {
size_t diff = slen - len;
memmove(sig + diff, sig, len);
@@ -215,6 +190,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
ret = SSH_ERR_INTERNAL_ERROR;
goto out;
}
+
/* encode signature */
if ((b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
@@ -235,7 +211,6 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
*lenp = len;
ret = 0;
out:
- explicit_bzero(digest, sizeof(digest));
freezero(sig, slen);
sshbuf_free(b);
return ret;
@@ -246,10 +221,10 @@ ssh_rsa_verify(const struct sshkey *key,
const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
const char *alg)
{
- const BIGNUM *rsa_n;
+ EVP_PKEY *pkey = NULL;
char *sigtype = NULL;
int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
- size_t len = 0, diff, modlen, dlen;
+ size_t len = 0, diff, modlen;
struct sshbuf *b = NULL;
u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
@@ -257,8 +232,7 @@ ssh_rsa_verify(const struct sshkey *key,
sshkey_type_plain(key->type) != KEY_RSA ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH;
if ((b = sshbuf_from(sig, siglen)) == NULL)
@@ -310,16 +284,15 @@ ssh_rsa_verify(const struct sshkey *key,
explicit_bzero(sigblob, diff);
len = modlen;
}
- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
- ret = SSH_ERR_INTERNAL_ERROR;
+
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
- digest, sizeof(digest))) != 0)
- goto out;
+ ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey);
+ EVP_PKEY_free(pkey);
- ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
- key->rsa);
out:
freezero(sigblob, len);
free(sigtype);
@@ -328,122 +301,26 @@ ssh_rsa_verify(const struct sshkey *key,
return ret;
}
-/*
- * See:
- * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
- * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
- */
-
-/*
- * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
- * oiw(14) secsig(3) algorithms(2) 26 }
- */
-static const u_char id_sha1[] = {
- 0x30, 0x21, /* type Sequence, length 0x21 (33) */
- 0x30, 0x09, /* type Sequence, length 0x09 */
- 0x06, 0x05, /* type OID, length 0x05 */
- 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
- 0x05, 0x00, /* NULL */
- 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
-};
-
-/*
- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
- * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
- * id-sha256(1) }
- */
-static const u_char id_sha256[] = {
- 0x30, 0x31, /* type Sequence, length 0x31 (49) */
- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
- 0x06, 0x09, /* type OID, length 0x09 */
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
- 0x05, 0x00, /* NULL */
- 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */
-};
-
-/*
- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
- * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
- * id-sha256(3) }
- */
-static const u_char id_sha512[] = {
- 0x30, 0x51, /* type Sequence, length 0x51 (81) */
- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
- 0x06, 0x09, /* type OID, length 0x09 */
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
- 0x05, 0x00, /* NULL */
- 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */
-};
-
static int
-rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
+openssh_RSA_verify(int hash_alg, const u_char *data, size_t datalen,
+ u_char *sigbuf, size_t siglen, EVP_PKEY *pkey)
{
- switch (hash_alg) {
- case SSH_DIGEST_SHA1:
- *oidp = id_sha1;
- *oidlenp = sizeof(id_sha1);
- break;
- case SSH_DIGEST_SHA256:
- *oidp = id_sha256;
- *oidlenp = sizeof(id_sha256);
- break;
- case SSH_DIGEST_SHA512:
- *oidp = id_sha512;
- *oidlenp = sizeof(id_sha512);
- break;
- default:
- return SSH_ERR_INVALID_ARGUMENT;
- }
- return 0;
-}
+ size_t rsasize = 0;
+ const RSA *rsa;
+ int ret;
-static int
-openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
- u_char *sigbuf, size_t siglen, RSA *rsa)
-{
- size_t rsasize = 0, oidlen = 0, hlen = 0;
- int ret, len, oidmatch, hashmatch;
- const u_char *oid = NULL;
- u_char *decrypted = NULL;
-
- if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
- return ret;
- ret = SSH_ERR_INTERNAL_ERROR;
- hlen = ssh_digest_bytes(hash_alg);
- if (hashlen != hlen) {
- ret = SSH_ERR_INVALID_ARGUMENT;
- goto done;
- }
+ rsa = EVP_PKEY_get0_RSA(pkey);
rsasize = RSA_size(rsa);
if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
siglen == 0 || siglen > rsasize) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto done;
}
- if ((decrypted = malloc(rsasize)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto done;
- }
- if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
- RSA_PKCS1_PADDING)) < 0) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto done;
- }
- if (len < 0 || (size_t)len != hlen + oidlen) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto done;
- }
- oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
- hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
- if (!oidmatch || !hashmatch) {
- ret = SSH_ERR_SIGNATURE_INVALID;
- goto done;
- }
- ret = 0;
+
+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen,
+ sigbuf, siglen);
+
done:
- freezero(decrypted, rsasize);
return ret;
}
#endif /* WITH_OPENSSL */
diff --git a/sshkey.c b/sshkey.c
index ad1957762..b95ed0b10 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -358,6 +358,83 @@ sshkey_type_plain(int type)
}
#ifdef WITH_OPENSSL
+int
+sshkey_calculate_signature(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
+ int *lenp, const u_char *data, size_t datalen)
+{
+ EVP_MD_CTX *ctx = NULL;
+ u_char *sig = NULL;
+ int ret, slen, len;
+
+ if (sigp == NULL || lenp == NULL) {
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+
+ slen = EVP_PKEY_size(pkey);
+ if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
+ return SSH_ERR_INVALID_ARGUMENT;
+
+ len = slen;
+ if ((sig = malloc(slen)) == NULL) {
+ return SSH_ERR_ALLOC_FAIL;
+ }
+
+ if ((ctx = EVP_MD_CTX_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto error;
+ }
+ if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
+ EVP_SignUpdate(ctx, data, datalen) <= 0 ||
+ EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto error;
+ }
+
+ *sigp = sig;
+ *lenp = len;
+ /* Now owned by the caller */
+ sig = NULL;
+ ret = 0;
+
+error:
+ EVP_MD_CTX_free(ctx);
+ free(sig);
+ return ret;
+}
+
+int
+sshkey_verify_signature(EVP_PKEY *pkey, int hash_alg, const u_char *data,
+ size_t datalen, u_char *sigbuf, int siglen)
+{
+ EVP_MD_CTX *ctx = NULL;
+ int ret;
+
+ if ((ctx = EVP_MD_CTX_new()) == NULL) {
+ return SSH_ERR_ALLOC_FAIL;
+ }
+ if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
+ EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto done;
+ }
+ ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
+ switch (ret) {
+ case 1:
+ ret = 0;
+ break;
+ case 0:
+ ret = SSH_ERR_SIGNATURE_INVALID;
+ break;
+ default:
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ break;
+ }
+
+done:
+ EVP_MD_CTX_free(ctx);
+ return ret;
+}
+
/* XXX: these are really begging for a table-driven approach */
int
sshkey_curve_name_to_nid(const char *name)
diff --git a/sshkey.h b/sshkey.h
index a91e60436..270901a87 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -179,6 +179,10 @@ const char *sshkey_ssh_name(const struct sshkey *);
const char *sshkey_ssh_name_plain(const struct sshkey *);
int sshkey_names_valid2(const char *, int);
char *sshkey_alg_list(int, int, int, char);
+int sshkey_calculate_signature(EVP_PKEY*, int, u_char **,
+ int *, const u_char *, size_t);
+int sshkey_verify_signature(EVP_PKEY *, int, const u_char *,
+ size_t, u_char *, int);
int sshkey_from_blob(const u_char *, size_t, struct sshkey **);
int sshkey_fromb(struct sshbuf *, struct sshkey **);

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,
+ kex->session_id, kex->session_id_len);
+ 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

@ -0,0 +1,152 @@
From 063e1a255b53abde1147522f9aceccfd2a7ceb9b Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 2 Mar 2021 19:45:25 +0100
Subject: [PATCH] Unbreak gsi-openssh by not holding the sshbuf structures
originated from incoming packet buffer
Keeping buffers from sshpkt_getb_froms() for breaks further packet
processing because the "derived" buffer keeps a "link" to te parent
buffer, which is then considered readonly.
This addresses the visible issue in the kexgss_server(), which
demonstrated with GSI (requiring more round trips than GSSAPI
with kerberos).
The additional two places in the client were never hit, because the host
keys are never sent as part of the gssapi key exchange but in case we
would have different server or we would start sending hostkeys as the
code is ready for that, we would hit it anyway.
Fixes #18
---
kexgssc.c | 14 ++++++++++++--
kexgsss.c | 48 ++++++++++++++++++++++++++++--------------------
2 files changed, 40 insertions(+), 22 deletions(-)
diff --git a/kexgssc.c b/kexgssc.c
index 1c62740e..29b8b031 100644
--- a/kexgssc.c
+++ b/kexgssc.c
@@ -162,11 +162,16 @@ kexgss_client(struct ssh *ssh)
do {
type = ssh_packet_read(ssh);
if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
+ char *tmp = NULL;
+ size_t tmp_len = 0;
+
debug("Received KEXGSS_HOSTKEY");
if (server_host_key_blob)
fatal("Server host key received more than once");
- if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0)
fatal("Failed to read server host key: %s", ssh_err(r));
+ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL)
+ fatal("sshbuf_from failed");
}
} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
@@ -453,11 +458,16 @@ kexgssgex_client(struct ssh *ssh)
do {
type = ssh_packet_read(ssh);
if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
+ char *tmp = NULL;
+ size_t tmp_len = 0;
+
debug("Received KEXGSS_HOSTKEY");
if (server_host_key_blob)
fatal("Server host key received more than once");
- if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0)
fatal("sshpkt failed: %s", ssh_err(r));
+ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL)
+ fatal("sshbuf_from failed");
}
} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
diff --git a/kexgsss.c b/kexgsss.c
index a2c02148..c8b7d652 100644
--- a/kexgsss.c
+++ b/kexgsss.c
@@ -64,7 +64,7 @@ kexgss_server(struct ssh *ssh)
*/
OM_uint32 ret_flags = 0;
- gss_buffer_desc gssbuf, recv_tok, msg_tok;
+ gss_buffer_desc gssbuf = {0, NULL}, recv_tok, msg_tok;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Gssctxt *ctxt = NULL;
struct sshbuf *shared_secret = NULL;
@@ -104,7 +104,7 @@ kexgss_server(struct ssh *ssh)
type = ssh_packet_read(ssh);
switch(type) {
case SSH2_MSG_KEXGSS_INIT:
- if (client_pubkey != NULL)
+ if (gssbuf.value != NULL)
fatal("Received KEXGSS_INIT after initialising");
if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
&recv_tok)) != 0 ||
@@ -135,6 +135,31 @@ kexgss_server(struct ssh *ssh)
goto out;
/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
+
+ /* Calculate the hash early so we can free the
+ * client_pubkey, which has reference to the parent
+ * buffer state->incoming_packet
+ */
+ hashlen = sizeof(hash);
+ if ((r = kex_gen_hash(
+ kex->hash_alg,
+ kex->client_version,
+ kex->server_version,
+ kex->peer,
+ kex->my,
+ empty,
+ client_pubkey,
+ server_pubkey,
+ shared_secret,
+ hash, &hashlen)) != 0)
+ goto out;
+
+ gssbuf.value = hash;
+ gssbuf.length = hashlen;
+
+ sshbuf_free(client_pubkey);
+ client_pubkey = NULL;
+
break;
case SSH2_MSG_KEXGSS_CONTINUE:
if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
@@ -156,7 +181,7 @@ kexgss_server(struct ssh *ssh)
if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
fatal("Zero length token output when incomplete");
- if (client_pubkey == NULL)
+ if (gssbuf.value == NULL)
fatal("No client public key");
if (maj_status & GSS_S_CONTINUE_NEEDED) {
@@ -185,23 +210,6 @@ kexgss_server(struct ssh *ssh)
if (!(ret_flags & GSS_C_INTEG_FLAG))
fatal("Integrity flag wasn't set");
- hashlen = sizeof(hash);
- if ((r = kex_gen_hash(
- kex->hash_alg,
- kex->client_version,
- kex->server_version,
- kex->peer,
- kex->my,
- empty,
- client_pubkey,
- server_pubkey,
- shared_secret,
- hash, &hashlen)) != 0)
- goto out;
-
- gssbuf.value = hash;
- gssbuf.length = hashlen;
-
if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
fatal("Couldn't get MIC");

View file

@ -1,17 +1,8 @@
From 6aa231d9acfeca870ee87e3bf9c4a1239518706d Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Thu, 15 May 2025 13:43:28 +0200
Subject: [PATCH 32/50] 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 347b2122..344f8a8a 100644
index dca158de..afdcb1d2 100644
--- a/regress/misc/sk-dummy/sk-dummy.c
+++ b/regress/misc/sk-dummy/sk-dummy.c
@@ -81,7 +81,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 347b2122..344f8a8a 100644
sk_api_version(void)
{
return SSH_SK_VERSION_MAJOR;
@@ -230,7 +230,7 @@ check_options(struct sk_option **options)
@@ -220,7 +220,7 @@ check_options(struct sk_option **options)
return 0;
}
@ -29,7 +20,7 @@ index 347b2122..344f8a8a 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)
@@ -478,7 +478,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 347b2122..344f8a8a 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,
@@ -535,7 +535,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 347b2122..344f8a8a 100644
sk_load_resident_keys(const char *pin, struct sk_option **options,
struct sk_resident_key ***rks, size_t *nrks)
{
--
2.49.0

View file

@ -0,0 +1,30 @@
diff --git a/channels.c b/channels.c
--- a/channels.c
+++ b/channels.c
@@ -3933,16 +3933,26 @@ x11_create_display_inet(int x11_display_
if (ai->ai_family == AF_INET6)
sock_set_v6only(sock);
if (x11_use_localhost)
set_reuseaddr(sock);
if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
debug2("%s: bind port %d: %.100s", __func__,
port, strerror(errno));
close(sock);
+
+ /* do not remove successfully opened
+ * sockets if the request failed because
+ * the protocol IPv4/6 is not available
+ * (e.g. IPv6 may be disabled while being
+ * supported)
+ */
+ if (EADDRNOTAVAIL == errno)
+ continue;
+
for (n = 0; n < num_socks; n++)
close(socks[n]);
num_socks = 0;
break;
}
socks[num_socks++] = sock;
if (num_socks == NUM_SOCKS)
break;

View file

@ -0,0 +1,11 @@
diff -up openssh-8.4p1/ssh-agent.c.cve-2021-28041 openssh-8.4p1/ssh-agent.c
--- openssh-8.4p1/ssh-agent.c.cve-2021-28041 2021-06-17 13:15:58.691479334 +0200
+++ openssh-8.4p1/ssh-agent.c 2021-06-17 13:17:16.573118348 +0200
@@ -581,6 +581,7 @@ process_add_identity(SocketEntry *e)
goto err;
}
free(ext_name);
+ ext_name = NULL;
break;
default:
error("%s: Unknown constraint %d", __func__, ctype);

View file

@ -0,0 +1,57 @@
--- compat.h.orig 2020-10-05 10:09:02.953505129 -0700
+++ compat.h 2020-10-05 10:10:17.587733113 -0700
@@ -34,7 +34,7 @@
#define SSH_BUG_UTF8TTYMODE 0x00000001
#define SSH_BUG_SIGTYPE 0x00000002
-/* #define unused 0x00000004 */
+#define SSH_BUG_SIGTYPE74 0x00000004
/* #define unused 0x00000008 */
#define SSH_OLD_SESSIONID 0x00000010
/* #define unused 0x00000020 */
--- compat.c.orig 2020-10-05 10:25:02.088720562 -0700
+++ compat.c 2020-10-05 10:13:11.637282492 -0700
@@ -65,11 +65,12 @@
{ "OpenSSH_6.5*,"
"OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD|
SSH_BUG_SIGTYPE},
+ { "OpenSSH_7.4*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE|
+ SSH_BUG_SIGTYPE74},
{ "OpenSSH_7.0*,"
"OpenSSH_7.1*,"
"OpenSSH_7.2*,"
"OpenSSH_7.3*,"
- "OpenSSH_7.4*,"
"OpenSSH_7.5*,"
"OpenSSH_7.6*,"
"OpenSSH_7.7*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
--- sshconnect2.c.orig 2020-09-26 07:26:37.618010545 -0700
+++ sshconnect2.c 2020-10-05 10:47:22.116315148 -0700
@@ -1305,6 +1305,26 @@
break;
}
free(oallowed);
+ /*
+ * OpenSSH 7.4 supports SHA2 sig types, but fails to indicate its
+ * support. For that release, check the local policy against the
+ * SHA2 signature types.
+ */
+ if (alg == NULL &&
+ (key->type == KEY_RSA && (datafellows & SSH_BUG_SIGTYPE74))) {
+ oallowed = allowed = xstrdup(options.pubkey_key_types);
+ while ((cp = strsep(&allowed, ",")) != NULL) {
+ if (sshkey_type_from_name(cp) != key->type)
+ continue;
+ tmp = match_list(sshkey_sigalg_by_name(cp), "rsa-sha2-256,rsa-sha2-512", NULL);
+ if (tmp != NULL)
+ alg = xstrdup(cp);
+ free(tmp);
+ if (alg != NULL)
+ break;
+ }
+ free(oallowed);
+ }
return alg;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,14 @@
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index e0768c06..5065ae7e 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -267,6 +267,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_pselect6
SC_ALLOW(__NR_pselect6),
#endif
+#ifdef __NR_pselect6_time64
+ SC_ALLOW(__NR_pselect6_time64),
+#endif
#ifdef __NR_read
SC_ALLOW(__NR_read),
#endif

View file

@ -0,0 +1,130 @@
From 66f16e5425eb881570e82bfef7baeac2e7accc0a Mon Sep 17 00:00:00 2001
From: Oleg <Fallmay@users.noreply.github.com>
Date: Thu, 1 Oct 2020 12:09:08 +0300
Subject: [PATCH] Fix `EOF: command not found` error in ssh-copy-id
---
contrib/ssh-copy-id | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id
index 392f64f94..a76907717 100644
--- a/contrib/ssh-copy-id
+++ b/contrib/ssh-copy-id
@@ -247,7 +247,7 @@ installkeys_sh() {
# the -z `tail ...` checks for a trailing newline. The echo adds one if was missing
# the cat adds the keys we're getting via STDIN
# and if available restorecon is used to restore the SELinux context
- INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF)
+ INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF
cd;
umask 077;
mkdir -p $(dirname "${AUTH_KEY_FILE}") &&
@@ -258,6 +258,7 @@ installkeys_sh() {
restorecon -F .ssh ${AUTH_KEY_FILE};
fi
EOF
+ )
# to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
printf "exec sh -c '%s'" "${INSTALLKEYS_SH}"
From de59a431cdec833e3ec15691dd950402b4c052cf Mon Sep 17 00:00:00 2001
From: Philip Hands <phil@hands.com>
Date: Sat, 3 Oct 2020 00:20:07 +0200
Subject: [PATCH] un-nest $() to make ksh cheerful
---
ssh-copy-id | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
From 02ac2c3c3db5478a440dfb1b90d15f686f2cbfc6 Mon Sep 17 00:00:00 2001
From: Philip Hands <phil@hands.com>
Date: Fri, 2 Oct 2020 21:30:10 +0200
Subject: [PATCH] ksh doesn't grok 'local'
and AFAICT it's not actually doing anything useful in the code, so let's
see how things go without it.
---
ssh-copy-id | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id
index a769077..11c9463 100755
--- a/contrib/ssh-copy-id
+++ b/contrib/ssh-copy-id
@@ -76,7 +76,7 @@ quote() {
}
use_id_file() {
- local L_ID_FILE="$1"
+ L_ID_FILE="$1"
if [ -z "$L_ID_FILE" ] ; then
printf '%s: ERROR: no ID file found\n' "$0"
@@ -94,7 +94,7 @@ use_id_file() {
# check that the files are readable
for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do
ErrMSG=$( { : < "$f" ; } 2>&1 ) || {
- local L_PRIVMSG=""
+ L_PRIVMSG=""
[ "$f" = "$PRIV_ID_FILE" ] && L_PRIVMSG=" (to install the contents of '$PUB_ID_FILE' anyway, look at the -f option)"
printf "\\n%s: ERROR: failed to open ID file '%s': %s\\n" "$0" "$f" "$(printf '%s\n%s\n' "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')"
exit 1
@@ -169,7 +169,7 @@ fi
# populate_new_ids() uses several global variables ($USER_HOST, $SSH_OPTS ...)
# and has the side effect of setting $NEW_IDS
populate_new_ids() {
- local L_SUCCESS="$1"
+ L_SUCCESS="$1"
# shellcheck disable=SC2086
if [ "$FORCED" ] ; then
@@ -181,13 +181,12 @@ populate_new_ids() {
eval set -- "$SSH_OPTS"
umask 0177
- local L_TMP_ID_FILE
L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX)
if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then
printf '%s: ERROR: mktemp failed\n' "$0" >&2
exit 1
fi
- local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\""
+ L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\""
# shellcheck disable=SC2064
trap "$L_CLEANUP" EXIT TERM INT QUIT
printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2
@@ -237,7 +236,7 @@ populate_new_ids() {
# produce a one-liner to add the keys to remote authorized_keys file
# optionally takes an alternative path for authorized_keys
installkeys_sh() {
- local AUTH_KEY_FILE=${1:-.ssh/authorized_keys}
+ AUTH_KEY_FILE=${1:-.ssh/authorized_keys}
# In setting INSTALLKEYS_SH:
# the tr puts it all on one line (to placate tcsh)
--
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id
index 11c9463..ee3f637 100755
--- a/contrib/ssh-copy-id
+++ b/contrib/ssh-copy-id
@@ -237,6 +237,7 @@ populate_new_ids() {
# optionally takes an alternative path for authorized_keys
installkeys_sh() {
AUTH_KEY_FILE=${1:-.ssh/authorized_keys}
+ AUTH_KEY_DIR=$(dirname "${AUTH_KEY_FILE}")
# In setting INSTALLKEYS_SH:
# the tr puts it all on one line (to placate tcsh)
@@ -249,7 +250,7 @@ installkeys_sh() {
INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF
cd;
umask 077;
- mkdir -p $(dirname "${AUTH_KEY_FILE}") &&
+ mkdir -p "${AUTH_KEY_DIR}" &&
{ [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] || echo >> ${AUTH_KEY_FILE} || exit 1; } &&
cat >> ${AUTH_KEY_FILE} ||
exit 1;
--

View file

@ -0,0 +1,25 @@
diff --git a/auth.c b/auth.c
index b8d1040d..0134d694 100644
--- a/auth.c
+++ b/auth.c
@@ -56,6 +56,7 @@
# include <paths.h>
#endif
#include <pwd.h>
+#include <grp.h>
#ifdef HAVE_LOGIN_H
#include <login.h>
#endif
@@ -2695,6 +2696,12 @@ subprocess(const char *tag, const char *command,
}
closefrom(STDERR_FILENO + 1);
+ if (geteuid() == 0 &&
+ initgroups(pw->pw_name, pw->pw_gid) == -1) {
+ error("%s: initgroups(%s, %u): %s", tag,
+ pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
+ _exit(1);
+ }
/* Don't use permanently_set_uid() here to avoid fatal() */
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) {
error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,

View file

@ -1,3 +1,3 @@
SHA512 (openssh-10.0p1.tar.gz) = 2daa1fcf95793b23810142077e68ddfabdf3732b207ef4f033a027f72d733d0e9bcdb6f757e7f3a5934b972de05bfaae3baae381cfc7a400cd8ab4d4e277a0ed
SHA512 (openssh-10.0p1.tar.gz.asc) = 6ab9deb4233ff159e55a18c9fc07d5ff8a41723dad74aa3d803e1476b585f5662aba34f8a7a1f5fe1d248f3ff3cd663f2c2fb8e399c6a4723b6215b0eb423d13
SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21
SHA512 (openssh-8.4p1.tar.gz) = d65275b082c46c5efe7cf3264fa6794d6e99a36d4a54b50554fc56979d6c0837381587fd5399195e1db680d2a5ad1ef0b99a180eac2b4de5637906cb7a89e9ce
SHA512 (openssh-8.4p1.tar.gz.asc) = 3d9a026db27729a5a56785db3824230ccf2a3beca4bb48ef465e44d869b944dbc5d443152a1b1be21bc9c213c465d3d7ca1f876a387d0a6b9682a0cfec3e6e32
SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d