Rebase OpenSSH to 9.8p1

Resolves: RHEL-42635
This commit is contained in:
Dmitry Belyavskiy 2024-07-25 12:54:19 +02:00
parent 9195080dcb
commit 089d798931
32 changed files with 2483 additions and 690 deletions

2
.gitignore vendored
View File

@ -60,3 +60,5 @@ pam_ssh_agent_auth-0.9.2.tar.bz2
/openssh-9.3p1.tar.gz.asc
/openssh-9.6p1.tar.gz
/openssh-9.6p1.tar.gz.asc
/openssh-9.8p1.tar.gz
/openssh-9.8p1.tar.gz.asc

View File

@ -237,11 +237,11 @@ diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-serve
- return (sftp_server_main(argc, argv, user_pw));
+ return (sftp_server_main(argc, argv, user_pw, 0));
}
diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c
--- openssh-8.6p1/sshd.c.log-in-chroot 2021-04-19 14:43:08.543843426 +0200
+++ openssh-8.6p1/sshd.c 2021-04-19 14:43:08.545843441 +0200
diff -up openssh-8.6p1/sshd-session.c.log-in-chroot openssh-8.6p1/sshd-session.c
--- openssh-8.6p1/sshd-session.c.log-in-chroot 2021-04-19 14:43:08.543843426 +0200
+++ openssh-8.6p1/sshd-session.c 2021-04-19 14:43:08.545843441 +0200
@@ -559,7 +559,7 @@ privsep_postauth(struct ssh *ssh, Authct
}
#endif
/* New socket pair */
- monitor_reinit(pmonitor);

View File

@ -116,10 +116,10 @@ index cb51f99..8b7cda2 100644
#endif
#ifdef LINUX_OOM_ADJUST
diff --git a/sshd.c b/sshd.c
diff --git a/sshd-session.c b/sshd-session.c
index 2871fe9..39b9c08 100644
--- a/sshd.c
+++ b/sshd.c
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -629,7 +629,7 @@ privsep_preauth_child(void)
demote_sensitive_data();

View File

@ -38,16 +38,16 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -418,7 +421,7 @@ typedef enum {
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
@@ -578,7 +578,7 @@ typedef enum {
sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
sPerSourcePenalties, sPerSourcePenaltyExemptList,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
- sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
+ sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
@@ -497,14 +500,16 @@ static struct {
@@ -600,14 +600,16 @@ static struct {
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
@ -129,3 +129,6 @@ diff -up openssh-7.4p1/sshd_config.GSSAPIEnablek5users openssh-7.4p1/sshd_config
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
diff -up openssh-9.8p1/servconf.c.xxx openssh-9.8p1/servconf.c
--- openssh-9.8p1/servconf.c.xxx 2024-07-11 13:51:19.969960781 +0200
+++ openssh-9.8p1/servconf.c 2024-07-11 13:51:30.938231250 +0200

View File

@ -1,6 +1,6 @@
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
--- openssh/sshd-session.c.ip-opts 2016-07-25 13:58:48.998507834 +0200
+++ openssh/sshd-session.c 2016-07-25 14:01:28.346469878 +0200
@@ -1507,12 +1507,32 @@ check_ip_options(struct ssh *ssh)
if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts,

View File

@ -39,9 +39,9 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in
SFTP_SERVER=$(libexecdir)/sftp-server
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
+SSH_KEYCAT=$(libexecdir)/ssh-keycat
SSHD_SESSION=$(libexecdir)/sshd-session
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper
PRIVSEP_PATH=@PRIVSEP_PATH@
@@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@
K5LIBS=@K5LIBS@
GSSLIBS=@GSSLIBS@
@ -54,8 +54,8 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in
.SUFFIXES: .lo
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT)
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT)
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) 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) sshd-session$(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 \
@ -95,8 +95,8 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/
--- 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 Authctxt *the_authctxt;
extern int inetd_flag;
extern int rexeced_flag;
+/* Wrapper around is_selinux_enabled() to log its return value once only */
+int
@ -131,7 +131,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/
- rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
+ rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
if (inetd_flag && !rexeced_flag) {
if (inetd_flag) {
use_current = "1";
} else {
use_current = "";

View File

@ -266,8 +266,8 @@ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5
+The default is
+.Cm yes .
.It Cm KexAlgorithms
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
@@ -1078,6 +1082,7 @@ Available keywords are
.Cm IPQoS ,
.Cm KbdInteractiveAuthentication ,

View File

@ -49,7 +49,7 @@ diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c
platform_setusercontext(pw);
- if (platform_privileged_uidswap()) {
+ if (platform_privileged_uidswap() && (!is_child || !use_privsep)) {
+ if (platform_privileged_uidswap() && !is_child) {
#ifdef HAVE_LOGIN_CAP
if (setusercontext(lc, pw, pw->pw_uid,
(LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
@ -96,8 +96,8 @@ diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c
}
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
--- openssh-7.4p1/sshd-session.c.privsep-selinux 2016-12-23 18:58:52.973122201 +0100
+++ openssh-7.4p1/sshd-session.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();
@ -109,13 +109,12 @@ diff -up openssh-7.4p1/sshd.c.privsep-selinux openssh-7.4p1/sshd.c
/* 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) {
@@ -403,7 +403,7 @@ privsep_postauth(struct ssh *ssh, Authct
* 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

View File

@ -27,7 +27,7 @@ diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c
-
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
cp = strncpy(s, kex, strlen(kex));
+#pragma pop
+#pragma GCC diagnostic pop
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (sshbuf_len(buf) != 0 &&
@ -221,9 +221,9 @@ diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c
return NULL;
}
/* validate also provider from URI */
diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
--- openssh-7.4p1/sshd.c.coverity 2016-12-23 16:40:26.897788690 +0100
+++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100
diff -up openssh-7.4p1/sshd-session.c.coverity openssh-7.4p1/sshd-session.c
--- openssh-7.4p1/sshd-session.c.coverity 2016-12-23 16:40:26.897788690 +0100
+++ openssh-7.4p1/sshd-session.c 2016-12-23 16:40:26.904788692 +0100
@@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt)
privsep_preauth_child(ssh);

View File

@ -109,7 +109,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
@@ -717,6 +728,8 @@ do_exec(Session *s, const char *command)
}
if (s->command != NULL && s->ptyfd == -1)
s->command_handle = PRIVSEP(audit_run_command(ssh, s->command));
s->command_handle = mm_audit_run_command(ssh, s->command);
+ if (pipe(paudit) < 0)
+ fatal("pipe: %s", strerror(errno));
#endif
@ -121,7 +121,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
+#ifdef SSH_AUDIT_EVENTS
+ close(paudit[1]);
+ if (use_privsep && ret == 0) {
+ if (ret == 0) {
+ /*
+ * Read the audit messages from forked child and send them
+ * back to monitor. We don't want to communicate directly,
@ -136,7 +136,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
return ret;
}
@@ -1538,6 +1565,34 @@ child_close_fds(void)
@@ -1538,6 +1565,33 @@ child_close_fds(void)
log_redirect_stderr_to(NULL);
}
@ -147,12 +147,11 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
+ int pparent = paudit[1];
+ close(paudit[0]);
+ /* Hack the monitor pipe to avoid race condition with parent */
+ if (use_privsep)
+ mm_set_monitor_pipe(pparent);
+ mm_set_monitor_pipe(pparent);
+#endif
+
+ /* remove hostkey from the child's memory */
+ destroy_sensitive_data(ssh, use_privsep);
+ destroy_sensitive_data(ssh);
+ /*
+ * We can audit this, because we hacked the pipe to direct the
+ * messages over postauth child. But this message requires answer
@ -176,7 +175,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
- /* remove hostkey from the child's memory */
- destroy_sensitive_data(ssh, 1);
- destroy_sensitive_data(ssh);
- ssh_packet_clear_keys(ssh);
- /* Don't audit this - both us and the parent would be talking to the
- monitor over a single socket, with no synchronization. */

View File

@ -11,8 +11,8 @@ diff --git a/channels.c b/channels.c
int sock;
struct sockaddr_un addr;
+ if (len <= 0)
+ return -1;
+ if (len <= 0)
+ return -1;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
error("socket: %.100s", strerror(errno));

View File

@ -2,7 +2,7 @@ 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 "*"
#define NUM_SOCKS 10
/* -- X11 forwarding */
-/* Maximum number of fake X11 displays to try. */

View File

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

View File

@ -129,19 +129,19 @@ diff -up openssh-8.6p1/audit.c.audit openssh-8.6p1/audit.c
+void
+audit_unsupported(struct ssh *ssh, int what)
+{
+ PRIVSEP(audit_unsupported_body(ssh, what));
+ mm_audit_unsupported_body(ssh, what);
+}
+
+void
+audit_kex(struct ssh *ssh, int ctos, char *enc, char *mac, char *comp, char *pfs)
+{
+ PRIVSEP(audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid()));
+ mm_audit_kex_body(ssh, ctos, enc, mac, comp, pfs, getpid(), getuid());
+}
+
+void
+audit_session_key_free(struct ssh *ssh, int ctos)
+{
+ PRIVSEP(audit_session_key_free_body(ssh, ctos, getpid(), getuid()));
+ mm_audit_session_key_free_body(ssh, ctos, getpid(), getuid());
+}
+
# ifndef CUSTOM_SSH_AUDIT_EVENTS
@ -446,7 +446,7 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c
/* Below is the sshd audit API code */
void
@@ -76,49 +176,210 @@ audit_connection_from(const char *host,
@@ -76,49 +176,211 @@ audit_connection_from(const char *host,
/* not implemented */
}
@ -525,6 +525,7 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c
case SSH_AUTH_FAIL_PASSWD:
+ if (options.use_pam)
+ break;
+ /* Fallthrough */
+ case SSH_LOGIN_EXCEED_MAXTRIES:
case SSH_AUTH_FAIL_KBDINT:
case SSH_AUTH_FAIL_PUBKEY:
@ -564,7 +565,7 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c
+{
+#ifdef AUDIT_CRYPTO_SESSION
+ char buf[AUDIT_LOG_SIZE];
+ const static char *name[] = { "cipher", "mac", "comp" };
+ static const char *name[] = { "cipher", "mac", "comp" };
+ char *s;
+ int audit_fd;
+
@ -582,7 +583,7 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c
+#endif
+}
+
+const static char *direction[] = { "from-server", "from-client", "both" };
+static const char *direction[] = { "from-server", "from-client", "both" };
+
+void
+audit_kex_body(struct ssh *ssh, int ctos, char *enc, char *mac, char *compress,
@ -661,7 +662,7 @@ diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c
+ }
+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
+ buf, NULL,
+ listening_for_clients() ? NULL : ssh_remote_ipaddr(ssh),
+ ssh_remote_ipaddr(ssh), /*FIXME listening_for_clients() ? NULL : ssh_remote_ipaddr(ssh) */
+ NULL, 1);
+ audit_close(audit_fd);
+ /* do not abort if the error is EPERM and sshd is run as non root user */
@ -733,7 +734,7 @@ diff -up openssh-8.6p1/auth2.c.audit openssh-8.6p1/auth2.c
/* Invalid user, fake password information */
authctxt->pw = fakepw();
-#ifdef SSH_AUDIT_EVENTS
- PRIVSEP(audit_event(ssh, SSH_INVALID_USER));
- mm_audit_event(ssh, SSH_INVALID_USER);
-#endif
}
#ifdef USE_PAM
@ -743,11 +744,11 @@ diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c
+++ openssh-8.6p1/auth2-hostbased.c 2021-04-19 16:47:35.754062114 +0200
@@ -158,7 +158,7 @@ userauth_hostbased(struct ssh *ssh)
authenticated = 0;
if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser,
chost, key)) &&
- PRIVSEP(sshkey_verify(key, sig, slen,
+ PRIVSEP(hostbased_key_verify(ssh, key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0)
if (mm_hostbased_key_allowed(ssh, authctxt->pw, cuser,
chost, key) &&
- mm_sshkey_verify(key, sig, slen,
+ mm_hostbased_key_verify(ssh, key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL) == 0)
authenticated = 1;
@@ -175,6 +175,20 @@ done:
@ -777,12 +778,12 @@ diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c
@@ -213,7 +213,7 @@ userauth_pubkey(struct ssh *ssh)
/* test for correct signature */
authenticated = 0;
if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) &&
- PRIVSEP(sshkey_verify(key, sig, slen,
+ PRIVSEP(user_key_verify(ssh, key, sig, slen,
if (mm_user_key_allowed(ssh, pw, key, 1, &authopts) &&
- mm_sshkey_verify(key, sig, slen,
+ mm_user_key_verify(ssh, key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b),
(ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL,
ssh->compat, &sig_details)) == 0) {
ssh->compat, &sig_details) == 0) {
@@ -305,6 +305,20 @@ done:
return authenticated;
}
@ -828,7 +829,7 @@ diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h
+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
/* Key / cert options linkage to auth layer */
const struct sshauthopt *auth_options(struct ssh *);
int auth_activate_options(struct ssh *, struct sshauthopt *);
@@ -239,6 +241,8 @@ struct passwd * getpwnamallow(struct ssh
char *, const char *, const char *, const char *, struct sshauthopt **);
int auth_check_authkeys_file(struct passwd *, FILE *, char *,
@ -915,8 +916,8 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c
#include "xmalloc.h"
+#include "audit.h"
#ifdef GSSAPI
#include "ssh-gss.h"
/* prototype */
static int kex_choose_conf(struct ssh *, uint32_t seq);
@@ -816,12 +817,16 @@ kex_start_rekex(struct ssh *ssh)
}
@ -1108,7 +1109,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c
extern struct sshbuf *loginmsg;
extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */
+extern void destroy_sensitive_data(struct ssh *, int);
+extern void destroy_sensitive_data(struct ssh *);
+
/* State exported from the child */
static struct sshbuf *child_state;
@ -1241,7 +1242,7 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c
sshpam_cleanup();
#endif
+ destroy_sensitive_data(ssh, 0);
+ destroy_sensitive_data(ssh);
+
while (waitpid(pmonitor->m_pid, &status, 0) == -1)
if (errno != EINTR)
@ -1536,9 +1537,9 @@ diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c
}
#endif /* SSH_AUDIT_EVENTS */
@@ -1095,3 +1137,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc
return &ci;
}
#endif /* GSSAPI */
+#ifdef SSH_AUDIT_EVENTS
+void
+mm_audit_unsupported_body(struct ssh *ssh, int what)
@ -1632,7 +1633,7 @@ diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h
+int mm_user_key_verify(struct ssh*, const struct sshkey *, const u_char *, size_t,
const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
#ifdef GSSAPI
void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m);
@@ -86,7 +88,12 @@ void mm_sshpam_free_ctx(void *);
#ifdef SSH_AUDIT_EVENTS
#include "audit.h"
@ -1817,7 +1818,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c
extern u_int utmp_len;
extern int startup_pipe;
-extern void destroy_sensitive_data(void);
+extern void destroy_sensitive_data(struct ssh *, int);
+extern void destroy_sensitive_data(struct ssh *);
extern struct sshbuf *loginmsg;
extern struct sshauthopt *auth_opts;
extern char *tun_fwd_ifnames; /* serverloop.c */
@ -1843,18 +1844,18 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c
+ if (s->command != NULL || s->command_handle != -1)
+ fatal("do_exec: command already set");
if (command != NULL)
- PRIVSEP(audit_run_command(command));
- mm_audit_run_command(command);
+ s->command = xstrdup(command);
else if (s->ttyfd == -1) {
char *shell = s->pw->pw_shell;
if (shell[0] == '\0') /* empty shell means /bin/sh */
shell =_PATH_BSHELL;
- PRIVSEP(audit_run_command(shell));
- mm_audit_run_command(shell);
+ s->command = xstrdup(shell);
}
+ if (s->command != NULL && s->ptyfd == -1)
+ s->command_handle = PRIVSEP(audit_run_command(ssh, s->command));
+ s->command_handle = mm_audit_run_command(ssh, s->command);
#endif
if (s->ttyfd != -1)
ret = do_exec_pty(ssh, s, command);
@ -1863,7 +1864,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c
/* remove hostkey from the child's memory */
- destroy_sensitive_data();
+ destroy_sensitive_data(ssh, 1);
+ destroy_sensitive_data(ssh);
ssh_packet_clear_keys(ssh);
+ /* Don't audit this - both us and the parent would be talking to the
+ monitor over a single socket, with no synchronization. */
@ -1923,7 +1924,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c
+{
+ if (s->command != NULL) {
+ if (s->command_handle != -1)
+ PRIVSEP(audit_end_command(ssh, s->command_handle, s->command));
+ mm_audit_end_command(ssh, s->command_handle, s->command);
+ free(s->command);
+ s->command = NULL;
+ s->command_handle = -1;
@ -1981,7 +1982,7 @@ diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c
@@ -2734,7 +2804,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au
* or if running in monitor.
*/
if (!use_privsep || mm_is_monitor())
if (mm_is_monitor())
- session_destroy_all(ssh, session_pty_cleanup2);
+ session_destroy_all(ssh, do_cleanup_one_session);
}
@ -2020,25 +2021,6 @@ diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h
diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
--- openssh-8.6p1/sshd.c.audit 2021-04-19 16:47:35.727061907 +0200
+++ openssh-8.6p1/sshd.c 2021-04-19 16:47:35.759062152 +0200
@@ -122,6 +122,7 @@
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
+#include "audit.h"
#include "ssh-sandbox.h"
#include "auth-options.h"
#include "version.h"
@@ -260,8 +261,8 @@ struct sshbuf *loginmsg;
struct passwd *privsep_pw = NULL;
/* Prototypes for various functions defined later in this file. */
-void destroy_sensitive_data(void);
-void demote_sensitive_data(void);
+void destroy_sensitive_data(struct ssh *, int);
+void demote_sensitive_data(struct ssh *);
static void do_ssh2_kex(struct ssh *);
static char *listener_proctitle;
@@ -279,6 +280,15 @@ close_listen_socks(void)
num_listen_socks = 0;
}
@ -2052,11 +2034,41 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
+ return num_listen_socks > 0;
+}
+
/* Allocate and initialise the children array */
static void
close_startup_pipes(void)
{
@@ -377,18 +387,45 @@ grace_alarm_handler(int sig)
ssh_remote_port(the_active_state));
child_alloc(void)
@@ -1204,6 +1259,7 @@ server_accept_loop(int *sock_in, int *so
if (received_sigterm) {
logit("Received signal %d; terminating.",
(int) received_sigterm);
+ /* destroy_sensitive_data(ssh, 0); FIXME */
close_listen_socks();
if (options.pid_file != NULL)
unlink(options.pid_file);
diff -up openssh-8.6p1/sshd-session.c.audit openssh-8.6p1/sshd-session.c
--- openssh-8.6p1/sshd-session.c.audit 2021-04-19 16:47:35.727061907 +0200
+++ openssh-8.6p1/sshd-session.c 2021-04-19 16:47:35.759062152 +0200
@@ -122,6 +122,7 @@
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
+#include "audit.h"
#include "ssh-sandbox.h"
#include "auth-options.h"
#include "version.h"
@@ -260,8 +261,8 @@ struct sshbuf *loginmsg;
struct sshbuf *loginmsg;
/* Prototypes for various functions defined later in this file. */
-void destroy_sensitive_data(void);
-void demote_sensitive_data(void);
+void destroy_sensitive_data(struct ssh *);
+void demote_sensitive_data(struct ssh *);
static void do_ssh2_kex(struct ssh *);
/*
@@ -377,18 +387,40 @@ grace_alarm_handler(int sig)
_exit(EXIT_LOGIN_GRACE);
}
-/* Destroy the host and server keys. They will no longer be needed. */
@ -2066,7 +2078,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
+ */
void
-destroy_sensitive_data(void)
+destroy_sensitive_data(struct ssh *ssh, int privsep)
+destroy_sensitive_data(struct ssh *ssh)
{
u_int i;
+#ifdef SSH_AUDIT_EVENTS
@ -2088,12 +2100,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
sensitive_data.host_keys[i] = NULL;
+ if (fp != NULL) {
+#ifdef SSH_AUDIT_EVENTS
+ if (privsep)
+ PRIVSEP(audit_destroy_sensitive_data(ssh, fp,
+ pid, uid));
+ else
+ audit_destroy_sensitive_data(ssh, fp,
+ pid, uid);
+ audit_destroy_sensitive_data(ssh, fp, pid, uid);
+#endif
+ free(fp);
+ }
@ -2163,9 +2170,9 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
#ifdef WITH_SELINUX
sshd_selinux_change_privsep_preauth_context();
@@ -492,7 +547,7 @@ privsep_preauth(struct ssh *ssh)
pmonitor->m_pkex = &ssh->kex;
if (use_privsep == PRIVSEP_ON)
box = ssh_sandbox_init(pmonitor);
box = ssh_sandbox_init(pmonitor);
- pid = fork();
+ pmonitor->m_pid = pid = fork();
if (pid == -1) {
@ -2189,48 +2196,21 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
reseed_prngs();
@@ -1143,7 +1198,7 @@ server_listen(void)
* from this function are in a forked subprocess.
*/
static void
-server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
+server_accept_loop(struct ssh *ssh, int *sock_in, int *sock_out, int *newsock, int *config_s)
{
struct pollfd *pfd = NULL;
int i, j, ret, npfd;
@@ -1204,6 +1259,7 @@ server_accept_loop(int *sock_in, int *so
if (received_sigterm) {
logit("Received signal %d; terminating.",
(int) received_sigterm);
+ destroy_sensitive_data(ssh, 0);
close_listen_socks();
if (options.pid_file != NULL)
unlink(options.pid_file);
@@ -2098,7 +2154,7 @@ main(int ac, char **av)
#endif
/* Accept a connection and return in a forked child */
- server_accept_loop(&sock_in, &sock_out,
+ server_accept_loop(ssh, &sock_in, &sock_out,
&newsock, config_s);
}
@@ -2333,6 +2389,9 @@ main(int ac, char **av)
do_authenticated(ssh, authctxt);
/* The connection has been terminated. */
+ packet_destroy_all(ssh, 1, 1);
+ destroy_sensitive_data(ssh, 1);
+ destroy_sensitive_data(ssh);
+
ssh_packet_get_bytes(ssh, &ibytes, &obytes);
verbose("Transferred: sent %llu, received %llu bytes",
(unsigned long long)obytes, (unsigned long long)ibytes);
@@ -2513,6 +2572,15 @@ do_ssh2_kex(struct ssh *ssh)
@@ -2513,6 +2572,14 @@ do_ssh2_kex(struct ssh *ssh)
void
cleanup_exit(int i)
{
+ static int in_cleanup = 0;
+ int is_privsep_child;
+
+ /* cleanup_exit can be called at the very least from the privsep
+ wrappers used for auditing. Make sure we don't recurse
@ -2238,24 +2218,17 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
+ if (in_cleanup)
+ _exit(i);
+ in_cleanup = 1;
extern int auth_attempted; /* monitor.c */
if (the_active_state != NULL && the_authctxt != NULL) {
do_cleanup(the_active_state, the_authctxt);
if (use_privsep && privsep_is_preauth &&
@@ -2525,9 +2593,16 @@ cleanup_exit(int i)
}
}
}
+ is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0;
+ if (sensitive_data.host_keys != NULL && the_active_state != NULL)
+ destroy_sensitive_data(the_active_state, is_privsep_child);
+ if (the_active_state != NULL)
+ packet_destroy_all(the_active_state, 1, is_privsep_child);
@@ -2525,7 +2593,9 @@ cleanup_exit(int i)
_exit(EXIT_AUTH_ATTEMPTED);
#ifdef SSH_AUDIT_EVENTS
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
- if (the_active_state != NULL && (!use_privsep || mm_is_monitor()))
- if (the_active_state != NULL && mm_is_monitor())
+ if (the_active_state != NULL &&
+ (the_authctxt == NULL || !the_authctxt->authenticated) &&
+ (!use_privsep || mm_is_monitor()))
+ mm_is_monitor())
audit_event(the_active_state, SSH_CONNECTION_ABANDON);
#endif
_exit(i);

View File

@ -1,23 +1,22 @@
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 @@
@@ -72,6 +72,8 @@
/* import */
extern ServerOptions options;
+extern int inetd_flag;
+extern int rexeced_flag;
+extern Authctxt *the_authctxt;
extern struct authmethod_cfg methodcfg_pubkey;
static char *
format_key(const struct sshkey *key)
@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
ac, av, &f,
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
+ runas_pw, temporarily_use_uid, restore_uid,
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
+ inetd_flag, the_authctxt)) == 0)
goto out;
uid_swapped = 1;
@ -27,7 +26,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
+ runas_pw, temporarily_use_uid, restore_uid,
+ (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
+ inetd_flag, the_authctxt)) == 0)
goto out;
uid_swapped = 1;
@ -82,14 +81,13 @@ diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/por
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 @@
@@ -49,10 +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
@ -128,7 +126,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
if (r == 0) {
/* If launched from xinetd, we must use current level */
- if (inetd_flag && !rexeced_flag) {
- if (inetd_flag) {
+ if (inetd) {
security_context_t sshdsc=NULL;
@ -152,7 +150,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
- if (inetd_flag && !rexeced_flag) {
- if (inetd_flag) {
+ if (inetd) {
use_current = "1";
} else {
@ -216,55 +214,45 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
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 @@
@@ -32,6 +32,8 @@
#include "openbsd-compat/openbsd-compat.h"
extern int use_privsep;
extern ServerOptions options;
+extern int inetd_flag;
+extern int rexeced_flag;
+extern Authctxt *the_authctxt;
void
platform_pre_listen(void)
/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
int
@@ -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,
+ inetd_flag, do_pam_putenv, the_authctxt,
+ options.use_pam);
#endif
}
diff -up openssh/sshd.c.refactor openssh/sshd.c
--- openssh/sshd.c.refactor 2019-04-04 13:19:12.275822068 +0200
+++ openssh/sshd.c 2019-04-04 13:19:51.270195262 +0200
diff -up openssh/sshd-session.c.refactor openssh/sshd-session.c
--- openssh/sshd-session.c.refactor 2019-04-04 13:19:12.275822068 +0200
+++ openssh/sshd-session.c 2019-04-04 13:19:51.270195262 +0200
@@ -158,7 +158,7 @@ int debug_flag = 0;
static int test_flag = 0;
int debug_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;
/* debug goes to stderr unless inetd_flag is set */
static int log_stderr = 0;
@@ -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,
+ inetd_flag, do_pam_putenv, the_authctxt,
+ options.use_pam);
#endif
#ifdef USE_PAM

View File

@ -72,17 +72,17 @@ diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h
u_int dh_estimate(int);
void dh_set_moduli_file(const char *);
diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c
--- openssh-8.6p1/kex.c.fips 2021-05-06 12:08:36.489926807 +0200
+++ openssh-8.6p1/kex.c 2021-05-06 12:08:36.498926877 +0200
diff -up openssh-8.6p1/kex-names.c.fips openssh-8.6p1/kex-names.c
--- openssh-8.6p1/kex-names.c.fips 2021-05-06 12:08:36.489926807 +0200
+++ openssh-8.6p1/kex-names.c 2021-05-06 12:08:36.498926877 +0200
@@ -39,6 +39,7 @@
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
+#include <openssl/fips.h>
#include <openssl/dh.h>
# ifdef HAVE_EVP_KDF_CTX_NEW_ID
# include <openssl/kdf.h>
#include <openssl/evp.h>
#endif
@@ -203,7 +203,10 @@ kex_names_valid(const char *names)
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
@ -361,8 +361,8 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
#include <stdio.h>
#include <stdlib.h>
@@ -77,6 +78,7 @@
#include <openssl/dh.h>
#include <openssl/bn.h>
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
#include <openssl/rand.h>
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
@ -393,7 +393,18 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
/*
* Chdir to the root directory so that the current disk can be
* unmounted if desired.
@@ -2494,10 +2501,14 @@ do_ssh2_kex(struct ssh *ssh)
diff -up openssh-8.6p1/sshd-session.c.fips openssh-8.6p1/sshd-session.c
--- a/sshd-session.c.fips 2021-05-06 12:08:36.493926838 +0200
+++ b/sshd-session.c 2021-05-06 12:13:56.501492639 +0200
@@ -78,6 +79,7 @@
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
#endif
@@ -2506,10 +2513,14 @@ do_ssh2_kex(struct ssh *ssh)
if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
orig = NULL;
@ -475,11 +486,11 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
*lenp = 0;
if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ /* Fallthrough */
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ /* Fallthrough */
if ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
if ((r = sshkey_unshield_private(key)) != 0)
@ -487,10 +498,10 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
*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 (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,

View File

@ -368,7 +368,7 @@ diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c
+ if (gssapi_client.store.envval == NULL)
return;
ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
ok = mm_ssh_gssapi_update_creds(&gssapi_client.store);
diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
--- openssh-8.6p1/gss-serv-krb5.c.ccache_name 2021-04-19 14:05:10.852744562 +0200
+++ openssh-8.6p1/gss-serv-krb5.c 2021-04-19 14:05:10.854744577 +0200
@ -579,9 +579,9 @@ diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c
child_set_env(&env, &envsize, "KRB5CCNAME",
s->authctxt->krb5_ccname);
#endif
diff -up openssh-8.6p1/sshd.c.ccache_name openssh-8.6p1/sshd.c
--- openssh-8.6p1/sshd.c.ccache_name 2021-04-19 14:05:10.849744540 +0200
+++ openssh-8.6p1/sshd.c 2021-04-19 14:05:10.855744584 +0200
diff -up openssh-8.6p1/sshd-session.c.ccache_name openssh-8.6p1/sshd-session.c
--- openssh-8.6p1/sshd-session.c.ccache_name 2021-04-19 14:05:10.849744540 +0200
+++ openssh-8.6p1/sshd-session.c 2021-04-19 14:05:10.855744584 +0200
@@ -2284,7 +2284,7 @@ main(int ac, char **av)
#ifdef GSSAPI
if (options.gss_authentication) {
@ -607,8 +607,8 @@ diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5
+can lead to overwriting previous tickets by subseqent connections to the same
+user account.
.It Cm KexAlgorithms
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
diff -up openssh-8.6p1/ssh-gss.h.ccache_name openssh-8.6p1/ssh-gss.h
--- openssh-8.6p1/ssh-gss.h.ccache_name 2021-04-19 14:05:10.852744562 +0200
+++ openssh-8.6p1/ssh-gss.h 2021-04-19 14:05:10.855744584 +0200

View File

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

View File

@ -23,20 +23,17 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c
if ((style = strchr(user, ':')) != NULL)
*style++ = 0;
@@ -314,8 +314,15 @@ input_userauth_request(int type, u_int32
use_privsep ? " [net]" : "");
@@ -314,7 +314,13 @@ input_userauth_request(int type, u_int32
setproctitle("%s [net]", authctxt->valid ? user : "unknown");
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);
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");
@ -50,7 +47,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
+ char *micuser;
struct sshbuf *b;
gss_buffer_desc mic, gssbuf;
const char *displayname;
u_char *p;
@@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple
fatal_f("sshbuf_new failed");
mic.value = p;
@ -74,7 +71,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
+ free(micuser);
free(mic.value);
if ((!use_privsep || mm_is_monitor()) &&
authctxt->postponed = 0;
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
@ -147,7 +144,7 @@ diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h
+++ 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_setcred(void);
void do_pam_chauthtok(void);
-int do_pam_putenv(char *, char *);
+int do_pam_putenv(char *, const char *);
@ -418,7 +415,7 @@ diff -up openssh/openbsd-compat/port-linux.h.role-mls openssh/openbsd-compat/por
diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compat/port-linux-sshd.c
--- openssh/openbsd-compat/port-linux-sshd.c.role-mls 2018-08-22 11:14:56.819430949 +0200
+++ openssh/openbsd-compat/port-linux-sshd.c 2018-08-22 11:14:56.819430949 +0200
@@ -0,0 +1,421 @@
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
+ * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com>
@ -472,7 +469,6 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa
+extern ServerOptions options;
+extern Authctxt *the_authctxt;
+extern int inetd_flag;
+extern int rexeced_flag;
+
+/* Send audit message */
+static int
@ -678,7 +674,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa
+
+ if (r == 0) {
+ /* If launched from xinetd, we must use current level */
+ if (inetd_flag && !rexeced_flag) {
+ if (inetd_flag) {
+ security_context_t sshdsc=NULL;
+
+ if (getcon_raw(&sshdsc) < 0)
@ -752,7 +748,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa
+
+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
+
+ if (inetd_flag && !rexeced_flag) {
+ if (inetd_flag) {
+ use_current = "1";
+ } else {
+ use_current = "";
@ -853,8 +849,8 @@ diff -up openssh/platform.c.role-mls openssh/platform.c
}
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
--- openssh/sshd-session.c.role-mls 2018-08-20 07:57:29.000000000 +0200
+++ openssh/sshd-session.c 2018-08-22 11:14:56.820430957 +0200
@@ -2186,6 +2186,9 @@ main(int ac, char **av)
restore_uid();
}
@ -864,4 +860,4 @@ diff -up openssh/sshd.c.role-mls openssh/sshd.c
+#endif
#ifdef USE_PAM
if (options.use_pam) {
do_pam_setcred(1);
do_pam_setcred();

View File

@ -155,7 +155,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.It Cm HostKeyAlias
Specifies an alias that should be used instead of the
real host name when looking up or saving the host key
@@ -1232,30 +1229,25 @@
@@ -1330,6 +1330,11 @@ it may be zero or more of:
and
.Cm pam .
.It Cm KexAlgorithms
@ -164,8 +164,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
Specifies the permitted KEX (Key Exchange) algorithms that will be used and
their preference order.
The selected algorithm will the the first algorithm in this list that
@@ -1338,28 +1343,17 @@ Multiple algorithms must be comma-separa
.Pp
If the specified list begins with a
.Sq +
-character, then the specified algorithms will be appended to the default set
@ -181,6 +184,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
.Sq ^
character, then the specified algorithms will be placed at the head of the
-default set.
-.Pp
-The default is:
-.Bd -literal -offset indent
-sntrup761x25519-sha512@openssh.com,
@ -191,10 +195,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
-diffie-hellman-group18-sha512,
-diffie-hellman-group14-sha256
-.Ed
+built-in openssh default set.
.Pp
The list of available key exchange algorithms may also be obtained using
+built-in openssh default set.
The list of supported key exchange algorithms may also be obtained using
.Qq ssh -Q kex .
.It Cm KnownHostsCommand
@@ -1365,37 +1357,33 @@
file.
This option is intended for debugging and no overrides are enabled by default.
@ -479,7 +484,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts
@@ -1044,20 +1017,25 @@
@@ -1025,6 +1025,11 @@ Specifies whether to look at .k5login fi
The default is
.Cm yes .
.It Cm KexAlgorithms
@ -488,9 +493,12 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 .
+.Pp
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
Alternately if the specified list begins with a
Specifies the permitted KEX (Key Exchange) algorithms that the server will
offer to clients.
The ordering of this list is not important, as the client specifies the
@@ -1033,16 +1038,16 @@ Multiple algorithms must be comma-separa
.Pp
If the specified list begins with a
.Sq +
-character, then the specified algorithms will be appended to the default set
-instead of replacing them.
@ -506,10 +514,10 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
character, then the specified algorithms will be placed at the head of the
-default set.
+built-in openssh default set.
.Pp
The supported algorithms are:
.Pp
.Bl -item -compact -offset indent
@@ -1089,16 +1067,6 @@
@@ -1075,16 +1080,6 @@ ecdh-sha2-nistp521
sntrup761x25519-sha512@openssh.com
.El
.Pp
@ -523,7 +531,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
-diffie-hellman-group14-sha256
-.Ed
-.Pp
The list of available key exchange algorithms may also be obtained using
The list of supported key exchange algorithms may also be obtained using
.Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress
@@ -1184,21 +1152,26 @@

View File

@ -3,7 +3,7 @@ index e7549470..b68c1710 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -109,6 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
kexgexc.o kexgexs.o \
kexsntrup761x25519.o sntrup761.o kexgen.o \
+ kexgssc.o \
@ -11,14 +11,14 @@ index e7549470..b68c1710 100644
sshbuf-io.o
@@ -125,7 +126,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
auth2-chall.o groupaccess.o \
auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \
monitor.o monitor_wrap.o auth-krb5.o \
- auth2-gss.o gss-serv.o gss-serv-krb5.o \
+ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \
- monitor.o monitor_wrap.o auth-krb5.o \
+ monitor.o monitor_wrap.o auth-krb5.o kexgsss.o \
auth2-gss.o gss-serv.o gss-serv-krb5.o \
loginrec.o auth-pam.o auth-shadow.o auth-sia.o \
srclimit.o sftp-server.o sftp-common.o \
sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
sftp-server.o sftp-common.o \
@@ -523,7 +523,7 @@ regress-prep:
ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile
@ -41,117 +41,10 @@ diff -up a/auth.c.gsskex b/auth.c
return 1;
break;
case PERMIT_FORCED_ONLY:
@@ -730,97 +731,6 @@ fakepw(void)
}
/*
- * Returns the remote DNS hostname as a string. The returned string must not
- * be freed. NB. this will usually trigger a DNS query the first time it is
- * called.
- * This function does additional checks on the hostname to mitigate some
- * attacks on based on conflation of hostnames and IP addresses.
- */
-
-static char *
-remote_hostname(struct ssh *ssh)
-{
- struct sockaddr_storage from;
- socklen_t fromlen;
- struct addrinfo hints, *ai, *aitop;
- char name[NI_MAXHOST], ntop2[NI_MAXHOST];
- const char *ntop = ssh_remote_ipaddr(ssh);
-
- /* Get IP address of client. */
- fromlen = sizeof(from);
- memset(&from, 0, sizeof(from));
- if (getpeername(ssh_packet_get_connection_in(ssh),
- (struct sockaddr *)&from, &fromlen) == -1) {
- debug("getpeername failed: %.100s", strerror(errno));
- return xstrdup(ntop);
- }
-
- ipv64_normalise_mapped(&from, &fromlen);
- if (from.ss_family == AF_INET6)
- fromlen = sizeof(struct sockaddr_in6);
-
- debug3("Trying to reverse map address %.100s.", ntop);
- /* Map the IP address to a host name. */
- if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
- NULL, 0, NI_NAMEREQD) != 0) {
- /* Host name not found. Use ip address. */
- return xstrdup(ntop);
- }
-
- /*
- * if reverse lookup result looks like a numeric hostname,
- * someone is trying to trick us by PTR record like following:
- * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
- */
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_DGRAM; /*dummy*/
- hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
- logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
- name, ntop);
- freeaddrinfo(ai);
- return xstrdup(ntop);
- }
-
- /* Names are stored in lowercase. */
- lowercase(name);
-
- /*
- * Map it back to an IP address and check that the given
- * address actually is an address of this host. This is
- * necessary because anyone with access to a name server can
- * define arbitrary names for an IP address. Mapping from
- * name to IP address can be trusted better (but can still be
- * fooled if the intruder has access to the name server of
- * the domain).
- */
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = from.ss_family;
- hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
- logit("reverse mapping checking getaddrinfo for %.700s "
- "[%s] failed.", name, ntop);
- return xstrdup(ntop);
- }
- /* Look for the address from the list of addresses. */
- for (ai = aitop; ai; ai = ai->ai_next) {
- if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
- sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
- (strcmp(ntop, ntop2) == 0))
- break;
- }
- freeaddrinfo(aitop);
- /* If we reached the end of the list, the address was not there. */
- if (ai == NULL) {
- /* Address not found for the host name. */
- logit("Address %.100s maps to %.600s, but this does not "
- "map back to the address.", ntop, name);
- return xstrdup(ntop);
- }
- return xstrdup(name);
-}
-
-/*
* Return the canonical name of the host in the other side of the current
* connection. The host name is cached, so it is efficient to call this
* several times.
diff --git a/auth2-gss.c b/auth2-gss.c
index 9351e042..d6446c0c 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -1,7 +1,7 @@
/* $OpenBSD: auth2-gss.c,v 1.34 2023/03/31 04:22:27 djm Exp $ */
/*
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
+ * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -54,6 +54,48 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh);
static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh);
static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
@ -187,10 +80,10 @@ index 9351e042..d6446c0c 100644
+ gssbuf.length = sshbuf_len(b);
+
+ /* gss_kex_context is NULL with privsep, so we can't check it here */
+ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context,
+ &gssbuf, &mic))))
+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
+ authctxt->pw, 1));
+ if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gss_kex_context,
+ &gssbuf, &mic)))
+ authenticated = mm_ssh_gssapi_userok(authctxt->user,
+ authctxt->pw, 1);
+
+ sshbuf_free(b);
+ free(mic.value);
@ -201,40 +94,42 @@ index 9351e042..d6446c0c 100644
/*
* We only support those mechanisms that we know about (ie ones that we know
* how to check local user kuserok and the like)
@@ -260,7 +302,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
@@ -260,7 +302,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
if ((r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
+ authctxt->pw, 1));
- authenticated = mm_ssh_gssapi_userok(authctxt->user);
+ authenticated = mm_ssh_gssapi_userok(authctxt->user, authctxt->pw, 1);
if ((!use_privsep || mm_is_monitor()) &&
(displayname = ssh_gssapi_displayname()) != NULL)
@@ -306,7 +349,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
authctxt->postponed = 0;
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
@@ -306,7 +349,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
gssbuf.length = sshbuf_len(b);
if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
+ authctxt->pw, 0));
if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))
- authenticated = mm_ssh_gssapi_userok(authctxt->user);
+ authenticated = mm_ssh_gssapi_userok(authctxt->user, authctxt->pw, 0);
else
logit("GSSAPI MIC check failed");
@@ -326,6 +370,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
@@ -326,6 +370,17 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
return 0;
}
+Authmethod method_gsskeyex = {
+struct authmethod_cfg methodcfg_gsskeyex = {
+ "gssapi-keyex",
+ NULL,
+ userauth_gsskeyex,
+ &options.gss_authentication
+};
+
+Authmethod method_gsskeyex = {
+ &methodcfg_gsskeyex,
+ userauth_gsskeyex,
+};
+
Authmethod method_gssapi = {
"gssapi-with-mic",
NULL,
&methodcfg_gssapi,
userauth_gssapi,
diff --git a/auth2.c b/auth2.c
index 0e776224..1c217268 100644
--- a/auth2.c
@ -442,15 +337,6 @@ diff --git a/gss-genr.c b/gss-genr.c
index d56257b4..763a63ff 100644
--- a/gss-genr.c
+++ b/gss-genr.c
@@ -1,7 +1,7 @@
/* $OpenBSD: gss-genr.c,v 1.28 2021/01/27 10:05:28 djm Exp $ */
/*
- * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,9 +41,33 @@
#include "sshbuf.h"
#include "log.h"
@ -735,8 +621,8 @@ index d56257b4..763a63ff 100644
+ ctx = &intctx;
/* RFC 4462 says we MUST NOT do SPNEGO */
if (oid->length == spnego_oid.length &&
@@ -287,6 +519,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
if (oid->length == spnego_oid.length &&
@@ -500,6 +500,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
ssh_gssapi_build_ctx(ctx);
ssh_gssapi_set_oid(*ctx, oid);
major = ssh_gssapi_import_name(*ctx, host);
@ -745,13 +631,13 @@ index d56257b4..763a63ff 100644
+ major = ssh_gssapi_client_identity(*ctx, client);
+
if (!GSS_ERROR(major)) {
major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token,
major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token,
NULL);
@@ -296,10 +532,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
@@ -527,10 +527,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx
GSS_C_NO_BUFFER);
}
- if (GSS_ERROR(major))
- if (GSS_ERROR(major))
+ if (GSS_ERROR(major) || intctx != NULL)
ssh_gssapi_delete_ctx(ctx);
@ -1012,7 +898,7 @@ index ab3a15f0..6ce56e92 100644
+ Gssctxt *ctx = NULL;
+ int res;
+
+ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
+ res = !GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctx, oid));
+ ssh_gssapi_delete_ctx(&ctx);
+
+ return (res);
@ -1158,7 +1044,7 @@ index ab3a15f0..6ce56e92 100644
/* Destroy delegated credentials if userok fails */
gss_release_buffer(&lmin, &gssapi_client.displayname);
gss_release_buffer(&lmin, &gssapi_client.exportedname);
@@ -382,14 +471,90 @@ ssh_gssapi_userok(char *user)
@@ -382,14 +471,85 @@ ssh_gssapi_userok(char *user)
return (0);
}
@ -1201,7 +1087,7 @@ index ab3a15f0..6ce56e92 100644
+ gssapi_client.store.envvar == NULL)
+ return;
+
+ ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
+ ok = mm_ssh_gssapi_update_creds(&gssapi_client.store);
+
+ if (!ok)
+ return;
@ -1213,11 +1099,6 @@ index ab3a15f0..6ce56e92 100644
+ * for rekeying. So, use our own :)
+ */
+#ifdef USE_PAM
+ if (!use_privsep) {
+ debug("Not even going to try and do PAM with privsep disabled");
+ return;
+ }
+
+ ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name,
+ &pamconv, &pamh);
+ if (ret)
@ -1256,20 +1137,34 @@ index ab3a15f0..6ce56e92 100644
/* Privileged */
diff --git a/kex.c b/kex.c
index ce85f043..574c7609 100644
index a5ae6ac0..fe714141 100644
--- a/kex.c
+++ b/kex.c
@@ -698,6 +755,9 @@ kex_free(struct kex *kex)
sshbuf_free(kex->server_version);
sshbuf_free(kex->client_pub);
sshbuf_free(kex->session_id);
+#ifdef GSSAPI
+ free(kex->gss_host);
+#endif /* GSSAPI */
sshbuf_free(kex->initial_sig);
sshkey_free(kex->initial_hostkey);
free(kex->failed_choice);
diff --git a/kex-names.c b/kex-names.c
index ce85f043..574c7609 100644
--- a/kex-names.c
+++ b/kex-names.c
@@ -57,6 +57,10 @@
#include "digest.h"
#include "ssherr.h"
#include "xmalloc.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+
/* prototype */
static int kex_choose_conf(struct ssh *, uint32_t seq);
static int kex_input_newkeys(int, u_int32_t, struct ssh *);
struct kexalg {
char *name;
u_int type;
@@ -115,15 +120,28 @@ static const struct kexalg kexalgs[] = {
#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
{ NULL, 0, -1, -1},
@ -1332,10 +1227,11 @@ index ce85f043..574c7609 100644
return NULL;
}
@@ -315,6 +349,29 @@ kex_assemble_names(char **listp, const char *def, const char *all)
@@ -315,3 +349,26 @@ kex_assemble_names(char **listp, const char *def, const char *all)
free(ret);
return r;
}
+
+/* Validate GSS KEX method name list */
+int
+kex_gss_names_valid(const char *names)
@ -1358,20 +1254,6 @@ index ce85f043..574c7609 100644
+ free(s);
+ return 1;
+}
+
/*
* Fill out a proposal array with dynamically allocated values, which may
* be modified as required for compatibility reasons.
@@ -698,6 +755,9 @@ kex_free(struct kex *kex)
sshbuf_free(kex->server_version);
sshbuf_free(kex->client_pub);
sshbuf_free(kex->session_id);
+#ifdef GSSAPI
+ free(kex->gss_host);
+#endif /* GSSAPI */
sshbuf_free(kex->initial_sig);
sshkey_free(kex->initial_hostkey);
free(kex->failed_choice);
diff --git a/kex.h b/kex.h
index a5ae6ac0..fe714141 100644
--- a/kex.h
@ -1406,16 +1288,16 @@ index a5ae6ac0..fe714141 100644
int (*verify_host_key)(struct sshkey *, struct ssh *);
struct sshkey *(*load_host_public_key)(int, int, struct ssh *);
@@ -174,8 +189,10 @@ struct kex {
int kex_nid_from_name(const char *);
int kex_names_valid(const char *);
char *kex_alg_list(char);
+char *kex_gss_alg_list(char);
char *kex_names_cat(const char *, const char *);
int kex_assemble_names(char **, const char *, const char *);
int kex_has_any_alg(const char *, const char *);
+int kex_gss_names_valid(const char *);
int kex_assemble_names(char **, const char *, const char *);
void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX],
const char *, const char *, const char *, const char *, const char *);
void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]);
@@ -202,6 +219,12 @@ int kexgex_client(struct ssh *);
int kexgex_server(struct ssh *);
int kex_gen_client(struct ssh *);
@ -2205,7 +2087,7 @@ index 00000000..60bc02de
+
+ debug2_f("Acquiring credentials");
+
+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
+ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid)))
+ fatal("Unable to acquire credentials for the server");
+
+ do {
@ -2282,8 +2164,8 @@ index 00000000..60bc02de
+ type);
+ }
+
+ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok,
+ &send_tok, &ret_flags));
+ maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok,
+ &send_tok, &ret_flags);
+
+ gss_release_buffer(&min_status, &recv_tok);
+
@ -2319,7 +2201,7 @@ index 00000000..60bc02de
+ if (!(ret_flags & GSS_C_INTEG_FLAG))
+ fatal("Integrity flag wasn't set");
+
+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
+ if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))
+ fatal("Couldn't get MIC");
+
+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 ||
@ -2409,7 +2291,7 @@ index 00000000..60bc02de
+
+ debug2_f("Acquiring credentials");
+
+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
+ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid)))
+ fatal("Unable to acquire credentials for the server");
+
+ /* 5. S generates an ephemeral key pair (do the allocations early) */
@ -2431,7 +2313,7 @@ index 00000000..60bc02de
+ if (max < min || nbits < min || max < nbits)
+ fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
+ min, nbits, max);
+ kex->dh = PRIVSEP(choose_dh(min, nbits, max));
+ kex->dh = mm_choose_dh(min, nbits, max);
+ if (kex->dh == NULL) {
+ sshpkt_disconnect(ssh, "Protocol error: no matching group found");
+ fatal("Protocol error: no matching group found");
@ -2478,8 +2360,8 @@ index 00000000..60bc02de
+ type);
+ }
+
+ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok,
+ &send_tok, &ret_flags));
+ maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok,
+ &send_tok, &ret_flags);
+
+ gss_release_buffer(&min_status, &recv_tok);
+
@ -2544,7 +2426,7 @@ index 00000000..60bc02de
+ gssbuf.value = hash;
+ gssbuf.length = hashlen;
+
+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
+ if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))
+ fatal("Couldn't get MIC");
+
+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 ||
@ -2873,7 +2755,7 @@ index 001a8fa1..6edb509a 100644
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m);
mm_request_receive_expect(pmonitor->m_recvfd,
@@ -1012,4 +1014,57 @@ mm_ssh_gssapi_userok(char *user)
@@ -1012,6 +1014,59 @@ mm_ssh_gssapi_userok(char *user)
debug3_f("user %sauthenticated", authenticated ? "" : "not ");
return (authenticated);
}
@ -2931,6 +2813,8 @@ index 001a8fa1..6edb509a 100644
+}
+
#endif /* GSSAPI */
/*
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 23ab096a..485590c1 100644
--- a/monitor_wrap.h
@ -3107,8 +2991,8 @@ diff -up a/servconf.c.gsskex b/servconf.c
#include "digest.h"
+#include "ssh-gss.h"
static void add_listen_addr(ServerOptions *, const char *,
const char *, int);
#if !defined(SSHD_PAM_SERVICE)
# define SSHD_PAM_SERVICE "sshd"
@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions
options->kerberos_ticket_cleanup = -1;
options->kerberos_get_afs_token = -1;
@ -3141,7 +3025,7 @@ diff -up a/servconf.c.gsskex b/servconf.c
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -506,6 +518,7 @@ typedef enum {
sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
sPerSourcePenalties, sPerSourcePenaltyExemptList,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
+ sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
@ -3262,14 +3146,6 @@ diff --git a/ssh-gss.h b/ssh-gss.h
index 36180d07..70dd3665 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -1,6 +1,6 @@
/* $OpenBSD: ssh-gss.h,v 1.15 2021/01/27 10:05:28 djm Exp $ */
/*
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,10 +61,34 @@
#define SSH_GSS_OIDTYPE 0x06
@ -3523,17 +3399,8 @@ diff --git a/sshconnect2.c b/sshconnect2.c
index af00fb30..03bc87eb 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -80,8 +80,6 @@
#endif
/* import */
-extern char *client_version_string;
-extern char *server_version_string;
extern Options options;
/*
@@ -163,6 +161,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
char *s, *all_key, *hkalgs = NULL;
char *all_key, *hkalgs = NULL;
int r, use_known_hosts_order = 0;
+#if defined(GSSAPI) && defined(WITH_OPENSSL)
@ -3545,8 +3412,8 @@ index af00fb30..03bc87eb 100644
xxx_hostaddr = hostaddr;
xxx_conn_info = cinfo;
@@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers,
options.macs, compression_alg_list(options.compression),
options.kex_algorithms, options.ciphers, options.macs,
compression_alg_list(options.compression),
hkalgs ? hkalgs : options.hostkeyalgorithms);
+
+#if defined(GSSAPI) && defined(WITH_OPENSSL)
@ -3587,7 +3454,7 @@ index af00fb30..03bc87eb 100644
free(hkalgs);
@@ -224,17 +256,47 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
@@ -224,14 +256,44 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
# ifdef OPENSSL_HAS_ECC
ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
# endif
@ -3618,11 +3485,8 @@ index af00fb30..03bc87eb 100644
+#endif
+
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done);
kex_proposal_free_entries(myproposal);
/* remove ext-info from the KEX proposals for rekeying */
free(myproposal[PROPOSAL_KEX_ALGS]);
myproposal[PROPOSAL_KEX_ALGS] =
compat_kex_proposal(ssh, options.kex_algorithms);
+#if defined(GSSAPI) && defined(WITH_OPENSSL)
+ /* repair myproposal after it was crumpled by the */
+ /* ext-info removal above */
@ -3633,9 +3497,9 @@ index af00fb30..03bc87eb 100644
+ free(gss);
+ }
+#endif
if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0)
fatal_r(r, "kex_prop2buf");
#ifdef DEBUG_KEXDH
/* send 1st encrypted/maced/compressed message */
if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
@@ -330,6 +392,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *);
static int input_gssapi_token(int type, u_int32_t, struct ssh *);
static int input_gssapi_error(int, u_int32_t, struct ssh *);
@ -3767,6 +3631,20 @@ diff --git a/sshd.c b/sshd.c
index 60b2aaf7..d92f03aa 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1852,7 +1852,8 @@ main(int ac, char **av)
free(fp);
}
accumulate_host_timing_secret(cfg, NULL);
- if (!sensitive_data.have_ssh2_key) {
+ /* The GSSAPI key exchange can run without a host key */
+ if (!sensitive_data.have_ssh2_key && !options.gss_keyex) {
logit("sshd: no hostkeys available -- exiting.");
exit(1);
}
diff --git a/sshd-session.c b/sshd-session.c
index 60b2aaf7..d92f03aa 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -817,8 +817,8 @@ notify_hostkeys(struct ssh *ssh)
}
debug3_f("sent %u hostkeys", nkeys);
@ -3778,16 +3656,6 @@ index 60b2aaf7..d92f03aa 100644
sshpkt_fatal(ssh, r, "%s: send", __func__);
sshbuf_free(buf);
}
@@ -1852,7 +1852,8 @@ main(int ac, char **av)
free(fp);
}
accumulate_host_timing_secret(cfg, NULL);
- if (!sensitive_data.have_ssh2_key) {
+ /* The GSSAPI key exchange can run without a host key */
+ if (!sensitive_data.have_ssh2_key && !options.gss_keyex) {
logit("sshd: no hostkeys available -- exiting.");
exit(1);
}
@@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh)
free(hkalgs);
@ -3838,9 +3706,9 @@ index 60b2aaf7..d92f03aa 100644
if ((r = kex_setup(ssh, myproposal)) != 0)
fatal_r(r, "kex_setup");
@@ -2362,7 +2405,18 @@ do_ssh2_kex(struct ssh *ssh)
# ifdef OPENSSL_HAS_ECC
#ifdef OPENSSL_HAS_ECC
kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
# endif
#endif
-#endif
+# ifdef GSSAPI
+ if (options.gss_keyex) {
@ -4036,9 +3904,9 @@ diff --git a/packet.h b/packet.h
int ssh_packet_read(struct ssh *);
+int ssh_packet_read_expect(struct ssh *, u_int type);
int ssh_packet_read_poll(struct ssh *);
int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p);
int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len);
int ssh_packet_process_read(struct ssh *, int);
diff --git a/packet.c b/packet.c
--- a/packet.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99)
+++ b/packet.c (date 1703172586447)

View File

@ -965,9 +965,9 @@ diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c
--- openssh-9.6p1/ssh-agent.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100
+++ openssh-9.6p1/ssh-agent.c 2024-01-12 14:25:25.234942360 +0100
@@ -1549,10 +1549,72 @@ add_p11_identity(struct sshkey *key, cha
idtab->nentries++;
}
#ifdef ENABLE_PKCS11
+static char *
+sanitize_pkcs11_provider(const char *provider)
+{

View File

@ -19,4 +19,4 @@ diff --git a/servconf.c b/servconf.c
+ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */
{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },
{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
{ "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL },

View File

@ -79,12 +79,12 @@ diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c
const struct ssh_conn_info *cinfo)
{
char *myproposal[PROPOSAL_MAX];
- char *s, *all_key, *hkalgs = NULL;
+ char *s, *all_key, *hkalgs = NULL, *filtered_algs = NULL;
- char *all_key, *hkalgs = NULL;
+ char *all_key, *hkalgs = NULL, *filtered_algs = NULL;
int r, use_known_hosts_order = 0;
#if defined(GSSAPI) && defined(WITH_OPENSSL)
@@ -260,9 +260,21 @@ ssh_kex2(struct ssh *ssh, char *host, st
@@ -260,10 +260,22 @@ ssh_kex2(struct ssh *ssh, char *host, st
if (use_known_hosts_order)
hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);
@ -100,8 +100,9 @@ diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c
+ options.hostkeyalgorithms, options.pubkey_accepted_algos);
+ }
+
kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers,
options.macs, compression_alg_list(options.compression),
kex_proposal_populate_entries(ssh, myproposal,
options.kex_algorithms, options.ciphers, options.macs,
compression_alg_list(options.compression),
- hkalgs ? hkalgs : options.hostkeyalgorithms);
+ filtered_algs);

View File

@ -148,15 +148,6 @@ diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p
ASSERT_PTR_NE(keyname, NULL);
kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname;
ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
@@ -180,7 +181,7 @@ do_kex(char *kex)
{
#ifdef WITH_OPENSSL
do_kex_with_key(kex, KEY_RSA, 2048);
- do_kex_with_key(kex, KEY_DSA, 1024);
+ /* do_kex_with_key(kex, KEY_DSA, 1024); */
#ifdef OPENSSL_HAS_ECC
do_kex_with_key(kex, KEY_ECDSA, 256);
#endif /* OPENSSL_HAS_ECC */
diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_file.c
--- openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck 2023-01-26 12:04:55.946343408 +0100
+++ openssh-8.7p1/regress/unittests/sshkey/test_file.c 2023-01-26 12:06:35.235164432 +0100
@ -196,22 +187,6 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh-
TEST_START("fuzz RSA SHA256 sig");
buf = load_file("rsa_1");
@@ -357,6 +358,7 @@ sshkey_fuzz_tests(void)
sshkey_free(k1);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("fuzz DSA sig");
buf = load_file("dsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
@@ -364,6 +366,7 @@ sshkey_fuzz_tests(void)
sig_fuzz(k1, NULL);
sshkey_free(k1);
TEST_DONE();
+ */
#ifdef OPENSSL_HAS_ECC
TEST_START("fuzz ECDSA sig");
diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c
--- openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck 2023-01-26 11:02:52.339413463 +0100
+++ openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c 2023-01-26 11:58:42.324253896 +0100
@ -241,10 +216,10 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openss
{
size_t len;
u_char *sig;
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
+ int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
+ /* 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 = SSH_ERR_LIBCRYPTO_ERROR;
+ 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);
@ -277,21 +252,6 @@ diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openss
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
ASSERT_PTR_EQ(k4, NULL);
diff -up openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck openssh-8.7p1/regress/unittests/sshsig/tests.c
--- openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck 2023-01-26 12:19:23.659513651 +0100
+++ openssh-8.7p1/regress/unittests/sshsig/tests.c 2023-01-26 12:20:28.021044803 +0100
@@ -102,9 +102,11 @@ tests(void)
check_sig("rsa.pub", "rsa.sig", msg, namespace);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("check DSA signature");
check_sig("dsa.pub", "dsa.sig", msg, namespace);
TEST_DONE();
+ */
#ifdef OPENSSL_HAS_ECC
TEST_START("check ECDSA signature");
diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c
--- openssh-8.7p1/serverloop.c.sshrsacheck 2023-01-12 14:57:08.118400073 +0100
+++ openssh-8.7p1/serverloop.c 2023-01-12 14:59:17.330470518 +0100
@ -332,61 +292,6 @@ diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c
goto out;
}
diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c
--- openssh-8.7p1/sshd.c.sshrsacheck 2023-01-12 13:29:06.355711140 +0100
+++ openssh-8.7p1/sshd.c 2023-01-12 13:29:06.358711178 +0100
@@ -1640,6 +1651,7 @@ main(int ac, char **av)
Authctxt *authctxt;
struct connection_info *connection_info = NULL;
sigset_t sigmask;
+ int forbid_ssh_rsa = 0;
#ifdef HAVE_SECUREWARE
(void)set_auth_parameters(ac, av);
@@ -1938,6 +1950,33 @@ main(int ac, char **av)
key = NULL;
continue;
}
+ if (key && (sshkey_type_plain(key->type) == KEY_RSA || sshkey_type_plain(key->type) == KEY_RSA_CERT)) {
+ size_t sign_size = 0;
+ u_char *tmp = NULL;
+ u_char data[] = "Test SHA1 vector";
+ int res;
+
+ res = sshkey_sign(key, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
+ free(tmp);
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) {
+ verbose_f("sshd: SHA1 in signatures is disabled for RSA keys");
+ forbid_ssh_rsa = 1;
+ }
+ }
+ if (key && (sshkey_type_plain(key->type) == KEY_DSA || sshkey_type_plain(key->type) == KEY_DSA_CERT)) {
+ size_t sign_size = 0;
+ u_char *tmp = NULL;
+ u_char data[] = "Test SHA1 vector";
+ int res;
+
+ res = sshkey_sign(key, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
+ free(tmp);
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) {
+ logit_f("sshd: ssh-dss is disabled, skipping key file %s", options.host_key_files[i]);
+ key = NULL;
+ continue;
+ }
+ }
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
@@ -2275,6 +2306,9 @@ main(int ac, char **av)
check_ip_options(ssh);
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
+
/* Prepare the channels layer */
channel_init_channels(ssh);
channel_set_af(ssh, options.address_family);
diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c
--- openssh-8.7p1/ssh-rsa.c.sshrsacheck 2023-01-20 13:07:54.180676144 +0100
+++ openssh-8.7p1/ssh-rsa.c 2023-01-20 13:07:54.290677074 +0100
@ -400,3 +305,34 @@ diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
}
diff -up openssh-9.8p1/sshd-session.c.xxx openssh-9.8p1/sshd-session.c
--- openssh-9.8p1/sshd-session.c.xxx 2024-07-23 15:08:14.794350818 +0200
+++ openssh-9.8p1/sshd-session.c 2024-07-23 15:40:21.658456636 +0200
@@ -1305,6 +1305,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);

View File

@ -200,7 +200,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x
u_char *kbuf = NULL;
size_t klen = 0;
- int kout, r;
+ int kout, r = 0;
+ int r = 0;
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_pub= ");

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
From 26f366e263e575c4e1a18e2e64ba418f58878b37 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Mon, 20 Mar 2023 20:22:14 +0100
Subject: [PATCH] Only set PAM_RHOST if the remote host is not "UNKNOWN"
When using sshd's -i option with stdio that is not a AF_INET/AF_INET6
socket, auth_get_canonical_hostname() returns "UNKNOWN" which is then
set as the value of PAM_RHOST, causing pam to try to do a reverse DNS
query of "UNKNOWN", which times out multiple times, causing a
substantial slowdown when logging in.
To fix this, let's only set PAM_RHOST if the hostname is not "UNKNOWN".
---
auth-pam.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/auth-pam.c b/auth-pam.c
index e143304e3..39b4e4563 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -735,7 +735,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.44.0

View File

@ -38,13 +38,13 @@
# rpm -ba|--rebuild --define "static_openssl 1"
%{?static_openssl:%global static_libcrypto 1}
%global openssh_ver 9.6p1
%global openssh_ver 9.8p1
%global openssh_rel 1
Summary: An open source implementation of SSH protocol version 2
Name: openssh
Version: %{openssh_ver}
Release: %{openssh_rel}%{?dist}.5
Release: %{openssh_rel}%{?dist}.0
URL: http://www.openssh.com/portable.html
Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
Source1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc
@ -63,6 +63,8 @@ Source17: ssh-agent.socket
Source19: openssh-server-systemd-sysusers.conf
Source20: ssh-host-keys-migration.sh
Source21: ssh-host-keys-migration.service
Source22: parallel_test.sh
Source23: parallel_test.Makefile
#https://bugzilla.mindrot.org/show_bug.cgi?id=2581
Patch100: openssh-6.7p1-coverity.patch
@ -122,7 +124,8 @@ Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch
Patch804: openssh-7.7p1-gssapi-new-unique.patch
# Respect k5login_directory option in krk5.conf (#1328243)
Patch805: openssh-7.2p2-k5login_directory.patch
# Rewriting OpenSSH GSS KEX to use new packet API
Patch806: openssh-9.6p1-gsskex-new-api.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
Patch901: openssh-6.6p1-kuserok.patch
@ -142,8 +145,6 @@ Patch926: openssh-6.7p1-sftp-force-permission.patch
Patch939: openssh-7.2p2-s390-closefrom.patch
# Move MAX_DISPLAYS to a configuration option (#1341302)
Patch944: openssh-7.3p1-x11-max-displays.patch
# Help systemd to track the running service
Patch948: openssh-7.4p1-systemd.patch
# Pass inetd flags for SELinux down to openbsd compat level
Patch949: openssh-7.6p1-cleanup-selinux.patch
# Sandbox adjustments for s390 and audit
@ -199,6 +200,8 @@ Patch1012: openssh-9.0p1-evp-fips-dh.patch
Patch1013: openssh-9.0p1-evp-fips-ecdh.patch
Patch1014: openssh-8.7p1-nohostsha1proof.patch
Patch1015: openssh-9.6p1-pam-rhost.patch
License: BSD-3-Clause AND BSD-2-Clause AND ISC AND SSH-OpenSSH AND ssh-keyscan AND sprintf AND LicenseRef-Fedora-Public-Domain AND X11-distribute-modifications-variant
Requires: /sbin/nologin
@ -329,6 +332,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%patch -P 801 -p1 -b .force_krb
%patch -P 804 -p1 -b .ccache_name
%patch -P 805 -p1 -b .k5login
%patch -P 806 -p1 -b .gsskex-new-api
#
%patch -P 901 -p1 -b .kuserok
%patch -P 906 -p1 -b .fromto-remote
@ -340,7 +344,6 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%patch -P 926 -p1 -b .sftp-force-mode
%patch -P 939 -p1 -b .s390-dev
%patch -P 944 -p1 -b .x11max
%patch -P 948 -p1 -b .systemd
%patch -P 949 -p1 -b .refactor
%patch -P 950 -p1 -b .sandbox
%patch -P 951 -p1 -b .pkcs11-uri
@ -372,6 +375,7 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%patch -P 1012 -p1 -b .evp-fips-dh
%patch -P 1013 -p1 -b .evp-fips-ecdh
%patch -P 1014 -p1 -b .nosha1hostproof
%patch -P 1015 -p1 -b .pam-rhost
%patch -P 100 -p1 -b .coverity
@ -470,10 +474,7 @@ popd
%endif
%check
#to run tests use "--with check"
%if %{?_with_check:1}%{!?_with_check:0}
make tests
%endif
%{SOURCE22} %{SOURCE23} # ./parallel_tests.sh parallel_tests.Makefile
%install
rm -rf $RPM_BUILD_ROOT
@ -613,6 +614,7 @@ test -f %{sysconfig_anaconda} && \
%files server
%dir %attr(0711,root,root) %{_datadir}/empty.sshd
%attr(0755,root,root) %{_sbindir}/sshd
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-session
%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-keygen
%attr(0644,root,root) %{_mandir}/man5/sshd_config.5*
@ -651,6 +653,10 @@ test -f %{sysconfig_anaconda} && \
%attr(0755,root,root) %{_libdir}/sshtest/sk-dummy.so
%changelog
* Thu Jul 25 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.8p1-1.0
- Rebase OpenSSH to 9.8p1
Resolves: RHEL-42635
* Fri Jul 12 2024 Zoltan Fridrich <zfridric@redhat.com> - 9.6p1-1.5
- Build OpenSSH without ENGINE API
Resolves: RHEL-45507

14
parallel_test.Makefile Normal file
View File

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

91
parallel_test.sh Executable file
View File

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

View File

@ -1,4 +1,3 @@
SHA512 (openssh-9.6p1.tar.gz) = 0ebf81e39914c3a90d7777a001ec7376a94b37e6024baf3e972c58f0982b7ddef942315f5e01d56c00ff95603b4a20ee561ab918ecc55511df007ac138160509
SHA512 (openssh-9.6p1.tar.gz.asc) = aec5a5bd6ce480a8e5b5879dc55f8186aec90fe61f085aa92ad7d07f324574aa781be09c83b7443a32848d091fd44fb12c1842d49cee77afc351e550ffcc096d
SHA512 (pam_ssh_agent_auth-0.10.4.tar.gz) = caccf72174d15e43f4c86a459ac6448682e62116557cf1e1e828955f3d1731595b238df42adec57860e7f341e92daf5d8285020bcb5018f3b8a5145aa32ee1c2
SHA512 (openssh-9.8p1.tar.gz) = 95dec2f18e58eb47994f3de4430253e0665e185564b65088ca5f4108870e05feddef8cda8d3c0a4b75f18b98cc2c024df0e27de53b48c1a16da8da483cb8292a
SHA512 (openssh-9.8p1.tar.gz.asc) = 4df1f1be2c6ab7f3aebaedd0a773b0e8c8929abb30cd3415873ad55d012cfa113f792e888e5e772dd468c394aeb7e35d62893a514dbc0ab1a03acd79918657f7
SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21